JAVA AVL删除,如何使用现有的旋转代码实现?
已经三天了,我仍然无法修复我的问题,我的问题是我的删除代码并不是每次删除都能完美工作。我从D.S.Malik的书中得到了这段代码,书名为“Java中的数据结构”。我想执行删除操作,但在大多数情况下,当我使用现有的旋转代码时,删除操作失败,完整的程序如下所示:JAVA AVL删除,如何使用现有的旋转代码实现?,java,algorithm,data-structures,Java,Algorithm,Data Structures,已经三天了,我仍然无法修复我的问题,我的问题是我的删除代码并不是每次删除都能完美工作。我从D.S.Malik的书中得到了这段代码,书名为“Java中的数据结构”。我想执行删除操作,但在大多数情况下,当我使用现有的旋转代码时,删除操作失败,完整的程序如下所示: public class AVL { protected class AVLNode { public int info; public int bfactor; public AVLNode llink;
public class AVL
{
protected class AVLNode
{
public int info;
public int bfactor;
public AVLNode llink;
public AVLNode rlink;
}
protected AVLNode root;
protected bool isTaller;
private bool isDuplicate = false;
private AVLNode rotateToLeft(AVLNode root)
{
AVLNode p; //reference variable to the root of the right subtree of root
if (root == null)
throw new Exception("Error in the tree.");
else if (root.rlink == null)
throw new Exception("Error in the tree: No right subtree to rotate.");
else
{
p = root.rlink;
root.rlink = p.llink; //the left subtree of p becomes the right subtree of root
p.llink = root;
root = p; //make p the new root node
}
return root;
}
private AVLNode rotateToRight(AVLNode root)
{
AVLNode p; //reference variable to the root of the left subtree of root
if (root == null)
throw new Exception("Error in the tree.");
else if (root.llink == null)
throw new Exception("Error in the tree: No left subtree to rotate.");
else
{
p = root.llink;
root.llink = p.rlink; //the right subtree of p becomes the left subtree of root
p.rlink = root;
root = p; //make p the new root node
}
return root;
}
private AVLNode balanceFromLeft(AVLNode root)
{
AVLNode p;
AVLNode w;
p = root.llink; //p points to the left subtree of root
switch (p.bfactor)
{
case -1:
root.bfactor = 0;
p.bfactor = 0;
root = rotateToRight(root);
break;
case 0:
throw new Exception("Error: Cannot balance from the left.");
case 1:
w = p.rlink;
if (w.bfactor == -1)
{
root.bfactor = 1;
p.bfactor = 0;
}
else if (w.bfactor == 0)
{
root.bfactor = 0;
p.bfactor = 0;
}
else if (w.bfactor == 1)
{
root.bfactor = 0;
p.bfactor = -1;
}
w.bfactor = 0;
p = rotateToLeft(p);
root.llink = p;
root = rotateToRight(root);
break;
}
return root;
}
private AVLNode balanceFromRight(AVLNode root)
{
AVLNode p;
AVLNode w;
p = root.rlink; //p points to the right subtree of root
switch (p.bfactor)
{
case -1:
w = p.llink;
if (w.bfactor == -1)
{
root.bfactor = 0;
p.bfactor = 1;
}
else if (w.bfactor == 0)
{
root.bfactor = 0;
p.bfactor = 0;
}
else if (w.bfactor == 1)
{
root.bfactor = -1;
p.bfactor = 0;
}
w.bfactor = 0;
p = rotateToRight(p);
root.rlink = p;
root = rotateToLeft(root);
break;
case 0:
throw new Exception("Error: Cannot balance from the right.");
case 1:
root.bfactor = 0;
p.bfactor = 0;
root = rotateToLeft(root);
break;
}
return root;
}
private AVLNode insertIntoAVL(AVLNode root, AVLNode newNode)
{
if (root == null)
{
root = newNode;
isTaller = true;
}
else if (root.info == newNode.info)
isDuplicate = true;
//throw new Exception("No duplicates are allowed.");
else if (root.info > newNode.info) //newNode goes in the left subtree
{
root.llink = insertIntoAVL(root.llink, newNode);
if (isTaller) //after insertion, the subtree grew in height
switch (root.bfactor)
{
case -1: root = balanceFromLeft(root);
isTaller = false;
break;
case 0: root.bfactor = -1;
isTaller = true;
break;
case 1: root.bfactor = 0;
isTaller = false;
break;
}
}
else
{
root.rlink = insertIntoAVL(root.rlink, newNode);
if (isTaller) //after insertion, the subtree grew in height
switch (root.bfactor)
{
case -1: root.bfactor = 0;
isTaller = false;
break;
case 0: root.bfactor = 1;
isTaller = true;
break;
case 1: root = balanceFromRight(root);
isTaller = false;
break;
}
}
return root;
}
}
从这本书中,我遵循了创建delete方法的所有说明,但正如我所说的,它失败了
编辑:好的,这是我的delete方法,但实际上它是用C#编码的。请原谅我对未知方法的额外调用,因为我目前正在用C#开发一个AVL动画应用程序,但无论如何我已经删除了这些方法,但是如果你看到一些不相关的方法调用,请忽略它
public Node deleteFromAVL(Node parent, Node delNode)
{
if (parent == null) //not found
{
MessageBox.Show("Item not found.");
isShorter = false;
}
else if (parent.value.Equals(delNode.value)) //found
{
//the four cases of deletion
#region FOUR CASES OF DELETION
if (parent.left == null && parent.right == null) //leaf node
{
isShorter = true;
return null;
}
else if (parent.left == null)
{
isShorter = true;
tempNode = parent.right;
return tempNode;
}
else if (parent.right == null)
{
isShorter = true;
tempNode = parent.left;
return tempNode;
}
else
{
current = parent.left;
trailCurrent = null;
while (current.right != null)
{
trailCurrent = current;
current = current.right;
}
parent.value = current.value;
if (trailCurrent == null)
{
parent.left = current.left; //movement
if (parent.left != null)
{
parent.left.moveToParent(); //move to parent
}
}
else
{
trailCurrent.right = current.left; //movement
if (trailCurrent.right != null)
{
trailCurrent.right.parent = trailCurrent;
}
}
isShorter = true;
}
#endregion
}
else if (parent.value > delNode.value) // search left
{
parent.left = deleteFromAVL(parent.left, delNode);
//change balance factors
if (isShorter)
{
switch (parent.bfactor)
{
case -1: parent.bfactor = 0;
isShorter = true;
break;
case 0: parent.bfactor = 1;
isShorter = false;
break;
case 1: parent = balanceFromRight(parent);
isShorter = false;
break;
}
}
}
else//search right
{
parent.right = deleteFromAVL(parent.right, delNode);
//change balance factors
if (isShorter)
{
switch (parent.bfactor)
{
case -1: parent = balanceFromLeft(parent);
isShorter = false;
break;
case 0: parent.bfactor = -1;
isShorter = false;
break;
case 1: parent.bfactor = 0;
isShorter = true;
break;
}
}
}
return parent;
}
我将向您展示我的节点删除实现
private AVLNode<T> Remove(AVLNode<T> T, int x)
{
if(T == null){ //if the value does not exist just return null
return null;
}
if(x < T.item)//if the value is less than item
{
if(T.left == null)//if T.left = null return null x doesnt exist
{
return null;
}
else
{
T.left = Remove(T.left, x); //T.left exists recursive call Remove with T.left
T.height = Math.max(Height(T.left), Height(T.right))+1;//reset height
if(HeightCheck(T.right) - HeightCheck(T.left) == 2){ //check for imbalance
if(T.right.left.height > T.right.right.height){ //if the height of the subtree is imbalance
return T = DoubleRotateWithRightChild(T); //if after delete the right->left > right->right double rotate
}
else{
return T = SingleRotateWithRightChild(T); //if after delete right->left < right->right single rotate
}
}
}
}
else
{
if(x > T.item){ //if X > item
if(T.right == null)\
{ //having an issue dealing with null pointers being passed so deal with it here
return null; //if T.right == null return null
}
else
{
T.right = Remove(T.right, x); //if T.right exists recursive call remove with T.right
T.height = Math.max(Height(T.left), Height(T.right))+1; //rest height
if(HeightCheck(T.left) - HeightCheck(T.right) == 2)
{ //check for imbalace
if(T.left.left.height > T.left.right.height)
{
return T = DoubleRotateWithLeftChild(T); //if after delete left->left height > left->right height double rotate
}
else
{
return T = SingleRotateWithLeftChild(T); // if after delete left->left height < left->right height single rotate
}
}
}
}
else{
if((T.right != null) && (T.left != null)){ //if x == T.item and both left and right exist
T.item = FindMax(T.left).item; //find the max item in the left sub tree or the right most value of the left subtree and set it as the new subtree root item
T.left = Remove(T.left, T.item); //remove the value you just made the new subtree root from the left subtree
}
else
{
if(T.left != null){ //if only one side exists return it.
return T.left;
}
else
{
return T.right;
}
}
}
}
return T;
}
private AVLNode Remove(AVLNode T,int x)
{
如果(T==null){//如果该值不存在,则返回null
返回null;
}
if(xT.right.right.height){//如果子树的高度不平衡
返回T=doubleRotateThrightChild(T);//如果删除右->左->右->右双旋转
}
否则{
返回T=singlerotateThightChild(T);//如果在删除右->左<右->右单旋转之后
}
}
}
}
其他的
{
if(x>T.item){//if x>item
如果(T.right==null)\
{//在处理传递的空指针时遇到问题,请在此处进行处理
return null;//如果T.right==null,则返回null
}
其他的
{
T.right=Remove(T.right,x);//如果T.right存在,则使用T.right递归调用Remove
T.height=Math.max(高度(T.left)、高度(T.right))+1;//静止高度
如果(高度检查(T.左)-高度检查(T.右)==2)
{//检查是否存在夹层
如果(T.left.left.height>T.left.right.height)
{
返回T=DoubleRotateWithLeftChild(T);//如果在删除左->左高度>左->右高度后进行双旋转
}
其他的
{
返回T=SingleRotateWithLeftChild(T);//如果删除左->左高度<左->右高度单次旋转
}
}
}
}
否则{
if((T.right!=null)和&(T.left!=null)){//if x==T.item并且左和右都存在
T.item=FindMax(T.left).item;//在左子树或左子树最右边的值中查找max项,并将其设置为新的子树根项
T.left=Remove(T.left,T.item);//从左子树中删除刚刚创建的新子树根的值
}
其他的
{
如果(T.left!=null){//如果只有一侧存在,则返回它。
返回T.left;
}
其他的
{
返回T.right;
}
}
}
}
返回T;
}
希望我的实现能帮助您理解您的错误之处。
我看到的主要是旋转的实现,你没有使用任何双旋转。这是一个具有右子对象的双旋转。从我上面的代码中,您将看到何时需要使用它
private AVLNode<T> DoubleRotateWithRightChild(AVLNode<T> T)
{
T.right = SingleRotateWithLeftChild(T.right);
return SingleRotateWithRightChild(T);
}
专用AVLNode DoubleRotateWithChild(AVLNode T)
{
T.right=单旋转thleftchild(T.right);
返回单次旋转第三个孩子(T);
}
您的删除方法在哪里?至少把它挂起来,这样我们可以给你一些想法,或者告诉你如何修复它。所以我在上面添加了删除方法,看看。。。