package data_structure.tree.two;
import java.util.ArrayList;
import java.util.List;
/**
* 完全平衡二叉树
* @author chenmingming
*
*/
public class AVLTree <T extends Comparable<T>>{
/**
* AVL树的节点
* @author chenmingming
*
*/
class Node <T>{
Node<T> left;
Node<T> right;
T data;
int height = 0;
@Override
public String toString() {
return data+"高度"+height;
}
}
/**
* 根节点
*/
private Node<T> root;
public Node<T> getRoot() {
return root;
}
/**
* 内部使用的方法获取指定节点的高度
* @param tree
* @return
*/
private int height(Node<T> tree){
if(tree!=null)
return tree.height;
return 0;
}
/**
* 对外使用获取整颗树的高度
* @return
*/
public int height() {
return root.height;
}
/**
* 获取两个中大的一个
* @param v1
* @param v2
* @return
*/
private int max(int v1,int v2) {
if(v1>v2)
return v1;
else
return v2;
}
/**************************************************************************************************/
/**
* http://blog.csdn.net/coslay/article/details/46984119
*/
/**
* LL 左单旋转
* @param k1 旋转前的根节点
* @return 旋转后的根节点
*/
private Node<T> LL(Node<T> k1) {
Node<T> k2;
k2 = k1.left;
k1.left = k2.right;
k2.right = k1;
k1.height = max(this.height(k1.left),this.height(k1.right))+1;
k2.height = max(this.height(k2.left),this.height(k2.right))+1;
return k2;
}
/**
* RR 右单旋转
* @param k1 旋转前的根节点
* @return 旋转后的根节点
*/
private Node<T> RR(Node<T> k1){
Node<T> k2;
k2 = k1.right;
k1.right = k2.left;
k2.left = k1;
k1.height = max(this.height(k1.left),this.height(k1.right))+1;
k2.height = max(this.height(k2.left),this.height(k2.right))+1;
return k2;
}
/**
* LR 左右双旋转
* @param k1 旋转前的根节点
* @return 旋转后的根节点
*/
private Node<T> LR(Node<T> k1) {
k1.left = this.RR(k1.left);
return this.LL(k1);
}
/**
* RL 右左双旋转
* @param k1 旋转前的根节点
* @return 旋转后的根节点
*/
private Node<T> RL(Node<T> k1) {
k1.right = this.LL(k1.right);
return this.RR(k1);
}
/******************************************************************************************/
/**
*
* @param root 树的根节点
* @param key 树的键值
* @return 新的树的根节点
*/
private Node<T> intser(Node<T> root,T key){
//System.out.println(key);
if (root == null) {
if(this.root!=null){
root = new Node<T>();
root.data = key;
}else{
this.root = new Node<T>();
this.root.data = key;
root = this.root;
}
}else {
int flag = key.compareTo(root.data);
//往左边插入
if (flag<0) {
root.left = intser(root.left, key);
//出现不平衡的情况
if((this.height(root.left) - this.height(root.right))>1){
if(root.right==null){
int j = key.compareTo(root.left.data);
if(j<0){
root = this.LL(root);
}else {
root = this.LR(root);
}
}else {
int leftFlag = key.compareTo(root.left.data);
//左边左子树插入 --LL
if(leftFlag<0){
root = this.LL(root);
}else{
//左边右子树插入 --LR
root = this.LR(root);
}
}
}
}else{
//往右边插入
root.right = intser(root.right, key);
//出现不平衡的情况
if ((this.height(root.right) - this.height(root.left))>1) {
if(root.left==null){
int j = key.compareTo(root.right.data);
if(j<0){
root = this.RL(root);
}else {
root = this.RR(root);
}
}else{
int rightFlag = key.compareTo(root.left.data);
//往右边右子树插入 --RR
if(rightFlag>0){
root = this.RR(root);
}else {
//往右边左子树插入 --LR
root = this.RL(root);
}
}
}
}
}
root.height = max(this.height(root.left),this.height(root.right))+1;
this.root = root;
return root;
}
/**
* 插入树
* @param key
*/
public void inset(T key) {
this.intser(this.root, key);
}
/**********************************************************************************/
/**
* 重小到大排列(中序排列)
* @param list
* @param root
* @return
*/
private List<T> min2max(List<T> list,Node<T> root){
if(list==null){
list = new ArrayList<T>();
}
if (root == null) {
return null;
}else{
min2max(list, root.left);
if(root.data!=null){
list.add(root.data);
}
min2max(list, root.right);
}
return list;
}
/**
* 获取重小到大排列的集合
* @return
*/
public List<T> min2max() {
return this.min2max(null, root);
}
/****************************************************************/
/**
* 获取对应的数据
*/
private T getData(T t,Node<T> root) {
if(root==null){
System.out.println("对不起找不到对应的数据");
return null;
}
int v = t.compareTo(root.data);
T value;
if(v>0){
value = getData(t, root.right);
}else if (v<0) {
value = getData(t, root.left);
}else {
value = root.data;
}
return value;
}
public T getData(T t) {
return this.getData(t,root);
}
}
比较时需要对象实现Comparable接口所以int ,double等基本类型就不能使用了
下面是我的测试实体
package data_structure.tree.two;
public class TestModel implements Comparable<TestModel>{
@Override
public int compareTo(TestModel o) {
int value = 0;
if(o.getAge()<this.age){
value = 1;
}else if(o.getAge()>this.age){
value = -1;
}
return value;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
private String name;
private int age;
}
以及我的测试类
package data_structure.tree.two;
import java.util.List;
public class Test {
public static void main(String[] args) {
Integer a [] =new Integer[]{2,5,1,7,6,8,9,4,8,10,0,31};
BRTree<Integer> tree = new BRTree<Integer>();
for (Integer integer : a) {
tree.insert(integer);
}
tree.min2max();
}
}