package com.data.java.towtree; import java.io.IOException; /** * 二叉樹 * @Title: uminton */ class Node{ public int iData; //數據用做關鍵值 public double dData; //其餘數據 public Node leftChild; //左子節點 public Node rightChild; //右子節點 public Node() { } public Node(int iData, double dData) { this.iData = iData; this.dData = dData; } public void displayNode(){ System.out.print("{"); System.out.print(iData); System.out.print(", "); System.out.print(dData); System.out.print("} "); } } public class Tree { private Node root; //根節點 public Node getRoot() { return root; } /** * 查找一個數據 * @param key * @return */ public Node find(int key){ Node current = root; //把跟節點設置爲當前節點 while (current.iData != key){ //循環查找 if(key < current.iData){ //若是小於就去當前樹的左邊子節點 current = current.leftChild; //把子節點賦給當前節點 }else { //若是大於就去當前樹的右邊子節點 current = current.rightChild;//把子節點賦給當前節點 } if(current == null){ //到達序列的末端沒有找到節點,代表他不存在,返回空 return current; } } return current; //循環條件相等,循環結束,找到結果。 } /** * 添加一個數據 * @param id * @param dd */ public void insert(int id, double dd) { Node newNode = new Node(id, dd); //先建立一個新節點 if(root == null){ //若是跟節點爲空,表示樹,沒有數據,直接賦值給根節點 root = newNode; }else { Node current = root; //根節點賦值給當前節點,用於查找 Node parent; //父節點,用來存儲遇到的最後一個不是null的節點,由於curent在查找的過程當中會變成null, // 才能發現發現查找過得上一個節點沒有子節點 while (true){ //循環查找 parent = current; //用來存儲遇到的最後一個不是null的節點 if (id < current.iData){ //若是小於就去當前樹的左邊子節點 current = current.leftChild; if(current == null){ //到達序列的末端沒有找到節點,代表他不存在 parent.leftChild = newNode; //把新的節點賦值給父節點的左子節點 return; //直接返回,結束循環 } }else { current = current.rightChild; if(current == null){ parent.rightChild = newNode; return; } } } } } /** * 刪除一個數據 * @param key * @return * * 刪除節點要考慮的三種狀況 * 1,該節點是葉節點 * 2,該節點有一個子節點 * 3,該節點有二個子節點 */ public boolean delete(int key){ Node current = root; Node parent = root; boolean isLeftChild = true; //記錄是左節點仍是右節點 while(current.iData != key){ //循環爲了找到要刪除的節點,循環條件若是相等就是找到了,退出循環 parent = current; //保存要刪除的父節點 if(key < current.iData){ isLeftChild = true; current = current.leftChild; }else { isLeftChild = false; current = current.rightChild; } if(current == null){ //查找到末端,都沒有找到,返回false return false; } } /**************************狀況1開始*********************************/ if(current.leftChild == null && current.rightChild == null) { //判斷是否沒有子節點,也就是該節點是葉節點 if (current == root) { //若是是根節點,直接賦值爲null root = null; } else if (isLeftChild) { //判斷是不是左節點 parent.leftChild = null; //用上面保存的父節點找子節點,直接賦值爲null } else { parent.rightChild = null; } /**************************狀況1結束*********************************/ /**************************狀況2開始*********************************/ }else if (current.rightChild == null){ //判斷左邊等null或右邊等於null if(current == root){ //若是是根節點,直接賦值爲null root = current.leftChild; }else if (isLeftChild){ //判斷是不是左節點 parent.leftChild = current.leftChild;//用上面保存的父節點找子節點,直接賦值爲null }else { parent.rightChild = current.leftChild; } }else if (current.leftChild == null){ //下面同理 if(current == root){ root = current.rightChild; }else if (isLeftChild){ parent.leftChild = current.rightChild; }else { parent.rightChild = current.rightChild; } /**************************狀況2結束*********************************/ /**************************狀況3開始*********************************/ }else { //上面都不成立,代表該節點有兩個子節點。 Node successor = getSuccessor(current); //取得後繼者 if(current == root){ //若是是根節點,直接賦值爲後繼者 root = successor; }else if (isLeftChild){ //判斷是不是左節點 parent.leftChild = successor; //用上面保存的父節點找子節點,直接賦值爲後繼者 }else { parent.rightChild = successor; } successor.leftChild = current.leftChild; } /**************************狀況3結束*********************************/ return true; } /** * 中序遍歷樹 * @param localRoot */ public void inOrder(Node localRoot){ if(localRoot != null){ inOrder(localRoot.leftChild); System.out.println(localRoot.iData); inOrder(localRoot.rightChild); } } /** * 查找最小值 * @return */ public Node minNumber(){ Node current = root; Node last = null; while (current != null){ last = current; current = current.leftChild; } return last; } /** * 獲取刪除節點的後繼者 * @param delNode * @return * 算法:程序找到要刪除的節點的右子節點,(它的關鍵字值必定比要刪除的節點的值大)而後轉到右子節點的左子節點(若果有的話) * 而後到這個左子節點的左子節點,以此類推,這個路徑的最後一個左子節點就是要刪除節點的後繼者 * 若果刪除節點右子節點沒有左子節點,它就是後繼者 */ private Node getSuccessor(Node delNode) { Node successorParent = delNode; Node successor = delNode; Node current = delNode.rightChild; //刪除節點右子節點 while (current != null){ successorParent = successor; //保留後繼者的父節點 successor = current; //後繼者 current = current.leftChild; //循環查找左子節點 } if(successor != delNode.rightChild){ successorParent.leftChild = successor.rightChild; successor.rightChild = delNode.rightChild; } return successor; } } class TreeApp{ public static void main(String[] args) throws IOException { Tree treTree = new Tree(); treTree.insert(38,1.5); treTree.insert(65,1.5); treTree.insert(40,1.5); treTree.insert(50,1.5); treTree.insert(55,1.5); treTree.insert(30,1.5); treTree.insert(90,1.5); treTree.insert(25,1.6); treTree.insert(70,1.7); treTree.insert(20,1.7); treTree.insert(80,1.7); treTree.delete(65); } }
最後刪除有點複雜,沒怎麼搞懂見諒。java