二叉搜索樹 思想 JAVA實現

二叉搜索樹:一棵二叉搜索樹是以一棵二叉樹來組織的,這樣一棵樹能夠使用鏈表的數據結構來表示(也能夠採用數組來實現)。除了key和可能帶有的其餘數據外,每一個節點還包含Left,Right,Parent,它們分別指節點的左孩子,右孩子,和父節點。java

一個二叉搜索樹老是知足 :node.left.key<node.key<=node.right.key。node

如下是一個用java實現的二叉搜索樹,包含了查找最大值,最小值,查找某一節點,插入和刪除操做。算法

接下來經過代碼來分析二叉搜索樹中的思想:在代碼實現二叉搜索樹中,大量採用了遞歸的思想,一樣能夠採用循環去遞歸來實現。數組

插入:自根節點起遞歸調用「尋找合適位置方法」,使二叉搜索樹始終知足條件  node.left.key<node.key<=node.right.key數據結構

查詢:自根節點起遞歸調用「查找孩子的方法」。查找孩子的方法採用的思想是,判斷node.key==key 返回,node.key>key 遞歸查找左子樹,node.key<=key 遞歸查             找右子樹。this

查詢最小值:遞歸查找左孩子,直到最後一個左孩子。spa

查詢最大值:遞歸查找右孩子,直到最後一個右孩子。blog

遍歷:遞歸

前序遍歷:根的關鍵字輸出在左右子樹的關鍵字以前。根 左 右。class

中序遍歷:根的關鍵字輸出在左右子樹的關鍵字之間。左 根 右。

後序遍歷:根的關鍵字輸出在左右子樹的關鍵字以後。左 右 根。

刪除:刪除一棵搜索樹是比較麻煩的。共有如下4種狀況

1.刪除節點沒有孩子,直接斷開鏈接便可

2.a圖:刪除節點沒有左孩子,將右孩子移至刪除節點處

3.b圖:刪除節點沒有右孩子,將左孩子移至刪除節點處

4.c圖:有左右孩子,右孩子 沒有 左孩子,將右孩子移動至刪除節點處,將左孩子的父節點鏈接值右孩子。

5.d圖:有左右孩子,且右孩子也有左右孩子,則查找右孩子的最小節點,將最小節點移至刪除節點處。

public class SearchTree {
                     //樹的根節點
      private Node Root = null;
                     //內部類,結點
      private class Node{

         Node parent;//父節點
         Node Left;//左孩子
         Node Right;//右孩子
         int keyValue;//關鍵字

         public Node(Node parent,
                Node Left,
                Node Right,
                int keyValue) {
          this.parent = parent;
          this.Left = Left;
          this.Right = Right;
          this.keyValue = keyValue;
         }
      }

      public void delete(int value) {
        Node deleteNode = this.search(value);//查找刪除節點
        if(deleteNode.Left==null) {//沒有左孩子
          transplant(deleteNode, deleteNode.Right);
        }else if(deleteNode.Right==null) {//沒有右孩子
          transplant(deleteNode, deleteNode.Left);
        }else {//有左右孩子時
          Node min = this.min(deleteNode.Right);//查找右孩子的最小節點
          if(min.parent!=deleteNode) {
            transplant(min, min.Right);
            min.Right = deleteNode.Right;
            min.Right.parent = min;
          }
        transplant(deleteNode, min);
        min.Left = deleteNode.Left;
        min.Left.parent = min;
        }
      }
                     

                     //交換子樹,將node2 移動至node1的位置。
      private void transplant(Node node1,Node node2) {
        if(node1.parent==null) {
          this.Root = node2;
        }else if(node1==node1.parent.Left) {
          node1.parent.Left = node2;
        }else {
          node1.parent.Right= node2;
        }
        if(node2!=null) {
          node2.parent = node1.parent;
        }
      }
                     

                     //查找方法
      public Node search(int value) {
        return searchNode(this.Root,value);
      }

      private Node searchNode(Node node,int key) {
        if(node==null || node.keyValue==key) {
          return node;
        }
        if(node.keyValue>key) {
          return this.searchNode(node.Left,key);
        }else {
          return this.searchNode(node.Right, key);
        }
      }

                     //插入方法
      public void insert(int value) {
        Node child = new Node(null, null, null, value);
        findRightPlace(this.Root,child);
      }

      private void findRightPlace(Node currentRoot,Node insertNode) {
        if(currentRoot!=null) {
            if(currentRoot.keyValue>insertNode.keyValue) {
              if(currentRoot.Left==null) {
                currentRoot.Left = insertNode;
                insertNode.parent = currentRoot;
              }else {
                findRightPlace(currentRoot.Left,insertNode);
                   }
            }else {
              if(currentRoot.Right==null) {
                currentRoot.Right = insertNode;
                insertNode.parent = currentRoot;
              }else {
                findRightPlace(currentRoot.Right,insertNode);
              }
            }
        }else {
            this.Root = insertNode;
        }
      }
                     

                     //查找最大
      public int findMax() {
        return max(this.Root)==null?-1:max(this.Root).keyValue;
      }

      private Node max(Node node) {
        if(node!=null) {
          if(node.Right!=null) {
            return max(node.Right);
          }else {
            return node;
          }
        }else {
          return null;
        }
      }
                     

                     //查找最小
      public int findMin() {
        return min(this.Root)==null?-1:min(this.Root).keyValue;
      }

      private Node min(Node node) {
        if(node!=null) {
          if(node.Left!=null) {
            return min(node.Left);
          }else {
            return node;
          }
        }else {
          return null;
        }
      }
                     

                     //後序遍歷
      public void after() {
        afterShow(this.Root);
      }

      private void afterShow(Node node) {
        if(node!=null) {
          afterShow(node.Left);
          afterShow(node.Right);
          System.out.println(node.keyValue);
        }
      }

                     //中序遍歷
      public void mid() {
        midShow(this.Root);
      }

      private void midShow(Node node) {
        if(node!=null) {
          midShow(node.Left);
          System.out.println(node.keyValue);
          midShow(node.Right);
        }
      }

                     //前序遍歷
      public void ahead() {
        aheadShow(this.Root);
      }

      private void aheadShow(Node node) {
        if(node!=null) {
          System.out.println(node.keyValue);
          aheadShow(node.Left);
          aheadShow(node.Right);
        }
}

 參考資料 《算法導論》第三版

相關文章
相關標籤/搜索