C#使用集合实现二叉查找树
作者: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();
以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,谢谢大家对脚本之家的支持。如果你想了解更多相关内容请查看下面相关链接