JAVA之二叉尋找樹,java二叉尋找
一:二叉樹的概念:
二叉樹指的是每個節點最多隻能有兩個子樹的有序樹。通常左邊的子樹被稱為“左子樹”,右邊的子樹被稱為“右子樹”。由此可見,二叉樹仍然是樹,只是一種特殊的樹。
二叉樹的每個節點最多隻有兩棵子樹(不存在大於2的節點)。二叉樹有左、右之分,不能顛倒。
樹和二叉樹的兩個重要區別如下:
1.樹中節點的最大度數沒有限制,而二叉樹節點的最大度數為2,也就是說,二叉樹的節點最大度數為2。
2.無序樹的節點無左右之分,而二叉樹的節點有左右之分,也就是說二叉樹是有序樹。
滿二叉樹:
一棵深度為K的二叉樹,如果它包含了2^K - 1個節點,就把這棵二叉樹稱為滿二叉樹。滿二叉樹的特點是,每一層上的節點數都是最大節點數,即各層節點數分別為1,2,4,8,16,32,……,2^(K-1) 。
完全二叉樹:
如果一棵二叉樹除最後一層外,其餘所有的節點都是滿的,並且最後一層或者是滿的,或者僅在右邊缺少若干連續的節點,則此二叉樹就是完全二叉樹。
區別:滿二叉樹是一種特殊的完全二叉樹。當完全二叉樹最後一層的所有節點都是滿的情況下,這棵完全二叉樹就變成了滿二叉樹。
二:實現二叉樹的基本操作:
首先定義我們的節點類:
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 @Override11 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 }
運行為:
看來寫的添加節點與遍曆節點都是可以的;
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 }
臨時有事,尋找刪除再整理;