天天看點

JAVA之二叉查找樹

一:二叉樹的概念:

  二叉樹指的是每個節點最多隻能有兩個子樹的有序樹。通常左邊的子樹被稱為“左子樹”,右邊的子樹被稱為“右子樹”。由此可見,二叉樹仍然是樹,隻是一種特殊的樹。

  二叉樹的每個節點最多隻有兩棵子樹(不存在大于2的節點)。二叉樹有左、右之分,不能颠倒。

樹和二叉樹的兩個重要差別如下:

  1.樹中節點的最大度數沒有限制,而二叉樹節點的最大度數為2,也就是說,二叉樹的節點最大度數為2。

  2.無序樹的節點無左右之分,而二叉樹的節點有左右之分,也就是說二叉樹是有序樹。

滿二叉樹:

      

JAVA之二叉查找樹

   一棵深度為K的二叉樹,如果它包含了2^K - 1個節點,就把這棵二叉樹稱為滿二叉樹。滿二叉樹的特點是,每一層上的節點數都是最大節點數,即各層節點數分别為1,2,4,8,16,32,……,2^(K-1) 。

完全二叉樹:

JAVA之二叉查找樹

  如果一棵二叉樹除最後一層外,其餘所有的節點都是滿的,并且最後一層或者是滿的,或者僅在右邊缺少若幹連續的節點,則此二叉樹就是完全二叉樹。

 差別:滿二叉樹是一種特殊的完全二叉樹。當完全二叉樹最後一層的所有節點都是滿的情況下,這棵完全二叉樹就變成了滿二叉樹。

   

 二:實作二叉樹的基本操作:

 首先定義我們的節點類:

1 package mytree;
 2 
 3 public class Node {
 4     int value;//值域
 5     Node left;//左子節點
 6     Node right;//右子節點
 7     public Node(int value) {
 8         this.value=value;
 9     }
10     @Override
11     public String toString() {
12         return String.valueOf(value);
13     }
14     
15     public void display(){
16         System.out.print(this.value+"\t");
17     }
18     
19 }      

定義我們的方法類:

1 public class BinaryTree {
2     private Node root = null;
3 
4     public BinaryTree(int value) {
5         root = new Node(value);
6         root.left = null;
7         root.right = null;
8     }
9 }      

1.實作添加節點:

  第一種:

1 public String insert(int value) { // 插入
 2         String error = null;//錯誤
 3         Node now = new Node(value);//建立要插入的節點
 4         Node curr = root;//擷取到根節點
 5         if (curr == null) {//如果根節點為空
 6             curr = now;//就把要插入的節點作為根節點
 7         } else {
 8             while (true) {
 9                 Node parent = null;//先建立一個臨時存放節點
10                 if (curr.value > value) {//如過目前節點>要插入的節點,就把節點插入到左子節點
11                     parent = curr;//把主節點指派給他
12                     curr = curr.left;//擷取到左子節點
13                     if (curr == null) {//如果左子節點為空的話
14                         parent.left = now;//插入
15                         break;
16                     }
17                 } else if (curr.value < value) {
18                     parent = curr;
19                     curr = curr.right;
20                     if (curr == null) {
21                         parent.right = now;
22                         break;
23                     }
24                 } else {
25                     error = "樹裡面有了相同的值:";
26                 }
27             }
28         }
29         return error;
30     }      

第二種遞歸添加:

1 /*
 2      * 插入遞歸調用實作
 3      * 
 4      * */
 5     public Node insert2(Node node, int data) {
 6         if (node == null) {  
 7             node = new Node(data);  
 8         } else {  
 9             if (data <= node.value) {  
10                 node.left = insert2(node.left, data);  
11             } else {  
12                 node.right = insert2(node.right, data);  
13             }  
14         }  
15         return (node);  
16     }  
17           

2.定義一個直接傳回整個二叉樹的方法:

 1 public Node getrootNode(){//傳回整個二叉樹 2 return root; 3 } 

 3.定義一個周遊節點的方法(中序周遊):

1 /** 
 2      * //中序周遊(遞歸): 
 3      *    1、調用自身來周遊節點的左子樹 
 4      *    2、去取得目前節點
 5      *    3、調用自身來周遊節點的右子樹 
 6      */ 
 7     public void inOrderTraverse(Node node) {  
 8         if (node == null)   
 9             return ;  
10         inOrderTraverse(node.left);  
11         node.display();  
12         inOrderTraverse(node.right);  
13     }  
14           

4.我們建立一個測試類看看我們的方法是不是寫的都是正确的:

1 package mytree;
 2 
 3 public class Test {
 4 
 5     public static void main(String[] args) {
 6         // TODO Auto-generated method stub
 7         BinaryTree b=new BinaryTree(12);
 8         b.insert(10);//普通插入方法
 9         Node no=b.getrootNode();//擷取到二叉樹對象
10         b.insert2(no, 20);//通過遞歸插入
11         no=b.getrootNode();
12         b.inOrderTraverse(no);//中序周遊
13     }    
14 }      

 運作為:

JAVA之二叉查找樹

看來寫的添加節點與周遊節點都是可以的;

 5.前序周遊:

1 /*前序周遊
 2  * 通路節點
 3  * 通路自身來周遊左子樹
 4  * 通路自身來周遊右子樹
 5  * */
 6     public void PreOrderTraverse(Node node) {
 7         if (node == null)
 8             return;
 9         inOrderTraverse(node.left);
10         node.display();
11         inOrderTraverse(node.right);
12     }      

6.後序周遊:

1 /*後序周遊
 2      * 
 3      * 通路自身來周遊左子樹
 4      * 通路自身來周遊右子樹
 5      * 通路節點
 6      * */
 7         public void nexOrderTraverse(Node node) {
 8             if (node == null)
 9                 return;
10             inOrderTraverse(node.left);
11             inOrderTraverse(node.right);
12             node.display();
13         }      

7.得到最小值:(其實也就是一直周遊左子樹直到空)

1  public int getMinValue() {  
2             Node current = root;  
3             while (true) {  
4                 if (current.left== null)  
5                     return current.value;  
6                   
7                 current = current.left;  
8             }  
9         }      

8.得到最大值:(其實也就是一直周遊右子樹直到空)

1  
 2         public int getMaxValue() {  
 3             Node current = root;  
 4             while (true) {  
 5                 if (current.right== null)  
 6                     return current.value;  
 7                   
 8                 current = current.right;  
 9             }  
10         }      

臨時有事,查找删除再整理;

歡迎大家一起說出自己的想法。