现在的位置: 首页 > 综合 > 正文

AVL樹旋轉圖解

2013年05月08日 ⁄ 综合 ⁄ 共 1725字 ⁄ 字号 评论关闭

AVL樹是一顆平衡樹,其左右子樹的高度差不會超過一層。爲了保持這一性質,採用旋轉節點的方式來降低高度。

如下圖,紅色表示新插入的節點,一共4种情況:

  • 左左:節點1插入到左子樹的左節點,導致節點5不平衡。

實際上我們只需要關心節點1、3、5,根據二叉搜索樹的性質(左 < 中 < 右),所以祇有節點3才可以作為父節點,於是將節點5繞節點3進行一次左旋,達到平衡。

 

  • 右右:和左左類似,可以通過一次右旋來實現平衡,如下圖:

 

  • 左右:這种情況光旋轉失衡的節點5是不夠的,因爲節點3是無法成爲父節點的,祇有節點4才有可能。

所以先把節點3右旋以使節點4居中,再將節點5左旋,共兩次旋轉實現平衡。

 

  • 右左:和左右的情況類似,也是兩次,先左旋后右旋。

 

 

    class AVLNode<T>
    {
        public T Value { get; set; }
        public AVLNode<T> Left { get; set; }
        public AVLNode<T> Right { get; set; }

        public int Height
        {
            get
            {
                return Math.Max(GetHeight(Left), GetHeight(Right)) + 1;
            }
        }

        public static int GetHeight(AVLNode<T> node)
        {
            return (node == null) ? -1 : node.Height;
        }
    }

    class AVLTree<T> where T : IComparable<T>
    {
        public AVLNode<T> Root { get; set; }

        public void Insert(T value)
        {
            Root = Insert(value, Root);
        }

        private AVLNode<T> Insert(T value, AVLNode<T> node)
        {
            if (node == null) return new AVLNode<T> { Value = value };

            int result = value.CompareTo(node.Value);
            if (result < 0)
            {
                node.Left = Insert(value, node.Left);

                if (AVLNode<T>.GetHeight(node.Left) - AVLNode<T>.GetHeight(node.Right) == 2)
                {
                    if (value.CompareTo(node.Left.Value) < 0)
                    {
                        node = RotateLeft(node);
                    }
                    else
                    {
                        node = RotateRightLeft(node);
                    }
                }
            }
            else if (result > 0)
            {
                node.Right = Insert(value, node.Right);

                if (AVLNode<T>.GetHeight(node.Right) - AVLNode<T>.GetHeight(node.Left) == 2)
                {
                    if (value.CompareTo(node.Right.Value) > 0)
                    {
                        node = RotateRight(node);
                    }
                    else
                    {
                        node = RotateLeftRight(node);
                    }
                }
            }
            else
            {

            }

            return node;
        }

        private AVLNode<T> RotateLeft(AVLNode<T> node)
        {
            var child = node.Left;
            node.Left = child.Right;
            child.Right = node;

            return child;
        }

        private AVLNode<T> RotateRight(AVLNode<T> node)
        {
            var child = node.Right;
            node.Right = child.Left;
            child.Left = node;

            return child;
        }

        private AVLNode<T> RotateRightLeft(AVLNode<T> node)
        {
            node.Left = RotateRight(node.Left);
            return RotateLeft(node);
        }

        private AVLNode<T> RotateLeftRight(AVLNode<T> node)
        {
            node.Right = RotateLeft(node.Right);
            return RotateRight(node);
        }
    }

 

有了圖,代碼就不難理解了

抱歉!评论已关闭.