数据结构--平衡二叉树

来源:互联网 发布:淘宝法院拍卖的房子 编辑:程序博客网 时间:2024/06/05 01:55

1、基本概念

平衡二叉树(AVL树)是一种二叉排序树,其中每个节点的左子树和右子树的高度最多相差1
平衡因子:二叉树的左子树深度减去右子树的深度 只有-1,0,1三个值
最小不平衡子树:距离插入节点最近,且平衡因子的绝对值大于1的节点为根节点

2、实现

在构建二叉排序树的过程中,每当插入一个节点,先检查是否因插入的新数据破坏了平衡性 若是 找出最小不平衡子树。在保持排序二叉树特性的情况下,调整最小不平衡子树中各节点之间的链接关系,进行相应的旋转,使之成为新的平衡子树。

平衡二叉树就是一个二叉排序树,只不过需要保证左右子树的深度在正负1以内,保证深度,就是做树的左右旋转操作

static class AVLNode{    int data;    int height; //节点的深度    AVLNode left, right;    public AVLNode(int data){        this.data = data;        left = null;        right = null;    }}//测试public static void main(String[] args) {    int[] src = { 3,2,1,4,5,6,7,16,15,14,13,12,11,10,8,9 };    AVLNode root = null;    for (int i = 0; i < src.length; i++) {        root = insert(root, src[i]);    }    print(root);    System.out.println("----------------------");    remove(root, 15);    print(root);}//获取节点的高度public static int height(AVLNode node){    if(node != null)        return node.height;    return 0;}//左旋转public static AVLNode llRotate(AVLNode node){    AVLNode tmp = node.left;    node.left = tmp.right;    tmp.right = node;    node = tmp;    node.height = Math.max(height(node.left), height(node.right))+1;    tmp.height = Math.max(height(tmp.left), height(node))+1;    return tmp;}//右旋转public static AVLNode rrRotate(AVLNode node){    AVLNode tmp = node.right;    node.right = tmp.left;    tmp.left = node;    node.height = Math.max(height(node.left), height(node.right))+1;    tmp.height = Math.max(height(tmp.right), height(node))+1;    return tmp;}//先左旋转 再右旋转public static AVLNode lrRotate(AVLNode node){    node.left = rrRotate(node.left);    return llRotate(node);}//先右旋转 再左旋转public static AVLNode rlRotate(AVLNode node){    node.right = llRotate(node.right);    return rrRotate(node);}//插入操作public static AVLNode insert(AVLNode node, int data) {    if(node == null) {//新建节点        node = new AVLNode(data);    } else {        if(data < node.data) {  //插入左子树            node.left = insert(node.left, data);            //如果排序二叉树不平衡            if(height(node.left) - height(node.right) == 2)                //当前节点在左子树,当前节点的data比上一个节点小 表示上一个节点也是左子树 所以直接左转换                if(data < node.left.data)                    node = llRotate(node);                else                    //当前节点比上一个节点大 表示上一个节点是右子树                    node = lrRotate(node);        }else if (data > node.data) {            node.right = insert(node.right, data);            if(height(node.right) - height(node.left) == 2)                if(data > node.right.data)                    node = rrRotate(node);                else                    node = rlRotate(node);        }else            ;    }    if(node != null)        //回溯,使节点深度每次+1        node.height = Math.max(height(node.left), height(node.right))+1;    return node;}public static AVLNode remove(AVLNode node, int data){    if(node == null)        return null;    if(data < node.data) {  //左子树        node.left = remove(node.left, data);        if(height(node.right) - height(node.left) == 2) {   //如果失去平衡            AVLNode r =  node.right;    //右子树高度大 旋转右子树 使平衡因子小于2            if (height(r.right) > height(r.left))                node = rlRotate(node);            else                node = rrRotate(node);        }    } else if(data > node.data) {   //右子树        node.right = remove(node.right, data);        if(height(node.left) - height(node.right) == 2) {            AVLNode l =  node.left;            if (height(l.right) > height(l.left))                node = lrRotate(node);            else                node = llRotate(node);        }    } else if(node.left!=null && node.right!=null) {        //如果左子树的深度大于右子树,则使用左子树的最大值替换        if(height(node.left) > height(node.right)) {            node.data = findMax(node.left).data;            node.left = remove(node.left, node.data);        } else {            //否则使用右子树的最小值替换            node.data = findMin(node.right).data;            node.right = remove(node.right, node.data);        }    } else {        node = (node.left != null) ? node.left : node.right;    }    return node;}//查找树中的最小值public static AVLNode findMin(AVLNode node){    if(node == null)        return null;    else if(node.left == null)        return node;    else        return findMin(node.left);//最左边的是最小的}//查找树中的最大值public static AVLNode findMax(AVLNode node){    if(node == null)        return null;    else if(node.right == null)        return node;    else        return findMax(node.right);//最右边的是最大的}//中序遍历public static void print(AVLNode node){    if(node != null) {        print(node.left);        System.out.println(node.data + "  "+node.height);        print(node.right);    }}

参考:
http://www.cnblogs.com/skywang12345/p/3577479.html

原创粉丝点击