對於一個任何一個節點x,它的左子樹中的關鍵字最大不超過x.key,其右子樹的關鍵字的值最小不低於x.key。前端
例以下圖後端
刪除比較複雜一點,咱們分三種狀況來處理,例如一棵樹T中要刪除的節點的爲z。post
下面是以上操做的JAVA版本提實現 。測試
1 表明樹節點的類this
/** * Created by dupang on 2017/11/12. */ public class TreeNode<T> { /** * 節點的左孩子 */ private TreeNode<T> left; /** * 節點的右孩子 */ private TreeNode<T> right; /** * 節點的父親 */ private TreeNode<T> parent; /** * 節點的值 */ private T value; public TreeNode(){ } public TreeNode(TreeNode<T> left,TreeNode<T> right,TreeNode<T> parent,T value){ this.left=left; this.right=right; this.parent=parent; this.value=value; } public TreeNode<T> getLeft() { return left; } public void setLeft(TreeNode<T> left) { this.left = left; } public TreeNode<T> getRight() { return right; } public void setRight(TreeNode<T> right) { this.right = right; } public TreeNode<T> getParent() { return parent; } public void setParent(TreeNode<T> parent) { this.parent = parent; } public T getValue() { return value; } public void setValue(T value) { this.value = value; } }
2 各個操做測試類spa
/** * Created by dupang on 2017/11/12. */ public class SearchTreeTest { public static void main(String[] args) { int[] values = new int[]{18,5,3,9,2,13,32}; //初始化一個表示樹的根節點 TreeNode<Integer> root = new TreeNode<>(null,null,null,null); //遍歷插入 for (Integer value:values){ //初始化要插入的節點 TreeNode<Integer> treeNode = new TreeNode<>(null,null,null,value); insert(root,treeNode); } //中序遍歷 inOrderTreeWalk(root); System.out.println(); //先序遍歷 preOrderTreeWalk(root); System.out.println(); //後序遍歷 postOrderTreeWalk(root); System.out.println(); TreeNode<Integer> treeNode = treeSearch(root,3); //求最大值 treeMaximum(root); //求最小值 treeMinimum(root); //後繼 treeSuccessor(root); //前驅 treeSuccessor(root); } /** * 二叉搜索樹的插入操做 * @param root 二叉樹的根 * @param tTreeNode 要插入的節點 */ public static void insert(TreeNode<Integer> root,TreeNode<Integer> tTreeNode){ //聲明一個y,用於記錄while循環中循環節點的位置,也就是插入節點要插入的位置 TreeNode<Integer> y = null; //把樹的根節點賦值給x,先從根節點開始尋找插入的點。 TreeNode<Integer> x = root; while (x!=null&&x.getValue()!=null){ y=x; //若是要插入的值比根節點的值大, if(tTreeNode.getValue()>x.getValue()){ x = x.getRight(); }else { x= x.getLeft(); } } //若是y是null,說明是個空樹 if(y==null){ root.setParent(null); root.setLeft(null); root.setRight(null); root.setValue(tTreeNode.getValue()); }else if(tTreeNode.getValue()>y.getValue()){ y.setRight(tTreeNode); tTreeNode.setParent(y); }else { y.setLeft(tTreeNode); tTreeNode.setParent(y); } } /** * 中序遍歷 * @param treeNode 根節點 */ public static void inOrderTreeWalk(TreeNode<Integer> treeNode){ if (treeNode!=null&&treeNode.getValue()!=null){ inOrderTreeWalk(treeNode.getLeft()); System.out.print(treeNode.getValue()+" "); inOrderTreeWalk(treeNode.getRight()); } } /** * 前序遍歷 * @param treeNode 根節點 */ public static void preOrderTreeWalk(TreeNode<Integer> treeNode){ if (treeNode!=null&&treeNode.getValue()!=null){ System.out.print(treeNode.getValue()+" "); inOrderTreeWalk(treeNode.getLeft()); inOrderTreeWalk(treeNode.getRight()); } } /** * 後序遍歷 * @param treeNode 根節點 */ public static void postOrderTreeWalk(TreeNode<Integer> treeNode){ if (treeNode!=null&&treeNode.getValue()!=null){ inOrderTreeWalk(treeNode.getLeft()); inOrderTreeWalk(treeNode.getRight()); System.out.print(treeNode.getValue()+" "); } } /** * 在樹中查詢指定值的節點 * @param treeNode 樹的節點 * @param k 要查詢的值 * @return 若是查詢到節點的值等於要查詢的值,就返回這個節點,不然返回null */ public static TreeNode<Integer> treeSearch(TreeNode<Integer> treeNode,Integer k){ if(treeNode==null||treeNode.getValue()==null||treeNode.getValue()==k){ return treeNode; } if(k>treeNode.getValue()){ return treeSearch(treeNode.getRight(),k); }else { return treeSearch(treeNode.getLeft(),k); } } /** * 在樹中找到最大值 * @param treeNode 樹的節點 * @return 若是查詢到節點的值等於要查詢的值,就返回這個節點,不然返回null */ public static TreeNode<Integer> treeMaximum(TreeNode<Integer> treeNode){ while (treeNode.getRight()!=null){ treeNode = treeNode.getRight(); } return treeNode; } /** * 在樹中找到最小值 * @param treeNode 樹的節點 * @return 若是查詢到節點的值等於要查詢的值,就返回這個節點,不然返回null */ public static TreeNode<Integer> treeMinimum(TreeNode<Integer> treeNode){ while (treeNode.getLeft()!=null){ treeNode = treeNode.getLeft(); } return treeNode; } /** * 找一個節點的後繼 * @return 一個節點的後繼 */ public static TreeNode<Integer> treeSuccessor(TreeNode<Integer> treeNode){ if(treeNode.getRight()!=null){ return treeMinimum(treeNode.getRight()); } TreeNode<Integer> y = treeNode.getParent(); while (y!=null && treeNode==y.getRight()){ treeNode = y; y = y.getParent(); } return y; } /** * 找一個節點的前驅 * @return 一個節點的前驅 */ public static TreeNode<Integer> treePredecessor(TreeNode<Integer> treeNode){ if(treeNode.getLeft()!=null){ return treeMaximum(treeNode.getLeft()); } TreeNode<Integer> y = treeNode.getParent(); while (y!=null && treeNode==y.getLeft()){ treeNode = y; y = y.getParent(); } return y; } public static void transplant(TreeNode<Integer> root,TreeNode<Integer> target,TreeNode<Integer> source){ if(target.getParent()==null){ root.setValue(source.getValue()); root.setLeft(source.getLeft()); root.setRight(source.getRight()); root.setParent(source.getParent()); }else if(target == target.getParent().getLeft()){ target.getParent().setLeft(source); }else { target.getParent().setRight(source); } source.setParent(target.getParent()); } /** * 從一棵樹中刪除一個節點 * @param root 根節點 * @param delete 要刪除的節點 */ public void treeDelete(TreeNode<Integer> root ,TreeNode<Integer> delete){ if(delete.getLeft()==null){ transplant(root,delete,delete.getRight()); }else if(delete.getRight()==null){ transplant(root,delete,delete.getLeft()); }else { TreeNode<Integer> y = treeMinimum(delete.getRight()); if(y.getParent()!=delete){ transplant(root,y,y.getRight()); y.setRight(delete.getRight()); y.getRight().setParent(y); } transplant(root,delete,y); y.setLeft(delete.getLeft()); y.getLeft().setParent(y); } } }