[英]Deleting an node in Binary search tree
这不是家庭作业。 我对此完全被封锁。 我知道该怎么办,但操作树时遇到困难。
似乎以下代码适用于叶节点,但不适用于其他情况。 以下代码进行编译。 请帮忙。
package com.binarytree;
import com.binarytree.Node;
public class BinaryTree1 {
private Node root;
private Node parent;
public BinaryTree1(){
root = null;
}
public Node getRoot() {
return root;
}
public void setRoot(Node root) {
this.root = root;
}
public Node insert(int data){
return insert(root, data);
}
private Node insert(Node node, int data){
if( node == null ) {
node = new Node(data);
}
else{
if (data <= node.data){
node.left = insert(node.left, data);
}
else{
node.right = insert(node.right, data);
}
}
return node;
}
public void printTree(Node node){
if( node == null) return;
//System.out.println( "left: " + (node.left != null ? node.left.data : null) );
printTree(node.left);
System.out.print(node.data + " ");
//System.out.println( "right: " + (node.right != null ? node.right.data : null) );
printTree(node.right);
}
/**
* case 0: no children - leaf node - delete the parent link
* case 1: 1 child - make the parent to point to the node child and delete
* case 2: find min from right sub tree, copy value in targetted node and delete duplicate node
* (OR)
* find max from left sub tree, copy value in targetted node and delete duplicate node
* @param root
* @param data
*/
public Node deleteNode(Node myroot, int data){
if( myroot == null) return null;
else if( data < myroot.data ){ //left sub tree
myroot.left = deleteNode(myroot.left, data);
}
else if (data > myroot.data){
myroot.right = deleteNode(myroot.right, data);
}
else{ //found the node
//no child
if( myroot.left == null && myroot.right == null ){
myroot = null;
parent = myroot;
}
else if( myroot.left == null && myroot.right != null){
parent.right = myroot.right;
myroot = null;
}
else if (myroot.left != null && myroot.right == null){
parent.left = myroot.right;
myroot = null;
} //2 children
else{
Node temp = myroot.right;
myroot.data = temp.data;
myroot.right = myroot.right.right;
}
}
parent = myroot;
return parent;
}
}
package com.binarytree;
public class RunBinaryTree1 {
public static void main(String[] args){
BinaryTree1 bt = new BinaryTree1();
bt.setRoot(bt.insert(5));
bt.setRoot(bt.insert(3));
bt.setRoot(bt.insert(4));
bt.setRoot(bt.insert(1));
bt.setRoot(bt.insert(6));
bt.setRoot(bt.insert(9));
// bt.setRoot(bt.insert(2));
System.out.print("Nodes in the BST (In order) are: "); bt.printTree(bt.getRoot());
System.out.println("");
System.out.print("Nodes in the BST (In order) are: "); bt.printTree(bt.deleteNode(bt.getRoot(), 1));
bt.setRoot(bt.insert(1));
//DOES NOT WORK
System.out.print("Nodes in the BST (In order) are: "); bt.printTree(bt.deleteNode(bt.getRoot(), 6));
}
}
package com.binarytree;
public class Node {
Node left;
Node right;
int data;
public Node(int data){
this.data = data;
this.left = null;
this.right = null;
}
}
从平衡树中删除节点时,需要注意三种可能,搜索树通常是这种情况。 如果您的树木不适合自我平衡,请忽略讨论它的内容。 即使它们是自我平衡的,该特定方面也是复杂的,可能值得提出不同的问题。
还请记住,下面的示例树实际上并未达到平衡,它们仅用于显示操作。
首先,如果您的节点是叶子。 在这种情况下,这很容易。 您只需删除节点。 然后,过渡变成删除D:
B B
/ \ / \
A C ==> A C
\
D
如果在这种情况下使用平衡树,请在删除的节点的父节点(C)上开始平衡,然后从该节点开始逐步向上平衡。
第二种情况,它有一个孩子。 在这种情况下,您只需“抚养”那个孩子,指针和其他所有东西。 例如,在下面删除C:
B B
/ \ / \
A C ==> A D
\ \
D E
\
E
如果树是自平衡的,则将从上移到的节点开始,在这种情况下为D。
第三种情况有些棘手,因为您要删除的节点有两个子节点,因此您既不能删除它也不能调出子节点。
在这种情况下,您要做的是将该节点中的数据与其前身的数据交换,这保证是叶节点或仅具有左子节点的节点。
然后,您可以简单地恢复到上述情况1或2,并删除先前节点(现在包含要删除的数据)并根据需要使用适当的规则进行重新平衡。
假设您要从以下内容中删除F,首先将F与它的前身E交换,然后删除F(在这种情况下是从叶节点开始,因此使用上面的情况1):
B B B
/ \ / \ / \
A F ==> A E ==> A E
/ \ / \ / \
D G D G D G
/ \ \ / \ \ / \
C E H C F H C H
(swap EF) (del F)
这样做的原因与在列表中的原因相同:
Index: 12345678
ABCDEFGH
如果要从该列表中删除F但第六位置受到某种保护,则可以在索引5和6处交换数据:
Index: 12345678
ABCDFEGH
然后删除索引5处的数据:
Index: 1234567
ABCDEGH
找到一个节点(具有两个子节点)的直接前辈的方法是转到其左子节点,然后继续向右移动,直到右子节点为NULL,伪代码如下:
def predecessor(n):
pre = n.left
while pre.right != null:
pre = pre.right
return pre
这是可行的。 那为所有帮助。
public class RunBinaryTreeForDeleteNode {
public static void main(String[] args){
BinaryTreeDeleteNode bt = new BinaryTreeDeleteNode();
bt.setRoot(bt.insert(5));
bt.setRoot(bt.insert(3));
bt.setRoot(bt.insert(4));
bt.setRoot(bt.insert(1));
bt.setRoot(bt.insert(6));
bt.setRoot(bt.insert(9));
// bt.setRoot(bt.insert(2));
//start of Testing deletion of nodes.
System.out.print("Nodes in the BST (In order) are: "); bt.printTree(bt.getRoot());
System.out.println("");
System.out.print("Nodes in the BST (In order) are: "); bt.printTree(bt.deleteNode(bt.getRoot(), 1));
bt.setRoot(bt.insert(1));
System.out.println("");
System.out.print("Nodes in the BST (In order) are: "); bt.printTree(bt.deleteNode(bt.getRoot(), 6));
bt.setRoot(bt.insert(6));
System.out.println("");
System.out.print("Nodes in the BST (In order) are: "); bt.printTree(bt.deleteNode(bt.getRoot(), 3));
bt.setRoot(bt.insert(3));
System.out.println("");
//BELOW CODE CORRUPTS THE TREE
System.out.print("Nodes in the BST (In order) are: "); bt.printTree(bt.deleteNode(bt.getRoot(), 5));
//bt.setRoot(bt.insert(5));
System.out.println("");
// System.out.print("Nodes in the BST (In order) are: "); bt.printTree(bt.getRoot());
//System.out.println("");
//end of Testing deletion of nodes.
}
}
public class Node {
Node left;
Node right;
int data;
public Node(int data){
this.data = data;
this.left = null;
this.right = null;
}
}
public class BinaryTreeDeleteNode {
private Node root;
public BinaryTreeDeleteNode(){
root = null;
}
public Node getRoot() {
return root;
}
public void setRoot(Node root) {
this.root = root;
}
public Node insert(int data){
return insert(root, data);
}
private Node insert(Node node, int data){
if( node == null ) {
node = new Node(data);
}
else{
if (data <= node.data){
node.left = insert(node.left, data);
}
else{
node.right = insert(node.right, data);
}
}
return node;
}
public void printTree(Node node){
if( node == null) return;
//System.out.println( "left: " + (node.left != null ? node.left.data : null) );
printTree(node.left);
System.out.print(node.data + " ");
//System.out.println( "right: " + (node.right != null ? node.right.data : null) );
printTree(node.right);
}
/**
* case 0: no children - leaf Node - delete the parent link
* case 1: 1 child - make the parent to point to the Node child and delete
* case 2: find min from right sub tree, copy value in targetted Node and delete duplicate Node
* (OR)
* find max from left sub tree, copy value in targetted BST Node and delete duplicate Node
* @param root
* @param data
*/
public Node deleteNode(Node myNode, int data) {
if( myNode == null) return null;
Node p, p2;
if (data < myNode.data)
{
myNode.left = deleteNode(myNode.left, data);
}
else if( data > myNode.data)
{
myNode.right = deleteNode(myNode.right, data);
}
else
{
if (myNode.left == null && myNode.right == null){ //leaf node
return null;
}
else if (myNode.left == null) //one child
{
return myNode.right;
}
else if (myNode.right == null) //one child
{
return myNode.left;
}
else //2 children
{
p2 = myNode.right;
p = myNode.right;
while (p.left != null){
p = p.left;
}
p.left = myNode.left;
return p2;
}
}
return myNode;
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.