C#使用集合实现二叉查找树

 更新时间:2022年08月22日 08:34:42   作者:Darren Ji  
这篇文章介绍了C#使用集合实现二叉查找树的方法,文中通过示例代码介绍的非常详细。对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下

链表堆栈队列不一样,二叉查找树不是线性数据结构,是二维数据结构。每个节点都包含一个LeftNode和RightNode,二叉查找树把比节点数据项小的数据放在LeftNode,把比节点数据项大的数据放在RightNode。

关于节点的类。

    public class TreeNode<T>
    {
        public T Element { get; set; }
        public TreeNode<T>  LeftNode { get; set; }
        public TreeNode<T>  RightNode { get; set; }
        public TreeNode(T element)
        {
            this.Element = element;
            LeftNode = RightNode = null;
        }
        public override string ToString()
        {
            string nodeString = "[" + this.Element + " ";
            if (this.LeftNode == null && this.RightNode == null)
            {
                nodeString += " (叶节点) ";
            }
            if (this.LeftNode != null)
            {
                nodeString += "左节点:" + this.LeftNode.ToString();
            }
            if (this.RightNode != null)
            {
                nodeString += "右节点:" + this.RightNode.ToString();
            }
            nodeString += "]";
            return nodeString;
        }
    }
以上,把比节点数据项Element小的数据所在节点赋值给LeftNode,把比节点数据项Element大的数据所在节点赋值给RightNode。


创建一个泛型二叉树查找类,维护着一个根节点,并提供各种对节点的操作方法。

    public class BinarySearchTree<T>
    {
        public TreeNode<T> Root { get; set; }
        public BinarySearchTree()
        {
            this.Root = null;
        }
        //把某个数据项插入到二叉树
        public void Insert(T x)
        {
            this.Root = Insert(x, this.Root);
        }
        //把某个数据项从二叉树中删除
        public void Remove(T x)
        {
            this.Root = Remove(x, this.Root);
        }
        //删除二叉树中的最小数据项
        public void RemoveMin()
        {
            this.Root = RemoveMin(this.Root);
        }
        //获取二叉树中的最小数据项
        public T FindMin()
        {
            return ElemntAt(FindMin(this.Root));
        }
        //获取二叉树中的最大数据项
        public T FindMax()
        {
            return ElemntAt(FindMax(this.Root));
        }
        //获取二叉树中的某个数据项
        public T Find(T x)
        {
            return ElemntAt(Find(x, this.Root));
        }
        //清空
        public void MakeEmpty()
        {
            this.Root = null;
        }
        //判断二叉树是否为空,是否存在
        public bool IsEmpty()
        {
            return this.Root == null;
        }
        //获取某个节点的数据项
        private T ElemntAt(TreeNode<T> t)
        {
            return t == null ? default(T) : t.Element;
        }
        /// <summary>
        /// 查找节点
        /// </summary>
        /// <param name="x">要查找数据项</param>
        /// <param name="t">已存在的节点</param>
        /// <returns>返回节点</returns>
        private TreeNode<T> Find(T x, TreeNode<T> t)
        {
            while (t != null)//当没有找到匹配数据项,不断调整查找范围,即t的值
            {
                if ((x as IComparable).CompareTo(t.Element) < 0)
                {
                    t = t.LeftNode;
                }
                else if ((x as IComparable).CompareTo(t.Element) > 0)
                {
                    t = t.RightNode;
                }
                else //如果找到数据项,就返回当前t的值
                {
                    return t;
                }
            }
            return null;
        }
        //获取最小的节点,
        private TreeNode<T> FindMin(TreeNode<T> t)
        {
            if (t != null)
            {
                while (t.LeftNode != null)//不断循环二叉树的左半边树
                {
                    t = t.LeftNode; //不断设置t的值
                }
            }
            return t;
        }
        //获取最大的节点
        private TreeNode<T> FindMax(TreeNode<T> t)
        {
            if (t != null)
            {
                while (t.RightNode != null)
                {
                    t = t.RightNode;
                }
            }
            return t;
        }
        /// <summary>
        /// 插入节点
        /// </summary>
        /// <param name="x">要插入的数据项</param>
        /// <param name="t">已经存在的节点</param>
        /// <returns>返回已存在的节点</returns>
        protected TreeNode<T> Insert(T x, TreeNode<T> t)
        {
            if (t == null)
            {
                t = new TreeNode<T>(x);
            }
            else if ((x as IComparable).CompareTo(t.Element) < 0)
            {
                //等号右边的t.LeftNode是null,因此会创建一个TreeNode实例给t.LeftNode
                t.LeftNode = Insert(x, t.LeftNode);
            }
            else if ((x as IComparable).CompareTo(t.Element) > 0)
            {
                t.RightNode = Insert(x, t.RightNode);
            }
            else
            {
                throw new Exception("插入了相同元素~~");
            }
            return t;
        }
        //删除最小的节点
        //返回当前根节点
        protected TreeNode<T> RemoveMin(TreeNode<T> t)
        {
            if (t == null)
            {
                throw new Exception("节点不存在~~");
            }
            else if (t.LeftNode != null)
            {
                //通过递归不断设置t.LeftNode,直到t.LeftNode=null
                t.LeftNode = RemoveMin(t.LeftNode);
                return t;
            }
            else //当t.LeftNode=null的时候,就把t.RightNode当作最小节点返回
            {
                return t.RightNode;
            }
        }
        //删除某数据项,返回当前根节点
        protected TreeNode<T> Remove(T x, TreeNode<T> t)
        {
            if (t == null)
            {
                throw new Exception("节点不存在~~");
            }
            else if((x as IComparable).CompareTo(t.Element) < 0)
            {
                t.LeftNode = Remove(x, t.LeftNode);
            }
            else if ((x as IComparable).CompareTo(t.Element) > 0)
            {
                t.RightNode = Remove(x, t.RightNode);
            }
            else if (t.LeftNode != null && t.RightNode != null)
            {
                t.Element = FindMin(t.RightNode).Element;
                t.RightNode = RemoveMin(t.RightNode);
            }
            else
            {
                t = (t.LeftNode != null) ? t.LeftNode : t.RightNode;
            }
            return t;
        }
        public override string ToString()
        {
            return this.Root.ToString();
        }
    }

