您的位置:首页 > 编程语言 > Java开发

AVL树的Java实现(递归方法)

2014-12-18 10:59 597 查看
AVL树是一种自平衡的二叉查找树。首先它是一种二叉查找树,满足任意一个节点(叶子节点除外)的值大于它左子树上任意一个节点,且小于它右子树上任意一个节点。因为二叉查找树的深度可能为O(N),这样的效率较低,因此衍生出了AVL树,它具有自平衡的效果,能保持树的深度为O(logN)。AVL树满足:任意一个节点它的左子树的高度和右子树的高度差不超过1。(假设叶子节点的高度为0,null节点的高度为-1)

基于上述的理论完成程序的编写,既然要保存每个节点的高度,Node节点就需要一个int类型的height变量。自己完成的是采用递归的方法,以后有时间完成非递归方法的实现。上代码:

public class TreeTest
{
public static void main(String[] args)
{
AVLTree<Integer> st=new AVLTree<Integer>();
st.insert(15);
st.insert(7);
st.insert(5);
st.insert(37);
st.insert(70);
System.out.println("插入节点:"+st);
st.remove(7);
st.remove(15);
System.out.println("删除节点:"+st);
}

}

//AVL树:每个节点的左子树和右子树的高度差最多为1
class AVLTree<T extends Comparable<T>>
{
private Node<T> root=null;

public AVLTree()
{
}
public void insert(T t)
{
root=insert(t,root);
}
public void remove(T t)
{
root=remove(t,root);
}
public T findMax()
{
if(root==null)     //如果还没有元素则返回空
return null;
return findMax(root).element;
}
public T findMin()
{
if(root==null)		//如果还没有元素则返回空
return null;
return findMin(root).element;
}
//先序遍历
public void printFirst()
{
System.out.print("先序遍历:");
printFirst(root);
System.out.print("\n");
}
private void printFirst(Node<T> node)
{
if(node!=null)
{
System.out.print(node.element+" ");
printFirst(node.left);
printFirst(node.right);
}
}
//中序遍历
public void printTree()
{
System.out.print("中序遍历:");
printTree(root);
System.out.print("\n");
}
private void printTree(Node<T> node)
{
if(node!=null)
{
printTree(node.left);
System.out.print(node.element+" ");
printTree(node.right);
}
}
//插入分为4总情况,分为两组,这两组镜像对称。返回之前要进行node的高度赋值
private Node<T> insert(T t,Node<T> node)
{
if(node==null)
return new Node<T>(t,null,null);
int i=t.compareTo(node.element);
if(i>0)
{
node.right=insert(t,node.right);

int cha=height(node.left)-height(node.right);
if(cha>1 | cha<-1)
{
if(t.compareTo(node.right.element)>0)
node=singleRightChild(node);
else
node=doubleRightChild(node);
}
}
else
{
if(i<0)
{
node.left=insert(t,node.left);
int cha=height(node.left)-height(node.right);
if(cha>1 | cha<-1)
{
if(t.compareTo(node.left.element)<0)
node=singleLeftChild(node);
else
node=doubleLeftChild(node);
}
}
}
node.height=Math.max(height(node.left),height(node.right))+1;
return node;
}
//删除节点方法:递归删除(三种情况),再判断node节点左右子节点的高度差,|差|>1则进行旋转平衡,高度赋值
private Node<T> remove(T t,Node<T> node)
{
if(node==null)
return null;
int i=t.compareTo(node.element);
if(i==0)
{
if(node.right!=null && node.left!=null)
{
node.element=findMin(node.right).element;
node.right=remove(node.element,node.right);
}
else
node=(node.right==null)?node.left:node.right;
}
else if(i>0)
node.right=remove(t,node.right);
else
node.left=remove(t,node.left);
if(node!=null)	   							//如果该节点不为空,则进行平衡的判别处理和高度的赋值
{
if(height(node.right)-height(node.left)>1)   	//进行右旋转
{
if(height(node.right.right)>=height(node.right.left))   //进行单旋转
node=singleRightChild(node);
else										//进行双旋转
node=doubleRightChild(node);
}
else if(height(node.left)-height(node.right)>1)	//进行左旋转
{
if(height(node.left.left)>=height(node.left.right))   //进行单旋转
node=singleLeftChild(node);
else										//进行双旋转
node=doubleLeftChild(node);
}
node.height=Math.max(height(node.right),height(node.left))+1;
}
return node;
}
private Node<T> singleRightChild(Node<T> node)
{
Node<T> n=node.right;
node.right=n.left;
n.left=node;
node.height=Math.max(height(node.left),height(node.right))+1;
n.height=Math.max(height(n.right),height(n.left))+1;
return n;
}
private Node<T> singleLeftChild(Node<T> node)
{
Node<T> n=node.left;
node.left=n.right;
n.right=node;
node.height=Math.max(height(node.left),height(node.right))+1;
n.height=Math.max(height(n.right),height(n.left))+1;
return n;
}
//一次双旋转=两次单旋转
private Node<T> doubleRightChild(Node<T> node)
{
node.right=singleLeftChild(node.right);
return singleRightChild(node);
}
private Node<T> doubleLeftChild(Node<T> node)
{
node.left=singleRightChild(node.left);
return singleLeftChild(node);
}
//返回节点的高度,空节点为-1。新建节点的高度为0
private int height(Node<T> node)
{
return (node==null)?-1:node.height;
}
//返回元素最小的节点
private Node<T> findMin(Node<T> node)
{
if(node==null)
return null;
if(node.left==null)
return node;
return findMin(node.left);
}
//返回元素最大的节点
private Node<T> findMax(Node<T> node)
{
if(node==null)
return null;
if(node.right==null)
return node;
return findMax(node.right);
}
//节点类,包含元素和高度信息
private static class Node<T>
{
private T element;
private int height;
private Node<T> left;
private Node<T> right;
public Node(T element,Node<T> left,Node<T> right)
{
this.element=element;
this.left=left;
this.right=right;
height=0;
}
}
@Override
public String toString()
{
StringBuilder sb=new StringBuilder();
sb.append("[");
sb.append(print(root));
sb.append("]");
return sb.toString();
}
//递归输出,中序遍历
private String print(Node<T> node)
{
if(node!=null)
{
StringBuilder sb=new StringBuilder();
sb.append(print(node.left));
if(node.left!=null)
sb.append(",");
sb.append(node.element);
if(node.right!=null)
sb.append(",");
sb.append(print(node.right));
return sb.toString();
}
return "";
}
}
输出结果:

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: