首先是Node 類的定義
package SearchTree;public class Node {private Node left;private Node right;private Node Parrent;int data;public Node(Node left, Node right, Node parrent, int data) {super();this.left = left;this.right = right;Parrent = parrent;this.data = data;}public void setLeft(Node left) {this.left = left;}public void setRight(Node right) {this.right = right;}public void setParrent(Node parrent) {Parrent = parrent;}public void setData(int data) {this.data = data;}public Node getLeft() {return left;}public Node getRight() {return right;}public Node getParrent() {return Parrent;}public int getData() {return data;}}
接著是,Tree 類的定義(各種常用的操作)
package SearchTree;public class Tree {private Node boot=null; // 二叉尋找樹的根節點public Node getBoot() {return boot;}public void setBoot(Node boot) {this.boot = boot;}public void Tree_Insert(Node i_node) // 在樹中插入一個節點 i_node{Node y = null;Node x = boot;while(x!=null){y = x;if(i_node.getData() < x.getData())x = x.getLeft();else x = x.getRight();}i_node.setParrent(y); // 設定插入節點的 父節點if(y == null) // This Tree is empty;{boot = i_node;}else if(y.getData() > i_node.getData())y.setLeft(i_node);else y.setRight(i_node);}public void InOrder_Tree_Walk() // 中序遍曆輸出樹{Traversal(boot);}private void Traversal(Node x){if(x!=null){Traversal(x.getLeft());System.out.println(x.getData());Traversal(x.getRight());}}public Node Tree_Search(int data){//Node find =RecursionSearch(boot, data); // 遞迴的尋找Node find = Non_RecursionSearch(boot, data); // 非遞迴的尋找if(find == null)System.out.println("Warning:The element that you are searching is not in the tree!");else System.out.println("find the element in the tree!");return find;}private Node RecursionSearch(Node b,int data){if(b==null || b.getData()==data) // | 和 || 兩者之間什麼關係 ?return b;if(b.getData() < data)return RecursionSearch(b.getRight(), data);else return RecursionSearch(b.getLeft(), data);}private Node Non_RecursionSearch(Node b,int data) // 非遞迴的尋找的實現{while(b!=null && b.getData()!=data){if(b.getData() > data)b = b.getLeft();else b = b.getRight();}return b;}/*** * 返回樹中最小的元素 ,如果樹為空白的話,返回空的引用 * @return */public Node Tree_Minmum() {if(boot==null)return null;Node find = minmum(boot);return find;}private Node minmum(Node x){while(x.getLeft()!=null)x= x.getLeft();return x;}/** * 返回樹中最大的元素,如果樹為空白的話,返回空的引用 * @return */public Node Tree_Maximum(){if(boot == null)return boot;Node find = Maximum(boot);return find;}private Node Maximum(Node x){while(x.getRight()!=null)x = x.getRight();return x;}/** * 尋找一個給定元素data的後繼(如果該元素存在的話) * 存在兩種情景:1:存在右孩子,則求右孩子的minmum即可 * 2: 不存在右孩子,那麼向上迴圈尋找一個父節點,它的左孩子等於迴圈中的x,此時該點為其後繼 * @param data * @return * while 迴圈是本函數的核心代碼(痛點) */public Node Tree_Successor(int data){Node x= Tree_Search(data); // 獲得元素data 的節點引用。if(x==null) return null;if(x.getRight()!=null)return minmum(x.getRight());Node y = x.getParrent();while(y!=null && x==y.getRight()){x=y;y= y.getParrent();}return y;}/** * Funtion:尋找一個給定元素的中序遍曆的前驅節點,有兩種情況: * 1:該節點存在左孩子,那麼求左孩子的Maximum * 2:該節點沒有左孩子,那麼向上遞迴求(通過迴圈)一個存在右孩子的節點,即為所求節點的前驅節點 * @param data * @return */public Node Tree_Predecessor(int data){Node x = Tree_Search(data); // 獲得元素data 的引用if(x==null) return null;if(x.getLeft()!=null) // 第一種情況,存在左孩子return Maximum(x.getLeft());Node y = x.getParrent();while(y!=null && y.getLeft()==x){x=y;y= y.getParrent();}return y;}/** * funtion:刪除樹中的元素data(如果存在的話),刪除時存在三種情況: * 1:該節點沒有孩子節點,則,直接刪除 * 2:該節點有一個孩子節點,那麼刪除節點之後,將該節點的父節點執行該節點的子節點 * 3:存在兩個子節點,那麼將該節點的後繼,覆蓋帶該節點即可,後繼節點一定不會有兩個子節點 * @param data */public void Tree_Delete(int data){Node z = Tree_Search(data);Node x,y;if(z==null)return; // 不存在元素data if((z.getLeft()==null)||(z.getRight()==null)) //如果是前兩種情況 { y = z; } else y = Tree_Successor(data);// 第三種情況 if(y.getLeft()!=null) // 獲得要刪除節點的子節點 x = y.getLeft(); else x = y.getRight(); if(x!=null) x.setParrent(y.getParrent()); if(y.getParrent()==null) boot = x; else if(y==y.getParrent().getLeft()) y.getParrent().setLeft(x); else y.getParrent().setRight(x); if(y!=z) //刪除節點不是指定節點,那麼是第三種情況 { z.setData(y.getData()); //修改刪除節點的data 域為它的後繼節點的data域 ,相對於寫該引用簡單很多 }}}
MainClass ,調試的主類:
package SearchTree;public class MainClass {/** * @param args */public static void main(String[] args) {// TODO Auto-generated method stubTree T =new Tree();int[] a = {4 ,3 ,5,2,6,7,1};for(int i=0;i < a.length; i++){T.Tree_Insert(new Node(null, null, null, a[i]));}T.InOrder_Tree_Walk();System.out.println("The minmum element is :" +T.Tree_Minmum().getData());System.out.println("The Maximum element is :" + T.Tree_Maximum().getData());System.out.println("The element 6's successor is:" + T.Tree_Successor(6).getData());System.out.println("The element 6's predecessor is:" + T.Tree_Predecessor(6).getData());T.Tree_Delete(5);T.InOrder_Tree_Walk();}}