客户端创建二叉查找树的实例,并调用实例方法插入随机数据。

            BinarySearchTree<int> intTree = new BinarySearchTree<int>();
            Random r = new Random(DateTime.Now.Millisecond);
            string trace = "";
            //插入5个随机数
            for (int i = 0; i < 5; i++)
            {
                int randomInt = r.Next(1, 500);
                intTree.Insert(randomInt);
                trace += randomInt + " ";
            }
            Console.WriteLine("最大的节点:" + intTree.FindMax());
            Console.WriteLine("最小的节点:" + intTree.FindMin());
            Console.WriteLine("根节点:" + intTree.Root.Element);
            Console.WriteLine("插入节点的依次顺序是:" + trace);
            Console.WriteLine("打印树为:" + intTree);
            Console.ReadKey();

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,谢谢大家对脚本之家的支持。如果你想了解更多相关内容请查看下面相关链接

相关文章

  • C#数组应用分析

    C#数组应用分析

    C#数组应用分析...
    2007-08-08
  • C#实现插入排序算法实例

    C#实现插入排序算法实例

    这篇文章主要介绍了C#实现插入排序算法,实例分析了插入排序算法的原理与实现技巧,需要的朋友可以参考下
    2015-05-05
  • C#中多态、重载、重写区别分析

    C#中多态、重载、重写区别分析

    这篇文章主要介绍了C#中多态、重载、重写区别,采用实例较为通俗易懂的分析了多态、重载的重写的概念与用法,对于C#初学者有非常不错的借鉴价值,需要的朋友可以参考下
    2014-09-09
  • WinForm IP地址输入框控件实现

    WinForm IP地址输入框控件实现

    这篇文章主要为大家详细介绍了WinForm IP地址输入框控件的实现代码,基于VS2010模拟windows系统自带IP输入框,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2018-05-05
  • C# pictureBox用法案例详解

    C# pictureBox用法案例详解

    这篇文章主要介绍了C# pictureBox用法案例详解,本篇文章通过简要的案例,讲解了该项技术的了解与使用,以下就是详细内容,需要的朋友可以参考下
    2021-08-08
  • C#借助OpenCvSharp读取摄像头并显示的实现示例

    C#借助OpenCvSharp读取摄像头并显示的实现示例

    OpenCvSharp是一个OpenCV的.Net wrapper,应用最新的OpenCV库开发,本文主要介绍了C#借助OpenCvSharp读取摄像头并显示的实现示例,具有一定的参考价值,感兴趣的可以了解一下
    2022-05-05
  • C#软件注册码的实现代码

    C#软件注册码的实现代码

    开发软件时,当用到商业用途时,注册码与激活码就显得很重要了,现在的软件技术实在在强了,各种国内外大型软件都有注册机制,但我们学习的是技术
    2013-05-05
  • C#生成带logo的二维码

    C#生成带logo的二维码

    带logo的二维码生成分为两步骤:首先根据输入的内容生成二维码图片,然后读取本地的logo图片,通过图片处理生成带logo的二维码。本文对此进行介绍,具有很好的参考价值,下面跟着小编一起来看下吧
    2017-02-02
  • 自定义WPF窗体形状的实战记录

    自定义WPF窗体形状的实战记录

    WPF是制作界面的一大利器,下面这篇文章主要给大家介绍了关于自定义WPF窗体形状的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们一起来看看吧
    2018-09-09
  • C#实现异步编程的方法

    C#实现异步编程的方法

    这篇文章主要为大家详细介绍了C#实现异步编程的方法,什么是异步,如何实现异步编程,感兴趣的小伙伴们可以参考一下
    2017-07-07

最新评论