1. 程式人生 > >二叉樹的創建、遍歷、查找、刪除

二叉樹的創建、遍歷、查找、刪除

遞歸 瀏覽器 nod 刪除 reac 二叉樹的遍歷 初始化 後序遍歷 lba

一、二叉樹的基本概念

一棵非空的二叉樹由根結點及左、右子樹這三個基本部分組成。如下圖:

技術分享

數字8為根節點,14713為葉子節點,8的左邊為左子樹,數值都比根節點8小,右邊為右子樹,數值都比根節點8大。

二、二叉樹的遍歷

前序遍歷:根->->(8-3-1-6-4-7-10-14-13);

中序遍歷:左->->(1-3-4-6-7-8-10-13-14);

後序遍歷:左->->(1-4-7-6-3-13-14-10-8);

典型應用分析:

1) 輸出某個文件夾下所有文件名稱(可以有子文件夾)---用先序遍歷實現

如果是文件夾,先輸出文件夾名,然後再依次輸出該文件夾下的所有文件

(包括子文件夾),如果有子文件夾,則再進入該子文件夾,輸出該子文件夾下的所有文件名。

2) 統計某個文件夾的大小(該文件夾下所有文件的大小--用後序遍歷實現

若要知道某文件夾的大小,必須先知道該文件夾下所有文件的大小,如果有子文件夾,若要知道該子文件夾大小,必須先知道子文件夾所有文件的大小。

3)從小到大輸出數據---中序遍歷實現

三、創建二叉樹的實現(遞歸算法)

//創建二叉樹

var BinaryTree=function(){

  var Node=function(key){//初始化節點

    this.key=key;

    this.left=null;

    this.right=null;

  }

  var rootNode=null;

  var insertNode=function(node,newNode){

  //插入的節點與父節點比較,小的在左邊,大的在右邊

  if(newNode.key< node.key){

    if(node.left ===null){

      node.left=newNode;

    }else{

      insertNode(node.left,newNode);

    }

  }else{

    if(node.right===null){

    node.right=newNode;

    }else{

      insertNode(node.right,newNode);

    }

  }

}

  this.insert=function(key){

    var newNode=new Node(key);

    if(rootNode===null){

      rootNode=newNode;

    }else{

      insertNode(rootNode,newNode);

    }

  }

}

var nodes=[8,3,10,1,6,14,4,7,13];

var binaryTree=new BinaryTree();

nodes.forEach(function(key){

  binaryTree.insert(key);

});

四、三種遍歷的實現

//中序遍歷

var inOrderTraverseNode=function(node,callback){

  if(node !==null){

    inOrderTraverseNode(node.left,callback);

    callback(node.key);

    inOrderTraverseNode(node.right,callback);

  }

}

this.inOrderTraverse=function(callback){

  inOrderTraverseNode(rootNode,callback);

};

//前序遍歷

var preOrderTraverseNode=function(node,callback){

  if(node !==null){

    callback(node.key);

    preOrderTraverseNode(node.left,callback);

    preOrderTraverseNode(node.right,callback);

  }

}

this.preOrderTraverse=function(callback){

  preOrderTraverseNode(rootNode,callback);

};

//後序遍歷

var afterOrderTraverseNode=function(node,callback){

  if(node !==null){

    afterOrderTraverseNode(node.left,callback);

    afterOrderTraverseNode(node.right,callback);

    callback(node.key);

  }

}

this.afterOrderTraverse=function(callback){

  afterOrderTraverseNode(rootNode,callback);

};

//以上代碼放在BinaryTree函數裏面定義

var callback=function(key){

  console.log(key);

}

binaryTree.preOrderTraverse(callback);

五、二叉樹節點查找

最小值:由於左節點總是比右節點大,所以只要判斷該節點沒有左節點就是最大值。

最大值:只要判斷該節點沒有右節點就是最大值。

指定值:運用遞歸方法進行比較,小於父節點就走左子樹,大於就走右子樹,直到等於指定值。代碼如下:

var minNode=function(node){

  if(node){

    while(node && node.left !==null){

    node=node.left;

  }

  return node.key;

}

return null;

}

this.min=function(){

  return minNode(rootNode);

}

var maxNode=function(node){

  if(node){

    while(node && node.right !==null){

    node=node.right;

  }

  return node.key;

}

return null;

}

this.max=function(){

  return maxNode(rootNode);

}

var searchNode=function(node,key){

  if(node===null){

    return false;

  }

  if(key<node.key){

    return searchNode(node.left,key);

  }else if(key>node.key){

    return searchNode(node.right,key);

  }else{

  return true;

  }

}

this.search=function(key){

  return searchNode(rootNode,key)

}

//以上代碼放在BinaryTree函數裏面定義;

console.log(binaryTree.min())//查找最小值

console.log(binaryTree.search(7)?‘has‘:‘no found 7‘)//查找指定值7

六、刪除節點

1、刪除葉子節點

通過遞歸方法,如果節點沒有左節點和右節點就是葉子節點,通過node =null刪除該節點。

2、刪除只有左子樹或者右子樹的節點,比如刪除節點10,那原先指向10的箭頭就指向14.

技術分享 技術分享

3、刪除左子樹右子樹都有的節點,比如節點3。由於左節點一定比父節點和右節點大,所以刪除節點3後,節點4將代替節點3的位置,節點4和連接的箭頭消失。如下圖:

技術分享

4、代碼實現如下:

var findMinNode=function(node){

  if(node){

    while(node && node.left !==null){

    node=node.left;

  }

  return node;

  }

  return null;

}

var removeNode=function(node,key){

  if(node===null){

    return null;

  }

  if(key<node.key){

    node.left=removeNode(node.left,key);

    return node;

  }else if(key>node.key){

    node.right=removeNode(node.right,key);

  return node;

  }else{

  //刪除左右節點都沒有的節點

  if(node.left===null && node.right===null){

    node=null;

    return node;

  }else if(node.left===null){//刪除左節點沒有的節點

    node=node.right;

    return node;

  }else if(node.right===null){//刪除右節點沒有的節點

    node=node.left;

    return node;

  }

  //刪除左右節點都有的節點

  var aux=findMinNode(node.right);//查找該節點右子樹最小值

  node.key=aux.key;//替換要刪除的節點

  //刪除掉要刪除節點的右子樹的最小值,也就是aux;

  node.right=removeNode(node.right,aux.key);

    return node;

  }

}

this.remove=function(key){

  rootNode=removeNode(rootNode,key)

}

以上代碼放在BinaryTree這個函數裏面定義。

binaryTree.remove(3);

這裏的代碼實現主要用的是遞歸方法,大家可以在瀏覽器上打斷點執行理解。

二叉樹的創建、遍歷、查找、刪除