二叉樹的創建與方法

二叉樹是一種重要的數據存儲結構,它體現了一對多的數據存儲方式,一顆二叉樹有一個根節點(root),與衆多分結點組成,每個雙親最多有兩個子樹分爲左子樹右子樹,結點的分支數稱爲這個結點的度,整個二叉樹的度爲最大的度.度爲0的結點稱爲葉結點.
代碼放在GitHub:二叉查找樹

滿二叉樹與完全二叉樹

在這裏插入圖片描述

  • 滿二叉樹每個層級的結點都達到最大
  • 完全二叉樹必須從左到右依次排序,造成只能右邊存在缺失(如果左邊缺失勢必造成不是正確的排序)

二叉樹的創建

  • 每個結點最多隻有兩個分支left(左子樹)、right(右子樹)

使用JavaScript實現二叉樹的創建


 /**
  * @name: 二叉樹創建封裝
  * @params: null
  * @return: undefined
  */
 function BinarySearchTree() {
    //  根節點
     this.root=null;
    // 結點包括左子樹和右子樹結點和當前的鍵
     this.node=function (key) {
         this.key=key;
         this.left=null;
         this.right=null;
     };
 }

可以看到非常的簡單,每個結點由相應的key、left(左子樹)、right(右子樹)構成,還有一個root(根節點)

添加插入結點的方法

  • 小於雙親的結點在雙親的左邊,大於雙親的在雙親的右邊
  • 根節點的左邊爲全部小於結點的樹,右邊全部爲大於跟結點
  • 如果沒有root(根節點)則插入結點爲根節點
/**
  * @name: 二叉樹插入方法
  * @params: 插入的鍵
  * @return: undefined
  */
 BinarySearchTree.prototype.insert=function (key) {
    // 創建新結點
    let newNode=new this.node(key); 
    if(this.root===null){
         this.root=newNode;
     }else{

         this.insertRecurse(this.root,newNode);
     }
 }
/**
 * @name:二叉樹遞歸插入方法 
 * @params: parent(雙親)  node(插入的結點)
 * @return: undefined
 */
BinarySearchTree.prototype.insertRecurse=function (parent,node) {
    // 小於爲左子樹部分,大於爲右子樹部分
    if(node.key<parent.key){
        parent.left?this.insertRecurse(parent.left,node):parent.left=node;
    }
    else{
        parent.right?this.insertRecurse(parent.right,node):parent.right=node;
    }
}

遍歷操作

二叉樹數據結構常用的遍歷方法主要有4種:

  • 前序遍歷
  • 中序遍歷
  • 後序遍歷
  • 層序遍歷

各種遍歷操作可以用根節點的位置進行區分,遍歷順序都是優先遍歷左在遍歷右,所以前序遍歷順序爲雙親(D)->左子樹(L)->右子樹( R),中序遍歷順序爲左子樹(L)->雙親(D)->右子樹( R),後序遍歷順序爲左子樹(L)->右子樹( R)->雙親(D),層序遍歷就是從左到右、從上到下進行遍歷,一般沒做說明.
在這裏插入圖片描述
例:如上圖滿二叉樹,前序遍歷順序爲 A BDE CFG,上圖非完全二叉樹遍歷順序爲A BD CEF

JavaScript實現前序遍歷
假設利用上邊的二叉樹插入方法,生成一顆二叉樹如下:
插入數值

var bst=new BinarySearchTree()
bst.insert(11);
bst.insert(5);
bst.insert(8);
bst.insert(10);
bst.insert(15);
bst.insert(16);
bst.insert(12);
bst.insert(14);
bst.insert(17);

在這裏插入圖片描述
則想要實現的前序遍歷順序應該 11 5 8 10 15 12 14 16 17
實現前序遍歷算法:

 /**
      * @name:前序遍歷算法 
      * @params: 接收遍歷結果的回調 
      * @return: undefined
      */
     BinarySearchTree.prototype.prevOrderIterate=function(callback) {
         this.prevOrderIterateRecurse(this.root,callback);
     };
    //  前序遍歷遞歸
     BinarySearchTree.prototype.prevOrderIterateRecurse=function (node,callback) {
         if(node!==null){
            //  返回遍歷值
            callback(node.key);
          
            //  繼續遍歷左子樹,再遍歷右子樹(利用棧結構特點)
             this.prevOrderIterateRecurse(node.left,callback);
             this.prevOrderIterateRecurse(node.right,callback);
         }
       }
/*調用*/
var res=''
bst.prevOrderIterate(function(e) {
    res+=' '+e;
})
console.log(res);

JavaScript實現中序遍歷、後序遍歷
思想同前序遍歷,只需改變遞歸操作中的順序即可

/**
* @name:中序遍歷 
* @params: 接收參數的回調 callback: [Function]
* @return: undefined
*/
BinarySearchTree.prototype.midOrderInterate=function (callback) {
   this.midOrderInterateRecurse(this.root,callback);
};
// 中序遍歷遞歸
BinarySearchTree.prototype.midOrderInterateRecurse=function (node,callback) {
   if(node!==null){
       this.midOrderInterateRecurse(node.left,callback);
       callback(node.key);
       this.midOrderInterateRecurse(node.right,callback);
   }
};
/**
* @name:後序遍歷 
* @params: 後序遍歷的回調 callback [Function]
* @return: undefined
*/
BinarySearchTree.prototype.aftOrderInterate=function (callback) {
   this.aftOrderInterateRecurse(this.root,callback);
};
// 後序遍歷遞歸
BinarySearchTree.prototype.aftOrderInterateRecurse=function (node,callback) {
   if(node!==null){
       this.midOrderInterateRecurse(node.left,callback);
       this.midOrderInterateRecurse(node.right,callback);
       callback(node.key);
   }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章