/** * 二叉搜索树(算法导论) * 实现 遍历、查询、新增、删除、最大值查找、最小值查找、获取后继节点 */ public class SearchBinaryTree { /** * 中序遍历所有节点 * 伪代码: * INORDER-TREE-WALK(x) * if(x != NIL) * INORDER-TREE-WALK(x.left) * print x.key * INORDER-TREE-WALK(x.right) */ public static void inPrint( TreeNode root){ if(root !=null){ inPrint(root.left); System.out.println(root.val); inPrint(root.right); } } /** * 输入二叉搜索树的根节点root 和需要查询的关键字key,查找key对应的节点 * 伪代码(递归实现): * TREE-SEARCH(X,K) * if x == NIL or k ==x.key * return x * if k<x.key * return TREE-SEARCH(X.left,K) * else return TREE-SEARCH(X.right,K) * @param root 根节点 * @param key 关键字 * @return */ public static TreeNode searchByRecursion( TreeNode root, int key){ if(root == null || key == root.val){ return root; } if(key <root.val) { return search(root.left, key); }else{ return search(root.right, key); } } /** * 输入二叉搜索树的根节点root 和需要查询的关键字key,查找key对应的节点 * 伪代码(非递归实现): * ITERATIVE-TREE-SEARCH(X,K) * while x != NIL and k !=x.key * if k < x.key * x = x.left * else x = x.right * return x * @param root 根节点 * @param key 关键字 * @return */ public static TreeNode search( TreeNode root, int key){ while (root != null && key != root.val){ if(key <root.val) { root = root.left; }else{ root = root.right; } } return root; } /** * 查找最小值(二次搜索树最小值为最左节点) * 伪代码: * TREE-MINNUM(X) * while x.left != NIL * X = x.left * return x * @param root * @return */ public static TreeNode getMin(TreeNode root){ while (root.left!=null){ root = root.left; } return root; } /** * 查找最大值(二次搜索树最大值为最右节点) * 伪代码: * TREE-MAXNUM(X) * while x.right != NIL * X = x.right * return x * @param root * @return */ public static TreeNode getMax(TreeNode root){ while (root.right!=null){ root = root.right; } return root; } /** * 获取后继节点 * 伪代码: * TREE-SUCCESSOR(x) * if x.right != NIL * return TREE-SUCCESSOR(x.right) * y = x.p * while y!=NIL and x == y.right * x = y * y = y.p * return y * @param node * @return */ public static TreeNode getNext (TreeNode node){ TreeNode next = null; if(node.right != null){ return getNext(node.right); } next = node.p; while (next != null && node==next.right){ node = next; next = next.p; } return next; } /** * 将一个新值插入到二叉树中 * 伪代码: * TREE-INSERT(T,z) * y = NIL * x = T.root * while x != NIL * y = x * if z.key < x.key * x = x.left * else x = x.right * z.p = y * if y == NIL * T.root = z * elseif z.key < y.key * y.left = z * else y.right = z * 代码逻辑: * 先找到需要挂载的节点 * 再判断挂哪边 * @param root 根节点 * @param val 需要插入的值 * @return */ public static void insert (TreeNode root, int val){ TreeNode insertNode= new TreeNode(val); if(root == null) { return; } TreeNode node = root; TreeNode temp = null; while ( node != null ){ temp = node; if(val < node.val){ node = node.left; }else { node = node.right; } } insertNode.p = temp; //挂载父节点 if(val<temp.val){ temp.left = insertNode; } else { temp.right = insertNode; } } /** * 删除一个节点,删除成功返回true,删除失败返回false * 伪代码: * TREE-DELETE(T,z) * if z.left == NIL * TRANSPLANT(T,z,z.right) * elseif z.right == NIL * ss(T,z,z.left) * else y = TREE-MINIMUN(z.right) * if y.p != z * TRANSPLANT(T,y,y.right) * y.right = z.right * y.right.p = y * TRANSPLANT(T,z,y) * y.left = z.left * y.left.p = y * 代码逻辑: * 1.如果z没有子节点,直接删除 * 2.如果z只有一个子节点,子节点直接替换z * 3.如果有两个子节点,那么找z的后继y(一定在右子树中),并让y占据z在树中的位置。z的左、右子树挂载到y上 * 4.如果z没有左孩子,用右孩子替换z * 5.如果z仅有一个左孩子,左孩子直接替换z * @param root * @param node * @return */ public static void delete (TreeNode root, TreeNode node){ TreeNode temp = null; if(node.left == null){ tranSplant(root,node,node.right); }else if (node.right == null){ tranSplant(root,node,node.left); }else { temp = getMin(node.right); if(temp.p!=node){ tranSplant(root,temp,temp.right); temp.right = node.right; temp.right.p = temp; } tranSplant(root,node,temp); temp.left = node.left; temp.left.p = temp; } node = null; } /*** * 移动子树 * TRANSPLANT(T,u,v) * if u.p == NIL * T.root = v * elseif u == u.p.left * u.p.left = v * else u.p.right = v * if v!= NIL * v.p = u.p * @param root * @param u * @param v */ private static void tranSplant(TreeNode root,TreeNode u,TreeNode v){ if(u.p == null){ root = v; }else if (u==u.p.left){ u.p.left = v; }else { u.p.right = v; } if(v != null){ v.p = u.p; } } }
二叉搜索树
最新推荐文章于 2024-07-10 21:37:49 发布