二叉排序樹的非遞歸插入,非遞歸查詢,尋找最大值,尋找最小值java
package whut.tree; //二叉排序樹的非遞歸插入,非遞歸查詢,尋找最大值,尋找最小值 class Node { private int data; private Node left; private Node right; public Node(int data) { this.data = data; } public int getData() { return data; } public Node getLeft() { return left; } public void setLeft(Node left) { this.left = left; } public Node getRight() { return right; } public void setRight(Node right) { this.right = right; } // 展現節點數據 public void displayNode() { System.out.println(" " + data + " "); } } // 樹 public class BinaryTree { private Node root;// 樹根 // 非遞歸方式插入新的節點數據, public void insert(int data) { Node newNode = new Node(data); if (root == null) { root = newNode; } else { // 子節點,當前節點 Node current = root; // 父節點 Node parent; while (true)// 尋找插入的位置 { parent = current; // 當小於根節點,插入到左邊 if (data < current.getData()) { current = current.getLeft(); // 跳出循環 if (current == null) { parent.setLeft(newNode); return; } } else { current = current.getRight(); if (current == null) { parent.setRight(newNode); return; } } } } } // 非遞歸方式實現查詢 public Node find(int data) { Node current = root; while (current.getData() != data) { if (current.getData() < data) current = current.getLeft(); else current = current.getRight(); // 當一個元素不在一個二叉樹中,確定爲null了 if (current == null) return null; } // 跳出循環說明找到了那個相等的 return current; } // 找二叉樹最小的節點,一直遍歷左孩子,直到其左孩子爲null public Node findMinNode() { Node current; Node parent; // if (root == null) { return null; } else { parent = root; current = parent.getLeft(); while (current != null) { parent = current; current = current.getLeft(); } return parent; } } // 找到二叉排序樹的最大值,也就是最右邊的孩子 public Node findMaxNode() { Node current; Node parent; // if (root == null) { return null; } else { parent = root; current = parent.getRight(); while (current != null) { parent = current; current = current.getRight(); } return parent; } } // 先要找到節點,而後根據要刪除節點的位置進行刪除 // 刪除的節點有三種,葉子節點,有一個節點的節點,有兩個節點的節點 public boolean delete(int key) { Node current = root; Node parent = root; // 這裏主要是爲了區分刪除的是左孩子仍是右孩子 boolean isLeftChild = false; // 顯然,當current.iData == key 時,current就是須要刪除的節點 // 在循環中利用parent保存了父類節點 while (current.getData() != key) { parent = current; if (key < current.getData()) { isLeftChild = true; current = current.getLeft(); } else { isLeftChild = false; current = current.getRight(); } if (current == null)// 找不到key時返回false return false; } // 當節點爲葉子節點的時候 if (current.getLeft() == null && current.getRight() == null) { if (current == root) root = null; else if (isLeftChild) parent.setLeft(null); else parent.setRight(null); } // 當刪除的節點爲含有一個子節點的節點 // 刪除的節點只有一個左子節點時 // 必需要考慮被刪除的節點是左節點仍是右節點 else if (current.getRight() == null) { if (current == root)// 要刪除的節點爲根節點 root = current.getLeft(); else if (isLeftChild)// 要刪除的節點是一個左子節點 parent.setLeft(current.getLeft()); else parent.setRight(current.getLeft());// 要刪除的節點是一個右子節點 } // 當刪除的節點爲含有一個子節點的節點 // 刪除的節點只有一個右子節點時 // 必需要考慮被刪除的節點是左節點仍是右節點 else if (current.getLeft() == null) { if (current == root)// 要刪除的節點爲根節點 root = current.getRight(); else if (isLeftChild)// 要刪除的節點是一個左子節點 parent.setLeft(current.getRight()); else parent.setRight(current.getRight());// 要刪除的節點是一個右子節點 } // 當要刪除的節點是含有兩個節點的時候 else { //首先要獲取被刪除節點的後繼節點,current Node successor = getSuccessor(current); if(current == root) root = successor ; //這裏已經屏蔽了後繼節點是葉子和非葉子節點 else if(isLeftChild) parent.setLeft(successor); else parent.setRight(successor); successor.setLeft(current.getLeft()); } return true; } // 尋找後記節點,主要是當要刪除的節點包含了兩個子節點的時候 // 返回後繼節點,後繼節點就是比要刪除的節點的關鍵值要大的節點集合中的最小值。 //後繼節點要麼是被刪除節點的不包含左子節點的右節點,要麼就是包含左子節點的右節點的子節點 private Node getSuccessor(Node delNode) { // 後繼節點的父節點 Node successorParent = delNode; // 後繼節點 Node successor = delNode.getRight(); //判斷後繼節點是否有左孩子 Node current = successor.getLeft(); while (current != null) { successorParent = successor; successor = current; current = current.getLeft(); } //當該後繼節點是屬於包含左子節點的右節點的子節點 if (successor != delNode.getRight()) { successorParent.setLeft(successor.getRight()); //鏈接被刪除節點的右孩子 successor.setRight(delNode.getRight()); } return successor; } // 下面三種遍歷樹 // 三種遍歷均是採用遞歸實現的 // 前序遍歷 public void preOrder(Node localRoot) { if (localRoot != null) { localRoot.displayNode();// 訪問這個節點 preOrder(localRoot.getLeft());// 調用自身來遍歷左子樹 preOrder(localRoot.getRight());// 調用自身來遍歷右子樹 } } // 中序遍歷 public void midOrder(Node localRoot) { if (localRoot != null) { preOrder(localRoot.getLeft());// 調用自身來遍歷左子樹 localRoot.displayNode();// 訪問這個節點 preOrder(localRoot.getRight());// 調用自身來遍歷右子樹 } } // 後續遍歷 public void lastOrder(Node localRoot) { if (localRoot != null) { preOrder(localRoot.getLeft());// 調用自身來遍歷左子樹 preOrder(localRoot.getRight());// 調用自身來遍歷右子樹 localRoot.displayNode();// 訪問這個節點 } } }
二叉排序樹的遞歸插入,遞歸遍歷,遞歸查詢app
package whut.tree; //二叉樹的存儲,這裏會創建一個二叉排序樹,遞歸方式 public class NodeTree { public int value; public NodeTree left; public NodeTree right; //遞歸實現存儲 public void store(int value) { if (value < this.value) { if (left == null) { left = new NodeTree(); left.value = value; } else { left.store(value); } } else if (value > this.value) { if (right == null) { right = new NodeTree(); right.value = value; } else { right.store(value); } } } public boolean find(int value) { System.out.println("find happen " + this.value); if (value == this.value) { return true; } else if (value > this.value) { if (right == null) return false; return right.find(value); } else { if (left == null) return false; return left.find(value); } } //前序遍歷 public void preList() { System.out.print(this.value + ","); if (left != null) left.preList(); if (right != null) right.preList(); } //中序遍歷 public void middleList() { if (left != null) left.middleList(); System.out.print(this.value + ","); if (right != null) right.middleList(); } //後續遍歷 public void afterList() { if (left != null) left.afterList(); if (right != null) right.afterList(); System.out.print(this.value + ","); } public static void main(String[] args) { int[] data = new int[20]; for (int i = 0; i < data.length; i++) { data[i] = (int) (Math.random() * 100) + 1; System.out.print(data[i] + ","); } System.out.println(); NodeTree root = new NodeTree(); root.value = data[0]; for (int i = 1; i < data.length; i++) { root.store(data[i]); } //查詢 root.find(data[19]); //先序 root.preList(); System.out.println(); //中序 root.middleList(); System.out.println(); //後續 root.afterList(); } }