Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
JAVA AVL删除,如何使用现有的旋转代码实现?_Java_Algorithm_Data Structures - Fatal编程技术网

JAVA AVL删除,如何使用现有的旋转代码实现?

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;

已经三天了,我仍然无法修复我的问题,我的问题是我的删除代码并不是每次删除都能完美工作。我从D.S.Malik的书中得到了这段代码,书名为“Java中的数据结构”。我想执行删除操作,但在大多数情况下,当我使用现有的旋转代码时,删除操作失败,完整的程序如下所示:

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);
}

您的删除方法在哪里?至少把它挂起来,这样我们可以给你一些想法,或者告诉你如何修复它。所以我在上面添加了删除方法,看看。。。