C#平衡树(AVLTree)

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

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics;
using System.Threading;
using System.IO;
using System.Collections;

namespace ConsoleApplication2
{
    public class Program
    {
        public static void Main()
        {
            int[] arr = { 3, 2, 1, 4, 5, 6, 7, 16, 15, 14, 13, 12, 11, 10, 8, 9 };

            AVLTree<int> avlTree = new AVLTree<int>();
            for (int i = 0; i < arr.Length; i++)
            {
                avlTree.Insert(arr[i]);
                Console.Write(arr[i] + " ");
            }
            Console.WriteLine();

            Console.Write("层遍历:");
            avlTree.LevelOrder();
            Console.WriteLine();

            Console.Write("删除节点15:");
            avlTree.Remove(15);
            avlTree.LevelOrder();
            Console.WriteLine();

            Console.Write("删除节点16:");
            avlTree.Remove(16);
            avlTree.LevelOrder();
            Console.WriteLine();

            Console.Write("删除节点7:");
            avlTree.Remove(7);
            avlTree.LevelOrder();
            Console.WriteLine();

            Console.Read();
        }
    }

    public class AVLTreeNote<TKey> where TKey : IComparable
    {
        public AVLTreeNote(TKey key, AVLTreeNote<TKey> leftNote, AVLTreeNote<TKey> rightNote)
        {
            Key = key;
            LeftNote = leftNote;
            RightNote = rightNote;
        }

        public TKey Key { get; set; }
        public int Height { get; set; }
        public AVLTreeNote<TKey> LeftNote { get; set; }
        public AVLTreeNote<TKey> RightNote { get; set; }

    }

    public class AVLTree<TKey> where TKey : IComparable
    {
        private AVLTreeNote<TKey> RootNote { get; set; }

        public AVLTree()
        {

        }

        private int GetHeight()
        {
            return 0;
        }

        private int GetHeight(AVLTreeNote<TKey> note)
        {
            return note == null ? 0 : note.Height;
        }

        private AVLTreeNote<TKey> LeftLeftRotation(AVLTreeNote<TKey> note)
        {
            AVLTreeNote<TKey> temp = note.LeftNote;
            note.LeftNote = temp.RightNote;
            temp.RightNote = note;

            note.Height = Math.Max(GetHeight(note.LeftNote), GetHeight(note.RightNote)) + 1;
            temp.Height = Math.Max(GetHeight(temp.LeftNote), GetHeight(temp.RightNote)) + 1;

            return temp;
        }

        private AVLTreeNote<TKey> RightRightRotation(AVLTreeNote<TKey> note)
        {
            AVLTreeNote<TKey> temp = note.RightNote;
            note.RightNote = temp.LeftNote;
            temp.LeftNote = note;

            note.Height = Math.Max(GetHeight(note.LeftNote), GetHeight(note.RightNote)) + 1;
            temp.Height = Math.Max(GetHeight(temp.LeftNote), GetHeight(temp.RightNote)) + 1;

            return temp;
        }

        private AVLTreeNote<TKey> LeftRightRotation(AVLTreeNote<TKey> note)
        {
            note.LeftNote = RightRightRotation(note.LeftNote);
            return LeftLeftRotation(note);
        }

        private AVLTreeNote<TKey> RightLeftRotation(AVLTreeNote<TKey> note)
        {
            note.RightNote = LeftLeftRotation(note.RightNote);
            return RightRightRotation(note);
        }

        public void Insert(TKey key)
        {
            RootNote = Insert(key, RootNote);
        }

