關於二叉搜索樹的刪除操做,先弄清如何找到前驅節點和後繼節點java
前驅節點:中序遍歷時的前一個節點node
若是左子樹存在,從該節點的左子節點的最右的節點。spa
若是左子樹 == null && 父節點!= null 父節點爲父節點遍歷,一直到節點關係發生改變。以下圖所示。3d
若是左子樹 == null && 父節點== null ,沒有前驅節點。code
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;
}
複製代碼
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;
}
}
}
複製代碼
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;
}
複製代碼
喜歡的能夠關注下個人公衆號,會在第一時間更新cdn