(기준은 "당신의"반복 버전은 물론 당신은 아담 드로즈 덱의를 의미한다.)
이 작동합니다 : node
가 null의 경우
public void delete(T info) {
root = delete (root.info);
}
public TreeNode<T> delete(TreeNode<T> node, T info) {
// if this node is null, we have reached the end of the tree
// so the node is not in the tree.
if (node == null) {
return node; // or handle as required
// if this is not the node to delete;
// recursively call this on the node's correct child
else if (info.compareTo(node.info) <0) {
node.left = delete(node.left, info);
return node;
} else {
node.right = delete(node.right, info);
return node;
}
// if this is the node to delete:
else if (node.info.equals(info)) {
// to delete it, we must return a sub-tree without it.
if (node.left == null)
// this node is a leaf node, or
// node.right contains only child.
// either way, return node.right
return node.right;
if (node.right == null)
// node.left contains only child
return node.left;
// else node has 2 children, so delete by merging:
// first, find its direct predecessor:
TreeNode<T> tmp = node.left;
while (tmp.right != null)
tmp = tmp.right;
// then append the node's right sub-tree
// to its direct predecessor:
tmp.right = node.right;
// lastly, replace the node by its left sub-tree:
return node.left;
}
}
먼저 우리는 확인한다. 그것이 존재한다면, 그것은 우리가 삭제할 요소가 트리에 없다는 것을 의미합니다. 왜냐하면 우리는 그것이있을 수있는 모든 노드를 다 쓸 때까지 통과했기 때문입니다.
다음으로 요소가 현재 노드의 요소보다 크거나 큰지 확인합니다. 그렇다면 요소를 비교하는 방법에 따라 왼쪽 또는 오른쪽으로 이동하여 트리를 계속 탐색해야합니다. 재귀 적 단계에서는 삭제 작업의 결과를 node
의 자식 중 하나에 할당합니다. 우리는 root
에서 삭제 작업의 결과가 할당 된 root
인 첫 번째 함수에서이 큐를 가져 왔습니다. 이 노드는 삭제하려는 노드를 나타내는 node
이 나타날 때까지 반복적으로 트리를 통과합니다. 여기서도 node
을 반환하므로 변경 사항이 발생하지 않은 경우 node.right = delete(node.right, info)
을 호출해도 현재 노드가 변경되지 않습니다.
노드를 찾으면 노드가 리프 노드 (자식이 없음)이거나 왼쪽 또는 오른쪽 자식이 1 개이거나 자식이 두 개있을 수 있습니다. 처음 3 개 시나리오 node
에 아이가없는 경우는 (널) node
의 권리 아이가 반환됩니다, 그래서 첫 번째 if
검사 노드를 삭제, 사실 일 것이다
if (node.left == null)
return node.right;
if (node.right == null)
return node.left;
주 라인이 적용됩니다 .
null을 반환하는 이유는 노드를 삭제하는 이유는 무엇입니까? 위에 설명 된 탐색 단계에서 우리는 삭제 작업의 결과를 node
의 자식에게 할당하기 때문에. 이전 재귀 단계의 node
은이 단계에서 node
의 부모입니다. delete가 해당 노드의 하위 노드에서 반복적으로 호출 되었기 때문입니다. 여기서 null을 반환하면 이전 호출에서 부모의 자식에 null을 할당하여 자식을 삭제합니다. 기본적으로 node
이 아닌 다른 값을 반환 할 때마다 트리에서 반환하는 값으로 현재 노드를 교체합니다.
네 번째 경우에는 병합을 통해 간단한 삭제가 필요합니다. 왼쪽 하위 트리의 가장 오른쪽 노드에 node
의 오른쪽 하위 트리를 추가하여이 작업을 수행 할 수 있습니다.
TreeNode<T> tmp = node.left;
while (tmp.right != null)
tmp = tmp.right;
그래서 tmp
지금 node
의 직접적인 전신 : 첫째, 우리는 node
의 직접적인 전신 왼쪽 서브 트리에서 가장 오른쪽 노드를 찾을 수 있습니다.다음으로 우리가 tmp
에 node
의 바로 하위 트리를 래치 : 그것의 왼쪽 서브 트리로 node
을 대체 할 마지막
tmp.right = node.right;
와,이 node
의 자식으로 node.left
와 node
을 대체하기 때문에, 우리는 단순히, node.left
을 반환 이전 재귀 호출의 부모.
제 설명이 혼란 스럽다면 this one을 사용해보십시오. 이것은 종이 위에 그림으로 설명하기가 훨씬 쉽습니다. 그래서 실용적인 세션 (네, 저는이 prac을 세웠습니다)보다는 나에게 물어봐야 할 것입니다. 마감일 전에 알아 냈 으면합니다!