avl树的插入与删除

                                      --也许有错,欢迎指点

{

public Object element;

public Node left;

public Node right;

public int height;

public Node[] path =new Node[32];

public Node(Object data,Node lt,Node rt)

{
element =data;

left=lt;

right=rt;

height=0;

}
public int CompareTo(Object obj)

{
return (((int)element.CompareTo((int)obj));

}

public int GetHeight()

{

if(this==null)

   return -1;

else 

  return this.height;

}


public Node insert(Object item,Node n)

{

if (n==null)                            //若为空 直接插入

 n=new Node(item,null,null);

else if (((int)item).CompareTo((int)n.element)<0)   //否则就比较值  小于这个节点就与这个节点的做儿子比较 

{
n.left=insert(item,n.left);                                            //递归

if(n.left.GetHeight()-n.right.GetHeight()==2)              //如果左节点比有节点高度多二 则不符合平衡状态  

  if (((int)item).CompareTo((int)n.left.element)<0)        //如果插入的值比左节点要小 就符合了单独右旋转

  n=left(n);

 else n=DoubleWithLeft(n);                                           //否则就是先子节点右旋转 然后在根节点左旋转

}

if(((int)item).CompareTo((int)n.element)>0)                  

{

n.right=insert(item,n.right)

   if(n.right.GetHeight()-n.left.GetHeight()==2)

     if(((int)item).CompareTo((int)n.right.element)>0)

        n=right(n);

     else  n=DoubleWithRight(n);

}

n.height=Math.Max(n.left.GetHeight(),n.right.GetHeight())+1;

return n;

}


     - - - - - 输入要删的值  先找到位置 然后引用RemoveNode方法

 public bool find(int val, Node n)
    {
        while (n != null)
        {
            if (val.CompareTo((int)n.element) > 0)
                n = n.right;
            else if (val.CompareTo((int)n.element) < 0)
                n = n.left;
            else break;
        }
        if ((int)n.element == val)
        {
            RemoveNode(n);
            return true;
        }
        else return false;
    }


  - - - - -利用Node   Path【】储存删除掉的那个节点的那一条 然后看哪里的节点不符合平衡状态 在旋转


   public Node RemoveNode(Node node)
    {
        Node j = node;
        if (node.left != null)
        {
            node = node.left;
            while (node.right != null)
            {


                node = node.right;
                path[v] = node;
                v++;
            }
            j.element = node.element;
            node = node.left;
        }
        else if (node.right != null)
        {
            node = node.right;
            while (node.left != null)
            {


                node = node.left;
                path[v++] = node;
               
            }
            j.element = node.element;
            node = node.right;
        }
        else node = null;


        while(v!=0)
        {
            v -= 1;
            if((path[v].left.GetHeight())-(path[v].right.GetHeight())==2)
            {
                if ((path[v].left.left.GetHeight()) - (path[v].left.right.GetHeight()) == 1)
                    WithLeft(path[v]);
                else DoubleWithLeft(path[v]);
            }
            
            else if ((path[v].left.GetHeight())-(path[v].right.GetHeight())==-2)
            {
                if ((path[v].right.left.GetHeight()) - (path[v].right.right.GetHeight()) == -1)
                    WithRight(path[v]);
                else DoubleWithRight(path[v]);
            }
            
        }
        return j;
    }














 

 

  avl树的是四种旋转(图片来自百度):

 单独的右旋转:




private Node  right(Node n1)

{

Node n2 = n1.right;                           //先把子节点放在n2 上

n1.right=n2.left;                                //把子节点下的左儿子节点放在子节点原来的位置              

n2.left=n1;                                         //把子节点的父亲放在N2的左儿子节点上

n1.height=Math.Max(n1.left.GetHeight(),n1.right.GetHeight())+1;       

n2.height=Math.Max(n2.left.GetHeight(),n1.height)+1;                         //记录高度

return n2;

}


 单独的左旋转:




private Node left(Node n2)

{

Node n1=n2.left;

n2.left=n1.right;

n1.right=n2;

n2.height=Math.Max(n2.left.GetHeight(),n2.right.GetHeight())+1;

n1.height=Math.Max(n1.left.GetHeight(),n2.height)+1;

return n1;

}

  先对子节点的右旋转在对跟节点左旋转:




private Node DoubleWithLeft(Node n3)

{

n3.left=right(n3.left);

return left(n3);

}


  先对子节点的左旋转在对根节点的右旋转:




private Node DoubleWithRight(Noed n4)

{

n4.right=left(n4.right);

return right(n4);

}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值