        private AVLTreeNote<TKey> Insert(TKey key, AVLTreeNote<TKey> note)
        {
            if (note == null)
            {
                note = new AVLTreeNote<TKey>(key, null, null);
            }
            else
            {
                if (key.CompareTo(note.Key) < 0)
                {
                    note.LeftNote = Insert(key, note.LeftNote);

                    if (Math.Abs(GetHeight(note.LeftNote) - GetHeight(note.RightNote)) == 2)
                    {
                        if (key.CompareTo(note.LeftNote.Key) < 0)//其实这里判断就像知道新增加的子节点属于左节点还是右节点 画图的话 一目了然
                        {
                            note = LeftLeftRotation(note);
                        }
                        else
                        {
                            note = LeftRightRotation(note);
                        }
                    }
                }

                if (key.CompareTo(note.Key) > 0)
                {
                    note.RightNote = Insert(key, note.RightNote);

                    if (Math.Abs(GetHeight(note.RightNote) - GetHeight(note.LeftNote)) == 2)
                    {
                        if (key.CompareTo(note.RightNote.Key) > 0)//其实这里判断就像知道新增加的子节点属于左节点还是右节点 画图的话 一目了然
                        {
                            note = RightRightRotation(note);
                        }
                        else
                        {
                            note = RightLeftRotation(note);
                        }
                    }
                }
            }
            note.Height = Math.Max(GetHeight(note.LeftNote), GetHeight(note.RightNote)) + 1;
            return note;
        }


        public void Remove(TKey key)
        {
            Remove(key, RootNote);
        }

        private AVLTreeNote<TKey> Remove(TKey key, AVLTreeNote<TKey> note)
        {
            if (note == null)
            {
                return null;
            }

            if (key.CompareTo(note.Key) < 0)
            {
                note.LeftNote = Remove(key, note.LeftNote);

                if (Math.Abs(GetHeight(note.RightNote) - GetHeight(note.LeftNote)) == 2)
                {
                    AVLTreeNote<TKey> rightNote = note.RightNote;

                    if (GetHeight(rightNote.LeftNote) > GetHeight(rightNote.RightNote))
                    {
                        note = RightLeftRotation(note);
                    }
                    else
                    {
                        note = RightRightRotation(note);
                    }

                }
            }

            if (key.CompareTo(note.Key) > 0)
            {
                note.RightNote = Remove(key, note.RightNote);

                if (Math.Abs(GetHeight(note.RightNote) - GetHeight(note.LeftNote)) == 2)
                {
                    AVLTreeNote<TKey> leftNote = note.LeftNote;
                    if (GetHeight(leftNote.RightNote) > GetHeight(leftNote.LeftNote))
                    {
                        note = LeftRightRotation(note);
                    }
                    else
                    {
                        note = LeftLeftRotation(note);
                    }
                }
            }

            if (note.Key.CompareTo(key) == 0)
            {
                if (note.LeftNote != null && note.RightNote != null)
                {
                    if (GetHeight(note.LeftNote) > GetHeight(note.RightNote))
                    {
                        AVLTreeNote<TKey> max = FindMax(note.LeftNote);
                        note.Key = max.Key;
                        note.LeftNote = Remove(max.Key, note.LeftNote);
                    }
                    else
                    {
                        AVLTreeNote<TKey> min = FindMin(note.RightNote);
                        note.Key = min.Key;
                        note.RightNote = Remove(min.Key, note.RightNote);
                    }
                }
                else
                {
                    note = note.LeftNote == null ? note.RightNote : note.LeftNote;
                }
            }
            return note;
        }


        public void LevelOrder()
        {
            LevelOrder(RootNote);
        }

        private void LevelOrder(AVLTreeNote<TKey> note)
        {
            Queue<AVLTreeNote<TKey>> queue = new Queue<AVLTreeNote<TKey>>();
            queue.Enqueue(note);

            while (queue.Count > 0)
            {
                var temp = queue.Dequeue();

                Console.Write(temp.Key + " ");

                if (temp.LeftNote != null)
                {
                    queue.Enqueue(temp.LeftNote);
                }

                if (temp.RightNote != null)
                {
                    queue.Enqueue(temp.RightNote);
                }
            }
        }

        public AVLTreeNote<TKey> FindMin()
        {
            return FindMin(RootNote);
        }

        private AVLTreeNote<TKey> FindMin(AVLTreeNote<TKey> note)
        {
            if (note.LeftNote == null)
            {
                return note;
            }
            return FindMin(note.LeftNote);
        }


        public AVLTreeNote<TKey> FindMax()
        {
            return FindMax(RootNote);
        }

        private AVLTreeNote<TKey> FindMax(AVLTreeNote<TKey> note)
        {
            if (note.RightNote == null)
            {
                return note;
            }
            return FindMax(note.RightNote);
        }
    }
}

 

posted @ 2015-12-22 14:37  拉拉叟  阅读(550)  评论(0编辑  收藏  举报