## 一直以来感觉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有错误请多多指教!!