AVL树的实现

## 一直以来感觉AVL树特别神秘,懂概念就是不会实现。今天终于实现了一波,但是没写删除0.0. 还是先说一下概念。

什么是AVL树呢:
AVL树是最先发明的自平衡二叉查找树。在AVL树中任何节点的两个子树的高度最大差别为1,所以它也被称为高度平衡树。增加和删除可能需要通过一次或多次树旋转来重新平衡这个树。

开始贴代码了

首先是结点的属性和构造函数

public  class Node
{
    public Node left;
    public Node right;
    int val;

    public Node(int val) {
        this.val = val;
    }

然后是插入函数,这里要注意每次插入后要进行判断是否满足AVL的条件(左右子树差小于等于1)

//节点的插入
public void add(Node node)
{
    if (node==null)
    {
        return;
    }
    if (node.val<this.val)
    {
        if (this.left==null)
        {
            this.left=node;
        }
        else
        {
            this.left.add(node);
        }
    }
    else
    {
        if (this.right==null)
        {
            this.right=node;
        }
        else
        {
            this.right.add(node);
        }
    }
    //如果右子树的高度减去左子树的高度要大于一 那么就进行左旋
    if (rightHeight()-leftHeight()>1)
    {
        //如果右子树的左子树的高度大于右子树的高度和话,会导致左旋后又出现不平衡的现象。所以先对右子树的左子树进行右旋!!
        if (right!=null&&right.leftHeight()>right.rightHeight())
        {
            right.rightRotate();
            leftRotate();
        }
        else
        {
            leftRotate();
        }
        return;
    }
    //和上面的道理一样
  if (leftHeight()-rightHeight()>1)
  {
      if (left!=null&&left.rightHeight()>left.leftHeight())
      {
          left.leftRotate();
          rightRotate();
      }
      else
      {
          rightRotate();
      }
      return;
  }

}

这个是很重要的一个部分,判断树的高度

//计算左子树的高度
public  int leftHeight()
{
    if (this.left!=null)
    {
        return this.left.height();
    }
    return 0;
}
//计算右子树的高度
public  int rightHeight()
{
    if (this.right!=null)
    {
        return this.right.height();
    }
    return 0;
}
//递归求出树的高度
public  int height()
{
    //如果左子节点为null,高度自然是0,如果不是再去递归看它的高度
    //右子节点一样的道理
    //最后求出最大值就是树的高度
    return Math.max(this.left==null?0:this.left.height(),this.right.right==null?0:this.right.height());
}

最最最核心的代码来了,左旋和右旋

//左旋转
public  void  leftRotate()
{
    //创建一个新的结点,值为当前结点的值
    Node node=new Node(val);
    //新节点的左结点为当前节点的左结点
    node.left=left;
    //新节点的右结点为当前节点右结点的左结点
    node.right=right.left;
    //当前结点的值变为右结点的值
    val=right.val;
    //当前结点的右结点为右结点的右结点
    right=right.right;
    //当前结点的左结点为新节点
    left=node;
    //画个图就明白了
}
//右旋 道理和左旋一样
public void  rightRotate()
{
    Node node=new Node(val);
    node.right=right;
    node.left=left.right;
    val=left.val;
    left=left.left;
    left=node;
}

下来就是中序遍历的方法

public void inOrder()
{
    if (this.left!=null)
    {
        this.left.inOrder();
    }
    System.out.println(this.val);
    if (this.right!=null)
    {
        this.right.inOrder();
    }
}

这就是所有的内容了 ,初学AVL有错误请多多指教!!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值