二叉查找树(C#) 代码实现(自己学习过程的产物,仅供自己玩) /// <summary> /// 二叉查找树 /// </summary> public class BinarySearchTree { #region 构造函数 public BinarySearchTree(BinarySearchTreeNode root) { this.Root = root; } public BinarySearchTree(long[] nodeValues) { if (nodeValues == null || nodeValues.Length == 0) return; this.Root = new BinarySearchTreeNode() { Value = nodeValues[0] }; for (int i = 1; i < nodeValues.Length; i++) { AddNode(nodeValues[i]); } } #endregion #region 属性区域 public BinarySearchTreeNode Root { get; set; } #endregion #region 函数区域 /// <summary> /// 获取具有最大值的节点 /// </summary> /// <returns>具有最大值的节点</returns> public BinarySearchTreeNode GetMaxNode() { return GetMaxNode(Root); } /// <summary> /// 获取具有最大值的节点 /// </summary> /// <returns>具有最大值的节点</returns> public BinarySearchTreeNode GetMaxNode(BinarySearchTreeNode root) { BinarySearchTreeNode maxNode = root; BinarySearchTreeNode rightNode = root.Right; while (rightNode != null) { maxNode = rightNode; rightNode = rightNode.Right; } return maxNode; } /// <summary> /// 获取二叉查找树的最大值 /// </summary> /// <returns>二叉查找树的最大值</returns> public long GetMax() { BinarySearchTreeNode node = GetMaxNode(Root); if (node == null) throw new Exception("最大值不存在"); return node.Value; } /// <summary> /// 获取具有最小值的节点 /// </summary> /// <returns>具有最小值的节点</returns> public BinarySearchTreeNode GetMinNode() { return GetMinNode(Root); } /// <summary> /// 获取具有最小值的节点 /// </summary> /// <returns>具有最小值的节点</returns> public BinarySearchTreeNode GetMinNode(BinarySearchTreeNode root) { BinarySearchTreeNode minNode = root; BinarySearchTreeNode leftNode = root.Left; while (leftNode != null) { minNode = leftNode; leftNode = minNode.Left; } return minNode; } /// <summary> /// 获取二叉查找树的最小值 /// </summary> /// <returns>二叉查找树的最小值</returns> public long GetMin() { BinarySearchTreeNode node = GetMinNode(); if (node == null) throw new Exception("最小值不存在"); return node.Value; } /// <summary> /// 获取指定节点的前驱节点 /// </summary> /// <param name="node">要获取前驱节点的节点</param> /// <returns>指定节点的前驱节点</returns> public BinarySearchTreeNode GetPredecessor(BinarySearchTreeNode node) { if (node == null) return null; // 左子树不为空,则节点的前驱为左子树的最大值节点 if (node.Left != null) { return GetMaxNode(node.Left); } else { // 左子树为空,则向上查找,直到某个是其父节点的左儿子的节点为止(反过来当前节点是要求节点的后继节点,可以想象下位置,右子树最小节点) BinarySearchTreeNode parent = node.Parent; while (parent != null && parent.Left == node) { node = parent; parent = parent.Parent; } return parent; } } /// <summary> /// 获取指定节点的后继节点 /// </summary> /// <param name="node">要获取后继节点的节点</param> /// <returns>指定节点的</returns> public BinarySearchTreeNode GetSuccessor(BinarySearchTreeNode node) { if (node == null) return null; // 右子树不为空,则节点的后继为右子树的最小值节点 if (node.Right != null) { return GetMinNode(node.Right); } else { // 右子树为空,则向上查找,直到某个是其父节点的右儿子的节点为止(反过来当前节点是要求节点的前驱节点,可以想象下位置,左子树最大节点) BinarySearchTreeNode parent = node.Parent; while (parent != null && parent.Right == node) { node = parent; parent = parent.Parent; } return parent; } } /// <summary> /// 搜索具有指定值的节点 /// </summary> /// <param name="value">指定值</param> /// <returns>具有指定值的节点</returns> public BinarySearchTreeNode Search(long value) { return Search(Root, value); } /// <summary> /// 搜索具有指定值的节点 /// </summary> /// <param name="value">指定值</param> /// <returns>具有指定值的节点</returns> private BinarySearchTreeNode Search(BinarySearchTreeNode parent, long value) { if (parent == null) return null; if (parent.Value == value) return parent; BinarySearchTreeNode searchedNode = null; if (value < parent.Value) { // 向左搜索 searchedNode = Search(parent.Left, value); } if (value > parent.Value) { // 向右搜索 searchedNode = Search(parent.Right, value); } return searchedNode; } /// <summary> /// 添加一个节点到二叉查找树(并保持二叉查找树的特性) /// </summary> /// <param name="node">要添加的节点</param> public void AddNode(long node) { if (Root.Value >= node) { // 向左子树添加 if (Root.Left == null) { // 添加 Root.Left = new BinarySearchTreeNode() { Parent = Root, Left = null, Right = null, Value = node }; return; } AddNode(node, Root.Left); } if (Root.Value < node) { // 向右子树添加 if (Root.Right == null) { // 添加 Root.Right = new BinarySearchTreeNode() { Parent = Root, Left = null, Right = null, Value = node }; return; } AddNode(node, Root.Right); } } /// <summary> /// 向指定的子树中添加节点 /// </summary> /// <param name="node">要添加节点</param> /// <param name="parent">子树</param> private void AddNode(long node, BinarySearchTreeNode parent) { if (parent.Value >= node) { // 向左子树添加 if (parent.Left == null) { // 添加 parent.Left = new BinarySearchTreeNode() { Parent = parent, Left = null, Right = null, Value = node }; return; } AddNode(node, parent.Left); } if (parent.Value < node) { // 向右子树添加 if (parent.Right == null) { // 添加 parent.Right = new BinarySearchTreeNode() { Parent = parent, Left = null, Right = null, Value = node }; return; } AddNode(node, parent.Right); } } /// <summary> /// 删除指定的节点(并保持二叉查找树的特性) /// </summary> /// <param name="node">要删除的节点</param> public void DeleteNode(BinarySearchTreeNode node) { if (node == null) throw new ArgumentNullException("参数node为空"); if (node.Left == null && node.Right == null) { // 当前节点为叶子节点,则直接删除 BinarySearchTreeNode parent = node.Parent; if (parent.Value >= node.Value) { parent.Left = null; } else { parent.Right = null; } } if ((node.Left != null && node.Right == null) || (node.Left == null && node.Right != null)) { // 只有一个子节点的节点,则直接追加该子节点 BinarySearchTreeNode parent = node.Parent; if (parent.Value >= node.Value) { parent.Left = node.Left == null ? node.Right : node.Left; parent.Left.Parent = parent; } else { parent.Right = node.Left == null ? node.Right : node.Left; parent.Right.Parent = parent; } } if (node.Left != null && node.Right != null) { // 备份当前节点 BinarySearchTreeNode copyNode = node.Clone() as BinarySearchTreeNode; // 删除后继节点 BinarySearchTreeNode postNode = GetSuccessor(node); DeleteNode(postNode); // 用后继节点代替当前节点 postNode.Left = node.Left; postNode.Right = node.Right; postNode.Parent = node.Parent; postNode.Tag = node.Tag; postNode.Value = node.Value; } } #endregion } /// <summary> /// 二叉查找树节点 /// </summary> public class BinarySearchTreeNode : ICloneable { #region 构造函数 public BinarySearchTreeNode() { } public BinarySearchTreeNode(BinarySearchTreeNode parent, BinarySearchTreeNode left, BinarySearchTreeNode right, long value, object tag) { this.Parent = parent; this.Left = left; this.Right = right; this.Value = value; this.Tag = tag; } #endregion #region 属性节点 /// <summary> /// 父节点 /// </summary> public BinarySearchTreeNode Parent { get; set; } /// <summary> /// 左儿子 /// </summary> public BinarySearchTreeNode Left { get; set; } /// <summary> /// 右儿子 /// </summary> public BinarySearchTreeNode Right { get; set; } /// <summary> /// 节点值 /// </summary> public long Value { get; set; } /// <summary> /// 存储其他值 /// </summary> public object Tag { get; set; } #endregion #region ICloneable 成员 public object Clone() { return new BinarySearchTreeNode() { Left = this.Left, Right = this.Right, Parent = this.Parent, Tag = this.Tag, Value = this.Value }; } #endregion }