如何在二叉樹中刪除具有2個子節點的節點?如何在二叉搜索樹中刪除具有2個子節點的節點?
是否有任何一種方法將其刪除?我GOOGLE了它。但沒有清楚的想法。有人用圖解表示來解釋它嗎?
How to delete the node '5' from the this image and what might be the outcome?
如何在二叉樹中刪除具有2個子節點的節點?如何在二叉搜索樹中刪除具有2個子節點的節點?
是否有任何一種方法將其刪除?我GOOGLE了它。但沒有清楚的想法。有人用圖解表示來解釋它嗎?
How to delete the node '5' from the this image and what might be the outcome?
替換表示,與在其右側最左邊的孩子,或在其左側最右邊的子節點。然後,您將該孩子從其被替換的底部刪除。
刪除五可能會產生一棵以3爲根或18作爲其根的樹,具體取決於您採取的方向。
它看起來就像你從這個網站圖片:http://www.algolist.net/Data_structures/Binary_search_tree/Removal
它顯示你想要的圖像太算法。
維基百科的文章給出了BST的一個很好的說明:
http://en.wikipedia.org/wiki/Binary_search_tree
當你刪除一個節點有2個孩子,5個在你的情況,你可以從右子樹替換最小值節點刪除節點,或來自左側子樹的最大值節點。
對具有2個子節點的節點的簡單刪除是將刪除節點的父節點的子節點與其後繼節點重新標記。
您不能使用右子樹的最左邊的節點。假設你有一棵樹,右子樹的最左邊的節點是15,但是15的父親也是15,所以用右子樹上最左邊的節點代替要刪除的節點可以給你一個等於值在右邊的子樹中。在我的示例中,15將成爲該子樹的新根,然後在根的右側會出現另一個15。
一個簡單而方便的解決方案:
Node* findMaxNode(Node* root)
{
if(root->right == NULL) return root;
findMaxNode(root->right);
}
Node* DeleteNodeInBST(Node* root,int data)
{
//base case when not found or found then recursion breaks
if(root == NULL) return root;
else if(root->data > data) root->left = DeleteNodeInBST(root->left, data);
else if(root->data < data) root->right = DeleteNodeInBST(root->right, data);
else
{
//when the node to be deleted is found
//Four possibilities
//case1: When the node to be deleted has no children
if(root->left == NULL && root->right == NULL)
{
delete root;
root = NULL;
}
//case2: When the node to be deleted has ONLY LEFT child
else if(root->right == NULL)
{
Node* temp = root;
root = root->left;
delete temp;
}
//case3: When the node to be deleted has ONLY RIGHT child
else if(root->left == NULL)
{
Node* temp = root;
root = root->right;
delete temp;
}
//case4: When the node to be deleted has TWO children
else
{
Node* maxNode = findMaxNode(root->left);//finding the maximum in LEFT sub-tree
root->data = maxNode->data; //Overwriting the root node with MAX-LEFT
root->left = DeleteNodeInBST(root->left, maxNode->data);//deleted the MAX-LEFT node
}
return root;
}
}
用於刪除一個節點有三種可能的情形..
知道缺失的概念之前,我們應該瞭解的繼任者的觀念和前輩
繼承人的繼承(或前身)被刪除:在二進制樹的後繼節點是樹的最小節點,該節點嚴格大於此節點。
有兩種可能的情況下,以節點
一個節點有正確的兒童:在這種情況下,右子樹的最左邊的孩子將是繼任者。
節點沒有子節點:轉到父節點並查找此節點是其左子樹的一部分的節點。現在刪除邏輯
public Node sucessor(Node node) {
Node sucessor = null;
if (node.getRightNode() != null) {
Node newNode = node.getRightNode();
while (newNode != null) {
sucessor = newNode;
newNode = newNode.getLeftNode();
}
} else {
sucessor = findRightParent(node);
}
return sucessor;
}
private Node findRightParent(Node node) {
Node newNode = null;
if (node.getParentNode() != null) {
if (node.getParentNode().getLeftNode() == node) {
newNode = node.getParentNode();
} else {
newNode = findRightParent(node.getParentNode());
}
}
return newNode;
}
public void deleteNode(Node node) {
// Node is a leaf node //
if(node.getLeftNode() == null && node.getRightNode() == null){
if(isRightNode(node.getParentNode(), node)){
node.getParentNode().setRightNode(null);
}else{
node.getParentNode().setLeftNode(null);
}
// Only left child is there//
}else if(node.getLeftNode() != null && node.getRightNode() == null){
if(isRightNode(node.getParentNode(), node)){
node.getParentNode().setRightNode(node.getLeftNode());
}else{
node.getParentNode().setLeftNode(node.getLeftNode());
}
// Only Right child is there //
}else if(node.getLeftNode() == null && node.getRightNode() != null){
if(isRightNode(node.getParentNode(), node)){
node.getParentNode().setRightNode(node.getRightNode());
}else{
node.getParentNode().setLeftNode(node.getRightNode());
}
// Both Left and Right children are their//
}else{
Node psNode = predessor(node);
deleteNode(psNode);
psNode.setParentNode(node.getParentNode());
psNode.setLeftNode(node.getLeftNode());
psNode.setRightNode(node.getRightNode());
if(isRightNode(node.getParentNode(), node)){
node.getParentNode().setRightNode(psNode);
}else{
node.getParentNode().setLeftNode(psNode);
}
}
}
溶液從http://coder2design.com/binary-tree/
採取此外,他們已解釋遍歷和插入的完整的源代碼的流動。
upvote for'Successor'的定義 –
算法:
->Find the node which need to delete (assume data is given)
->Find the deepest node of tree
->Replace deepest node's data with the node to be deleted
->Delete the deepest node
Java實現:
public static void deleteTheNode(BTNode root, int data) {
BTNode nodeToDelete = findTheNode(root, data);
if (nodeToDelete == null) {
System.out.println("Node Does not exists in Binary Tree");
return;
}
BTNode deepestNode = findDepestNodeOfBinaryTree(root);
nodeToDelete.setData(deepestNode.getData());
_deleteTheNode(root, deepestNode);
}
private static void _deleteTheNode(BTNode root, BTNode node) {
Queue<BTNode> q = new LinkedList<>();
q.offer(root);
while (!q.isEmpty()) {
BTNode temp = q.poll();
if (temp.getLeft() == node) {
temp.setLeft(null);
node = null;
break;
} else if (temp.getRight() == node) {
temp.setRight(null);
node = null;
break;
}
if (temp.getLeft() != null) {
q.offer(temp.getLeft());
}
if (temp.getRight() != null) {
q.offer(temp.getRight());
}
}
}
//Find the deepest nodeof the binary tree
public static BTNode findDepestNodeOfBinaryTree(BTNode root) {
int depth = 0;
BTNode deepetNode = root;
Stack<BTNode> nodes = new Stack<>();
Stack<BTNode> path = new Stack<>();
if (root == null) {
return null;
}
nodes.push(root);
while (!nodes.empty()) {
BTNode node = nodes.peek();
if (!path.empty() && node == path.peek()) {
if (path.size() > depth) {
depth = path.size() - 1;
deepetNode = node;
}
path.pop();
nodes.pop();
} else {
path.push(node);
if (node.getRight() != null) {
nodes.push(node.getRight());
}
if (node.getLeft() != null) {
nodes.push(node.getLeft());
}
}
}
return deepetNode;
}
查找節點的序後繼被刪除。然後複製該節點的中間繼承者的內容並刪除中繼者。 (您也可以使用inorder而不是inorder後繼)
該程序可以工作,但使用不同的方法。有人可以說,爲什麼我被拒絕了嗎? –