数据结构&算法-AVL平衡二叉树

Posted 彩色墨水

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了数据结构&算法-AVL平衡二叉树相关的知识,希望对你有一定的参考价值。

概念

高度平衡的二叉排序树。我们将二叉树上结点的左子树深度减去右子树深度的值成为平衡因子。平衡因子的绝对值不大于1就是平衡二叉树了。

运算结果

代码

using System;

namespace AVLBalancedBinaryTrees

    class Program
    
        static void Main(string[] args)
        

            Tree tree = new Tree();
            tree.Inset(16);
            tree.Inset(3);
            tree.Inset(7);
            tree.Inset(11);
            tree.Inset(9);
            tree.Inset(26);
            tree.Inset(18);
            tree.Inset(14);
            tree.Inset(15);
            tree.Inset(115);
            tree.Inset(315);
            tree.Inset(44);
            tree.Inset(58);
            tree.Inset(31);

            tree.InOrder();
            Console.ReadKey();
        
    
    class Node
    
        public int data;//数据
        public Node left;//左孩子
        public Node right;//又孩子
        public Node parent;
        public int BF;//平衡因子,左-右 数量
        public Node(int data)
        
            this.data = data;
        
    

    class Tree
    
        Node root;
        int count;
        public void Inset(int data)
        
            if (root == null)
            
                root = new Node(data);
                return;
            
            Node currentNode = root;
            Node parentNode = root;


            while (currentNode != null)
            
                parentNode = currentNode;
                if (data < currentNode.data)
                

                    currentNode = currentNode.left;

                
                else
                

                    currentNode = currentNode.right;

                

            
            currentNode = new Node(data);
            currentNode.parent = parentNode;
            //来到这里说明已经符合条件的位置了
            if (data < parentNode.data)
            
                parentNode.left = currentNode;
            
            else
            
                parentNode.right = currentNode;
            
            while (parentNode != null)
            
                if (parentNode.left == currentNode)
                
                    parentNode.BF++;
                
                else
                
                    parentNode.BF--;
                
                if (parentNode.BF == 0)
                
                    break;
                
                else if (parentNode.BF == -1 || parentNode.BF == 1)
                
                    currentNode = parentNode;
                    parentNode = currentNode.parent;
                
                else
                
                    if (parentNode.BF == 2)
                    
                        if (currentNode.BF == 1)//LL
                        
                            RotaeLL(parentNode);
                        
                        else
                        
                            RotateLR(parentNode);
                        
                    
                    else
                    
                        if (currentNode.BF == -1)
                        
                            RotateRR(parentNode);
                        
                        else
                        
                            RotateRL(parentNode);
                        
                    
                    break;
                

            
            count++;

        

        void RotaeLL(Node parent)
        
            Node grandParent = parent.parent;
            Node curNode = parent.left;
            if (grandParent != null)
            
                if (grandParent.left == parent)
                
                    grandParent.left = curNode;
                    curNode.parent = grandParent;
                    grandParent.BF--;
                
                else
                
                    grandParent.right = curNode;
                    curNode.parent = grandParent;
                    grandParent.BF++;
                
            
            else
            
                curNode.parent = null;
                root = curNode;
            

            parent.left = curNode.right;
            if (parent.left != null)
            
                parent.left.parent = parent;
            
            curNode.right = parent;
            parent.parent = curNode;
            curNode.BF--;
            parent.BF--;
        


        public void RotateLR(Node parent)
        

            Node grandParent = parent.parent;
            Node curNode = parent.left;
            Node c = curNode.right;
            if (grandParent != null) //若存在G, 则将c改为g的孩子
            
                if (grandParent.left == parent)
                
                    grandParent.left = c;
                    c.parent = grandParent;
                    grandParent.BF--;
                
                else
                
                    grandParent.right = c;
                    c.parent = grandParent;
                    grandParent.BF++;
                
            
            else //若不存在G
            
                c.parent = null;
                root = c;
            
            //将cur的右孩子改为x3
            curNode.right = c.left;
            if (curNode.right != null)
            
                curNode.right.parent = curNode;
            
            //将p的左孩子改为X4
            parent.left = c.right;
            if (parent.left != null)
            
                parent.left.parent = parent;
            
            //将c的左孩子改为cur
            c.left = curNode;
            curNode.parent = c;
            //将c的右孩子改为P
            c.right = parent;
            parent.parent = c;

            parent.BF = 0;
            curNode.BF++;
            c.BF = curNode.BF;
        
        public void RotateRR(Node parent)
        

            Node grandParent = parent.parent;
            Node curNode = parent.right;
            if (grandParent != null) //若存在G, 则将cur改为g的孩子
            
                if (grandParent.left == parent)
                
                    grandParent.left = curNode;
                    curNode.parent = grandParent;
                    grandParent.BF--;
                
                else
                
                    grandParent.right = curNode;
                    curNode.parent = grandParent;
                    grandParent.BF++;
                
            
            else //若不存在G
            
                curNode.parent = null;
                root = curNode;
            
            parent.right = curNode.left; //将cur的左孩子X2改为P的右孩子
            if (parent.right != null)
            
                parent.right.parent = parent; //将P改为X2的parent
            
            curNode.left = parent; //将P改为cur的左孩子
            parent.parent = curNode; //将cur改为P的parent
            curNode.BF++;
            parent.BF++;
        
        public void RotateRL(Node parent)
        

            Node grandParent = parent.parent;
            Node curNode = parent.right;
            Node c = curNode.left;
            if (grandParent != null) //若存在G, 则将c改为g的孩子
            
                if (grandParent.left == parent)
                
                    grandParent.left = c;
                    c.parent = grandParent;
                    grandParent.BF--;
                
                else
                
                    grandParent.right = c;
                    c.parent = grandParent;
                    grandParent.BF++;
                
            
            else //若不存在G
            
                c.parent = null;
                root = c;
            
            //将cur的左孩子改为x4
            curNode.left = c.right;
            if (curNode.left != null)
            
                curNode.left.parent = curNode;
            
            //将p的右孩子改为X3
            parent.right = c.left;
            if (parent.right != null)
            
                parent.right.parent = parent;
            
            //将c的右孩子改为cur
            c.right = curNode;
            curNode.parent = c;
            //将c的左孩子改为P
            c.left = parent;
            parent.parent = c;

            parent.BF = 0;
            curNode.BF--;
            c.BF = -curNode.BF;
        

        public void InOrder()
        
            _InOrder(root);
        

        private void _InOrder(Node node)
        
            if (node == null)
            
                return;
            

            _InOrder(node.left);
            Console.Write(node.data + " ");
            _InOrder(node.right);
        
    


参考

平衡二叉树(AVL树)的基本操作

C# AVL树(平衡二叉树)的实现

以上是关于数据结构&算法-AVL平衡二叉树的主要内容,如果未能解决你的问题,请参考以下文章

Day584&585.平衡二叉树 -数据结构和算法Java

D13-平衡二叉树[Java数据结构和算法]

什么是《平衡二叉树》

AVL树-平衡二叉树

数据结构54:平衡二叉树(AVL树)

什么是平衡二叉树