二叉树查找(C#)

参考文章:

http://www.cnblogs.com/huangxincheng/archive/2012/07/21/2602375.html

http://www.cnblogs.com/xiashengwang/archive/2013/03/04/2942555.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()
        {
            BinaryTree<int, Student> binaryTree = new BinaryTree<int, Student>();
            binaryTree.Add(30, new Student() { Age = 30, Name = "30", Sex = false });//这个是用Age作为key
            binaryTree.Add(25, new Student() { Age = 25, Name = "25", Sex = false });
            binaryTree.Add(19, new Student() { Age = 19, Name = "19", Sex = true });
            binaryTree.Add(37, new Student() { Age = 37, Name = "37", Sex = false });
            binaryTree.Add(35, new Student() { Age = 35, Name = "35", Sex = true });
            binaryTree.Add(40, new Student() { Age = 40, Name = "40", Sex = false });
            binaryTree.Add(39, new Student() { Age = 39, Name = "39", Sex = true });
            binaryTree.Add(34, new Student() { Age = 34, Name = "34", Sex = true });
            binaryTree.Add(32, new Student() { Age = 32, Name = "32", Sex = false });
            binaryTree.Add(38, new Student() { Age = 38, Name = "38", Sex = true });
            binaryTree.Add(22, new Student() { Age = 22, Name = "22", Sex = true });
            binaryTree.Add(42, new Student() { Age = 42, Name = "42", Sex = true });
            binaryTree.Add(38, new Student() { Age = 38, Name = "38@", Sex = true });//注意哦 这里故意又出现个38
            binaryTree.Add(36, new Student() { Age = 36, Name = "36", Sex = false });


            Console.WriteLine("层排序遍历:");
            LevelOrder(binaryTree.RootNote);
            Console.WriteLine();

            Console.WriteLine("是否含有指定元素");
            Console.WriteLine(binaryTree.Contain(39));
            Console.WriteLine();

            Console.WriteLine("最小元素");
            Console.WriteLine(binaryTree.FindMin().TreeKey);
            Console.WriteLine();

            Console.WriteLine("最大元素");
            Console.WriteLine(binaryTree.FindMax().TreeKey);
            Console.WriteLine();

            Console.WriteLine("范围查找");
            foreach (var item in binaryTree.SearchRange(25, 35))
            {
                Console.WriteLine(item.Age);
            }
            Console.WriteLine();

            Console.WriteLine("删除指定元素");
            binaryTree.Remove(37, new Student() { Age = 37, Name = "37", Sex = false  });
            Console.WriteLine();

            Console.WriteLine("层排序遍历:");
            LevelOrder(binaryTree.RootNote);
            Console.WriteLine();

            Console.WriteLine("前序遍历:");
            PreOrder(binaryTree.RootNote);
            Console.WriteLine();

            Console.WriteLine("中序遍历:");
            InOrder(binaryTree.RootNote);
            Console.WriteLine();

            Console.WriteLine("后序遍历:");
            PostOrder(binaryTree.RootNote);
            Console.WriteLine();

            Console.Read();
        }

        private static void PreOrder(TreeNote<int, Student> treeNote)
        {
            foreach (var item in treeNote.TreeValues)
            {
                Console.Write(item.Name + " ");
            }

            if (treeNote.LeftTreeNote != null)
            {
                PreOrder(treeNote.LeftTreeNote);
            }

            if (treeNote.RightTreeNote != null)
            {
                PreOrder(treeNote.RightTreeNote);
            }
        }

        private static void InOrder(TreeNote<int, Student> treeNote)
        {
            if (treeNote.LeftTreeNote != null)
            {
                InOrder(treeNote.LeftTreeNote);
            }

            foreach (var item in treeNote.TreeValues)
            {
                Console.Write(item.Name + " ");
            }

            if (treeNote.RightTreeNote != null)
            {
                InOrder(treeNote.RightTreeNote);
            }
        }

        private static void PostOrder(TreeNote<int, Student> treeNote)
        {
            if (treeNote.LeftTreeNote != null)
            {
                PostOrder(treeNote.LeftTreeNote);
            }

            if (treeNote.RightTreeNote != null)
            {
                PostOrder(treeNote.RightTreeNote);
            }

            foreach (var item in treeNote.TreeValues)
            {
                Console.Write(item.Name + " ");
            }
        }

        private static void LevelOrder(TreeNote<int, Student> treeNote)
        {
            Queue queue = new Queue();
            queue.Enqueue(treeNote);
            while (queue.Count > 0)
            {
                var treeNoteTemp = (TreeNote<int, Student>)queue.Dequeue();

                foreach (var item in treeNoteTemp.TreeValues)
                {
                    Console.Write(item.Name + " ");
                }

                if (treeNoteTemp.LeftTreeNote != null)
                {
                    queue.Enqueue(treeNoteTemp.LeftTreeNote);
                }

                if (treeNoteTemp.RightTreeNote != null)
                {
                    queue.Enqueue(treeNoteTemp.RightTreeNote);
                }
            }
        }
    }

    public class Student : IEquatable<Student>//由于后面代码的treeNote.TreeValues.Remove(treeValue);  因为HashCode不同无法删除 这里需要重写GetHashCode()
    {
        public string Name { get; set; }
        public bool Sex { get; set; }
        public int Age { get; set; }

        public bool Equals(Student other)
        {
            return this.Name == other.Name &&
                this.Sex == other.Sex &&
                this.Age == other.Age;
        }
        public override bool Equals(object obj)
        {
            if (obj == null) return base.Equals(obj);

            if (obj is Student)
                return Equals(obj as Student);
            else
                throw new InvalidCastException("the 'obj' Argument is not a Student object");
        }
        public override int GetHashCode()
        {
            return Name.GetHashCode()^Sex.GetHashCode()^Age.GetHashCode();//return object's hashcode
        }
    }


    public class TreeNote<TKey, TValue> where TKey : IComparable
    {
        public TreeNote(TKey treeKey, TValue treeValue)
        {
            TreeKey = treeKey;
            TreeValues = new HashSet<TValue>();
            TreeValues.Add(treeValue);
        }

        public TKey TreeKey { get; set; }
        public HashSet<TValue> TreeValues { get; set; }
        public TreeNote<TKey, TValue> LeftTreeNote { get; set; }
        public TreeNote<TKey, TValue> RightTreeNote { get; set; }
    }

    public class BinaryTree<TKey, TValue> where TKey : IComparable
    {
        public TreeNote<TKey, TValue> RootNote = null;//根节点

        public void Add(TKey treeKey, TValue treeValue)
        {
            RootNote = Add(treeKey, treeValue, RootNote);
        }

        private TreeNote<TKey, TValue> Add(TKey treeKey, TValue treeValue, TreeNote<TKey, TValue> treeNote)
        {
            if (treeNote == null)
            {
                return new TreeNote<TKey, TValue>(treeKey, treeValue);
            }

            if (treeNote.TreeKey.CompareTo(treeKey) > 0)
            {
                treeNote.LeftTreeNote = Add(treeKey, treeValue, treeNote.LeftTreeNote);
            }

            if (treeNote.TreeKey.CompareTo(treeKey) < 0)
            {
                treeNote.RightTreeNote = Add(treeKey, treeValue, treeNote.RightTreeNote);
            }

            if (treeNote.TreeKey.CompareTo(treeKey) == 0)
            {
                treeNote.TreeValues.Add(treeValue);
            }

            return treeNote;
        }

        public bool Contain(TKey treeKey)
        {
            return Contain(treeKey, RootNote);
        }

        private bool Contain(TKey treeKey, TreeNote<TKey, TValue> treeNote)
        {
            if (treeNote == null)
            {
                return false;
            }

            if (treeNote.TreeKey.CompareTo(treeKey) > 0)
            {
                return Contain(treeKey, treeNote.LeftTreeNote);
            }

            if (treeNote.TreeKey.CompareTo(treeKey) < 0)
            {
                return Contain(treeKey, treeNote.RightTreeNote);
            }

            return treeNote.TreeKey.CompareTo(treeKey) == 0;
        }

        public HashSet<TValue> SearchRange(TKey minTreeKey, TKey maxTreeKey)
        {
            return SearchRange(minTreeKey, maxTreeKey, RootNote, new HashSet<TValue>());
        }

        private HashSet<TValue> SearchRange(TKey minTreeKey, TKey maxTreeKey, TreeNote<TKey, TValue> treeNote, HashSet<TValue> attach)
        {
            if (treeNote == null)
            {
                return attach;
            }

            if (treeNote.TreeKey.CompareTo(minTreeKey) > 0)
            {
                SearchRange(minTreeKey, maxTreeKey, treeNote.LeftTreeNote, attach);
            }

            if (treeNote.TreeKey.CompareTo(minTreeKey) >= 0 && treeNote.TreeKey.CompareTo(maxTreeKey) <= 0)
            {
                foreach (var item in treeNote.TreeValues)
                {
                    attach.Add(item);
                }
            }

            if (treeNote.TreeKey.CompareTo(maxTreeKey) < 0)
            {
                SearchRange(minTreeKey, maxTreeKey, treeNote.RightTreeNote, attach);
            }

            return attach;
        }

        public TreeNote<TKey, TValue> FindMin()
        {
            return FindMin(RootNote);
        }

        private TreeNote<TKey, TValue> FindMin(TreeNote<TKey, TValue> treeNote)
        {
            if (treeNote == null)
            {
                return null;
            }

            if (treeNote.LeftTreeNote == null)
            {
                return treeNote;
            }
            else
            {
                return FindMin(treeNote.LeftTreeNote);
            }
        }

        public TreeNote<TKey, TValue> FindMax()
        {
            return FindMax(RootNote);
        }

        private TreeNote<TKey, TValue> FindMax(TreeNote<TKey, TValue> treeNote)
        {
            if (treeNote == null)
            {
                return null;
            }

            if (treeNote.RightTreeNote == null)
            {
                return treeNote;
            }
            else
            {
                return FindMax(treeNote.RightTreeNote);
            }
        }

        public void Remove(TKey treeKey, TValue treeValue)
        {
            Remove(treeKey, treeValue, RootNote, true);
        }

        private TreeNote<TKey, TValue> Remove(TKey treeKey, TValue treeValue, TreeNote<TKey, TValue> treeNote, bool isAccordingToTreeValues)
        {
            if (treeNote == null)
            {
                return null;
            }

            if (treeNote.TreeKey.CompareTo(treeKey) > 0)
            {
                treeNote.LeftTreeNote = Remove(treeKey, treeValue, treeNote.LeftTreeNote, isAccordingToTreeValues);
            }

            if (treeNote.TreeKey.CompareTo(treeKey) < 0)
            {
                treeNote.RightTreeNote = Remove(treeKey, treeValue, treeNote.RightTreeNote, isAccordingToTreeValues);
            }

            if (treeNote.TreeKey.CompareTo(treeKey) == 0)
            {
                if (treeNote.TreeValues.Count > 1 && isAccordingToTreeValues)
                {
                    treeNote.TreeValues.Remove(treeValue);
                }
                else
                {
                    if (treeNote.LeftTreeNote == null || treeNote.RightTreeNote == null)
                    {
                        treeNote = treeNote.LeftTreeNote == null ? treeNote.RightTreeNote : treeNote.LeftTreeNote;
                    }
                    else //有一对子元素
                    {
                        var treeNoteTemp = FindMin(treeNote.RightTreeNote);//右子节点下的最小子节点替换当前节点
                        treeNote.TreeKey = treeNoteTemp.TreeKey;
                        treeNote.TreeValues = treeNoteTemp.TreeValues;

                        treeNote.RightTreeNote = Remove(treeNoteTemp.TreeKey, treeValue, treeNote.RightTreeNote, false);
                    }
                }
            }
            return treeNote;
        }
    }
}

 

posted @ 2015-12-15 18:26  拉拉叟  阅读(543)  评论(0编辑  收藏  举报