AVL树的Java实现(递归方法)
2014-12-18 10:59
597 查看
AVL树是一种自平衡的二叉查找树。首先它是一种二叉查找树,满足任意一个节点(叶子节点除外)的值大于它左子树上任意一个节点,且小于它右子树上任意一个节点。因为二叉查找树的深度可能为O(N),这样的效率较低,因此衍生出了AVL树,它具有自平衡的效果,能保持树的深度为O(logN)。AVL树满足:任意一个节点它的左子树的高度和右子树的高度差不超过1。(假设叶子节点的高度为0,null节点的高度为-1)
基于上述的理论完成程序的编写,既然要保存每个节点的高度,Node节点就需要一个int类型的height变量。自己完成的是采用递归的方法,以后有时间完成非递归方法的实现。上代码:
基于上述的理论完成程序的编写,既然要保存每个节点的高度,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 ""; } }输出结果:
相关文章推荐
- JAVA使用循环和递归方法实现斐波拉切数列
- java实现递归文件列表的方法
- Java实现二叉树的前序、中序、后序、层序遍历(非递归方法)
- Java非递归实现删除任意目录的方法
- Java代码实现一维数组的二分查找(折半查找)(非递归方法)
- Java实现二叉树的前序、中序、后序、层序遍历(递归方法)
- Java实现链式存储的二叉查找树(递归方法)
- java中的递归方法(简单实现)
- 【leetcode】104. Maximum Depth of Binary Tree【java】三种实现方法:递归、BFS、DFS
- Java中的递归详解及实现方法
- java :非递归方法的二叉搜索树,实现部分功能
- Java实现分叉查找--递归方法
- Java实现二叉树的前序、中序、后序遍历(非递归方法)
- Java递归方法求5!的实现代码
- 完全二叉树的JAVA实现(以及非递归遍历方法)
- java、js中实现无限层级的树形结构方法(类似递归)
- java递归方法实现菲波拉契数列问题
- Java实现二叉树的前序、中序、后序遍历(递归方法)
- Java实现二叉树的前序、中序、后序、层序遍历(非递归方法)
- java实现的递归方法逆序对查找