关于二叉搜索树的删除操作,先弄清如何找到前驱节点和后继节点
•前驱节点:中序遍历时的前一个节点•如果左子树存在,从该节点的左子节点的最右的节点。•如果左子树 == null && 父节点!= null 父节点为父节点遍历,一直到节点关系发生改变。如下图所示。•如果左子树 == null && 父节点== null ,没有前驱节点。
public Node<E> findPredecessorNode(E element) { return findPredecessorNode(node(element)); } private Node<E> findPredecessorNode(Node<E> element) { if (element.left != null) { Node<E> node = element.left; while (node.right!= null) { node = node.right; } return node; } while (element.parent != null && element == element.parent.left) { element = element.parent; } return element.parent; }
•前驱节点:中序遍历时的后一个节点•如果右子树存在,从该节点的左子节点的最左的节点。•如果右子树 == null && 父节点!= null 父节点为父节点遍历,一直到节点关系发生改变。•如果右子树 == null && 父节点== null ,没有后继节点。
•直接删除
•用子节点替换既可
•找到前驱或者后继节点的值,并替换原节点。•他的前驱、后继节点的度只可能是0或者是1。
private void remove(Node<E> node) { if (node == null) return; size--; // 度为2的节点 if (node.twoChildren()) { // 找到后继节点 Node<E> s = findSucceessorNode(node); // 用后继节点的值覆盖原节点的值 node.element = s.element; node = s; } // 删除的node节点 (node的度必然是1或者0) 如果是0 replacement为null Node<E> replacement = node.left != null ? node.left : node.right; // 度为1 if (replacement != null) { // 更改parent replacement.parent = node.parent; // 更改parent的 chil if (node.parent == null) { // node是度为1的节点并且是根节点 root = replacement; } else if (node == node.parent.left) { node.parent.left = replacement; } else { // node == node.parent.right node.parent.right = replacement; } } else if (node.parent == null) { // node是叶子节点并且是根节点 root = null; } else { // node是叶子节点 if (node == node.parent.left) { node.parent.left = null; } else { node.parent.right = null; } } }
•中序遍历+ 前/后序遍历 •可以确定一颗唯一二叉树•前序遍历+ 后序遍历•如果他是一颗真二叉树(Proper Binary Tree) ,结果是唯一的。•其他情况 不唯一。
List<Integer> perorder = Arrays.asList(5,1,2,4,3,9); List<Integer> inorder = Arrays.asList(2,1,4,5,9,3); private Node<E> RefactoringTree(List<E> perorderList, List<E> inorderList) { if (perorderList.size() == 0|| inorderList.size() == 0) { return null; } E element = perorderList.get(0); Node<E> root = new Node<>(element, null); perorderList = perorderList.subList(1, perorderList.size()); int index = inorderList.indexOf(element); List<E> leftInorderList = inorderList.subList(0, index); List<E> rightInorderList = inorderList.subList(index + 1, inorderList.size()); List<E> leftperOrderList = perorderList.subList(0, leftInorderList.size()); List<E> rightperOrderList = perorderList.subList(leftperOrderList.size(), perorderList.size()); root.left = RefactoringTree(leftperOrderList, leftInorderList); root.right = RefactoringTree(rightperOrderList, rightInorderList); return root; }
本文分享自微信公众号 - 老沙课堂(gh_f73a6b772d4f),作者:沙睿
原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。
原始发表时间:2019-10-12
本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。
我来说两句