与链表、堆栈和队列不一样,二叉查找树不是线性数据结构,是二维数据结构。每个节点都包含一个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.LeftNodet.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=nullt.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();
参考资料:
Binary Search Trees (BSTs) in C#
“了解集合本质必须要知晓的概念”系列包括:
了解集合本质必须要知晓的概念01-链表
了解集合本质必须要知晓的概念02-堆栈
了解集合本质必须要知晓的概念03-队列
了解集合本质必须要知晓的概念04-二叉查找树
了解集合本质必须要知晓的概念04-二叉查找树
时间: 2024-10-10 03:01:41