實現排序二叉樹

概念

二叉樹:如圖。html

  • 某個節點最多有兩個子節點的樹。經常使用於排序。效率較高。
  • 節點中的值:鍵。key。
  • 兄弟節點:擁有同一個父節點的節點。
  • 根節點:沒有父節點
  • 外部節點:葉子節點,沒有子節點。
  • 內部節點:中間節點。有子節點。
  • 高:節點都有深度,最大的節點深度即爲這棵樹的高。
  • 排序二叉樹:節點左孩子的值小於它,右孩子的值大於它。顯然,左子樹的節點值都比當前節點小,右子樹的逗比當前節點大。

代碼實現

須要建立對象實現其基本結構、封裝相應屬性和方法。建立對象或者繼承對象的方法可見《JavaScript高級程序設計》第六章。此次實現則採起了構造函數進行封裝的方法。node

結構

  • 完整的排序二叉樹,包括對節點(特別地,根節點)結構的描述、以及必要的方法。
  • 節點的通常結構:
    var Node = function(key){
        this.key = key;
        this.left = null;
        this.right = null;
    };
    
    var root = null;
  • 其實是個也是個節點的構造函數,將在以後的insert()方法中對其進行調用。

方法

  • 有了基本的節點結構,就能夠在此基礎上使用必要的方法來建立、遍歷、查詢、刪除排序二叉樹了。
  • 建立一棵排序二叉樹:insert(key)方法
    1. 基本描述:顯然須要一個一個的插入相應的節點值,最後循環獲得完整的排序二叉樹。
    2. 分析:須要經過遞歸依次將待插入的節點與排序二叉樹的部分節點進行大小比較。從根節點開始,遵循左子節點小於當前節點,右子節點大於當前節點的規則。就是說,須要考慮兩種狀況:插入根節點、插入通常節點。
    3. 藉助:insertNode(key)函數。
    4. 遞歸:如圖(藉助中序遍歷進行說明)。遞歸函數有個進棧和退棧的過程。當本次遞歸中全部語句執行完畢(這是通常狀況,函數執行完畢都會默認return)或者遇到return語句的時候,會返回上一個調用此次遞歸的位置。並從該位置開始繼續執行接下來的語句。
  • 遍歷二叉樹:
    • 一樣涉及遞歸。
    • 操做的對象是整棵樹
    • 顯然x序遍歷的「x」是前/中/後取決於當前節點的位置,而左一直在右前面
    • 中序遍歷:
      1. 遍歷順序:左子節點(樹)->當前節點->右子節點(樹);
      2. 適合進行升序打印。
      3. 方法:inOrderTraverse(callback);//從根節點開始,callback()就是處理遍歷到的節點的方法,較靈活。藉助inOrderTraverseNode(node,callback)函數
    • 前序遍歷:
      1. 遍歷順序:當前節點->左子節點(樹)->右子節點(樹);
      2. 適合進行排序二叉樹的複製,效率比建立一棵一樣的二叉樹高;
      3. 方法:preOrderTraverse(callback);//從根節點開始,callback()就是處理遍歷到的節點的方法,較靈活。藉助preOrderTraverseNode(node,callback)函數
    • 後序遍歷:
      1. 遍歷順序左子節點(樹)->右子節點(樹)->當前節點;
      2. 適合進行文件系統的遍歷。
      3. 方法:postOrderTraverse(callback);//從根節點開始,callback()就是處理遍歷到的節點的方法,較靈活。藉助postOrderTraverseNode(node,callback)方法。
  • 查找二叉樹
    • 查找是否有符合條件的節點。
    • 一樣涉及遍歷。
    • 查找整棵二叉樹的最小值:從根節點開始,不斷查找左子節點,直到某一個左子節點是葉節點,即爲最小值對應的節點。
    • 查找整棵二叉樹的最大值:從根節點開始,不斷向右子節點查找,直到某一個右子節點是葉節點,即爲最大值對應的節點
    • 查找任意值輸入值:
      1. 與當前節點比較大小:若相同返回這個值;若小於當前節點,則進入左子樹;若大於當前節點,則進入右子樹。。。
      2. 直至找到相同值 or 沒法繼續查找(沒有左節點或者右節點了),前者表示二叉樹中存在相應節點(能夠返回true或其餘操做);後者表示不存在相應節點(能夠返回false或進行其餘操做)
      3. search(key)方法,藉助search(node,key)函數。通常從根節點開始查找。
  • 刪除節點(比較重要)
    • 一樣涉及遍歷
    • 有如下對應狀況須要進行處理:
      1. 若只有一個子節點(只有左節點or右節點):刪除該節點,將其父節點與其子節點鏈接起來。
      2. 若沒有子節點(葉子節點):刪除該節點,且刪除其父節點指向他的鏈接(=null)
      3. 如有兩個子節點:從右子樹中找到值最小的那個,用其代替刪除的節點。固然須要注意處理一些細節問題。好比幾處指針的指向。
    • remove(key)方法。藉助removeNode(node,key)函數。一樣通常從根節點開始。
    • 其實涉及到節點的查找。

其餘連接

相關文章
相關標籤/搜索