二叉尋找樹(C#)
代碼實現(自己學習過程的產物,僅供自己玩)
/// <summary><br /> /// 二叉尋找樹<br /> /// </summary><br /> public class BinarySearchTree<br /> {<br /> #region 建構函式</p><p> public BinarySearchTree(BinarySearchTreeNode root)<br /> {<br /> this.Root = root;<br /> }</p><p> public BinarySearchTree(long[] nodeValues)<br /> {<br /> if (nodeValues == null || nodeValues.Length == 0) return;</p><p> this.Root = new BinarySearchTreeNode()<br /> {<br /> Value = nodeValues[0]<br /> };</p><p> for (int i = 1; i < nodeValues.Length; i++)<br /> {<br /> AddNode(nodeValues[i]);<br /> }<br /> }</p><p> #endregion</p><p> #region 屬性地區</p><p> public BinarySearchTreeNode Root<br /> {<br /> get;<br /> set;<br /> }</p><p> #endregion</p><p> #region 函數地區</p><p> /// <summary><br /> /// 擷取具有最大值的節點<br /> /// </summary><br /> /// <returns>具有最大值的節點</returns><br /> public BinarySearchTreeNode GetMaxNode()<br /> {<br /> return GetMaxNode(Root);<br /> }</p><p> /// <summary><br /> /// 擷取具有最大值的節點<br /> /// </summary><br /> /// <returns>具有最大值的節點</returns><br /> public BinarySearchTreeNode GetMaxNode(BinarySearchTreeNode root)<br /> {<br /> BinarySearchTreeNode maxNode = root;<br /> BinarySearchTreeNode rightNode = root.Right;<br /> while (rightNode != null)<br /> {<br /> maxNode = rightNode;<br /> rightNode = rightNode.Right;<br /> }</p><p> return maxNode;<br /> }</p><p> /// <summary><br /> /// 擷取二叉尋找樹的最大值<br /> /// </summary><br /> /// <returns>二叉尋找樹的最大值</returns><br /> public long GetMax()<br /> {<br /> BinarySearchTreeNode node = GetMaxNode(Root);<br /> if (node == null) throw new Exception("最大值不存在");</p><p> return node.Value;<br /> }</p><p> /// <summary><br /> /// 擷取具有最小值的節點<br /> /// </summary><br /> /// <returns>具有最小值的節點</returns><br /> public BinarySearchTreeNode GetMinNode()<br /> {<br /> return GetMinNode(Root);<br /> }</p><p> /// <summary><br /> /// 擷取具有最小值的節點<br /> /// </summary><br /> /// <returns>具有最小值的節點</returns><br /> public BinarySearchTreeNode GetMinNode(BinarySearchTreeNode root)<br /> {<br /> BinarySearchTreeNode minNode = root;<br /> BinarySearchTreeNode leftNode = root.Left;<br /> while (leftNode != null)<br /> {<br /> minNode = leftNode;<br /> leftNode = minNode.Left;<br /> }</p><p> return minNode;<br /> }</p><p> /// <summary><br /> /// 擷取二叉尋找樹的最小值<br /> /// </summary><br /> /// <returns>二叉尋找樹的最小值</returns><br /> public long GetMin()<br /> {<br /> BinarySearchTreeNode node = GetMinNode();<br /> if (node == null) throw new Exception("最小值不存在");</p><p> return node.Value;<br /> }</p><p> /// <summary><br /> /// 擷取指定節點的前驅節點<br /> /// </summary><br /> /// <param name="node">要擷取前驅節點的節點</param><br /> /// <returns>指定節點的前驅節點</returns><br /> public BinarySearchTreeNode GetPredecessor(BinarySearchTreeNode node)<br /> {<br /> if (node == null) return null;</p><p> // 左子樹不為空白,則節點的前驅為左子樹的最大值節點<br /> if (node.Left != null)<br /> {<br /> return GetMaxNode(node.Left);<br /> }<br /> else<br /> {<br /> // 左子樹為空白,則向上尋找,直到某個是其父節點的左兒子的節點為止(反過來當前節點是要求節點的後繼節點,可以想象下位置,右子樹最小節點)<br /> BinarySearchTreeNode parent = node.Parent;<br /> while (parent != null && parent.Left == node)<br /> {<br /> node = parent;<br /> parent = parent.Parent;<br /> }</p><p> return parent;<br /> }<br /> }</p><p> /// <summary><br /> /// 擷取指定節點的後繼節點<br /> /// </summary><br /> /// <param name="node">要擷取後繼節點的節點</param><br /> /// <returns>指定節點的</returns><br /> public BinarySearchTreeNode GetSuccessor(BinarySearchTreeNode node)<br /> {<br /> if (node == null) return null;</p><p> // 右子樹不為空白,則節點的後繼為右子樹的最小值節點<br /> if (node.Right != null)<br /> {<br /> return GetMinNode(node.Right);<br /> }<br /> else<br /> {<br /> // 右子樹為空白,則向上尋找,直到某個是其父節點的右兒子的節點為止(反過來當前節點是要求節點的前驅節點,可以想象下位置,左子樹最大節點)<br /> BinarySearchTreeNode parent = node.Parent;<br /> while (parent != null && parent.Right == node)<br /> {<br /> node = parent;<br /> parent = parent.Parent;<br /> }</p><p> return parent;<br /> }<br /> }</p><p> /// <summary><br /> /// 搜尋具有指定值的節點<br /> /// </summary><br /> /// <param name="value">指定值</param><br /> /// <returns>具有指定值的節點</returns><br /> public BinarySearchTreeNode Search(long value)<br /> {<br /> return Search(Root, value);<br /> }</p><p> /// <summary><br /> /// 搜尋具有指定值的節點<br /> /// </summary><br /> /// <param name="value">指定值</param><br /> /// <returns>具有指定值的節點</returns><br /> private BinarySearchTreeNode Search(BinarySearchTreeNode parent, long value)<br /> {<br /> if (parent == null) return null;<br /> if (parent.Value == value) return parent;</p><p> BinarySearchTreeNode searchedNode = null;<br /> if (value < parent.Value)<br /> {<br /> // 向左搜尋<br /> searchedNode = Search(parent.Left, value);<br /> }<br /> if (value > parent.Value)<br /> {<br /> // 向右搜尋<br /> searchedNode = Search(parent.Right, value);<br /> }</p><p> return searchedNode;<br /> }</p><p> /// <summary><br /> /// 添加一個節點到二叉尋找樹(並保持二叉尋找樹的特性)<br /> /// </summary><br /> /// <param name="node">要添加的節點</param><br /> public void AddNode(long node)<br /> {<br /> if (Root.Value >= node)<br /> {<br /> // 向左子樹添加<br /> if (Root.Left == null)<br /> {<br /> // 添加<br /> Root.Left = new BinarySearchTreeNode()<br /> {<br /> Parent = Root,<br /> Left = null,<br /> Right = null,<br /> Value = node<br /> };<br /> return;<br /> }<br /> AddNode(node, Root.Left);<br /> }<br /> if (Root.Value < node)<br /> {<br /> // 向右子樹添加<br /> if (Root.Right == null)<br /> {<br /> // 添加<br /> Root.Right = new BinarySearchTreeNode()<br /> {<br /> Parent = Root,<br /> Left = null,<br /> Right = null,<br /> Value = node<br /> };<br /> return;<br /> }<br /> AddNode(node, Root.Right);<br /> }<br /> }</p><p> /// <summary><br /> /// 向指定的子樹中添加節點<br /> /// </summary><br /> /// <param name="node">要添加節點</param><br /> /// <param name="parent">子樹</param><br /> private void AddNode(long node, BinarySearchTreeNode parent)<br /> {<br /> if (parent.Value >= node)<br /> {<br /> // 向左子樹添加<br /> if (parent.Left == null)<br /> {<br /> // 添加<br /> parent.Left = new BinarySearchTreeNode()<br /> {<br /> Parent = parent,<br /> Left = null,<br /> Right = null,<br /> Value = node<br /> };<br /> return;<br /> }<br /> AddNode(node, parent.Left);<br /> }<br /> if (parent.Value < node)<br /> {<br /> // 向右子樹添加<br /> if (parent.Right == null)<br /> {<br /> // 添加<br /> parent.Right = new BinarySearchTreeNode()<br /> {<br /> Parent = parent,<br /> Left = null,<br /> Right = null,<br /> Value = node<br /> };<br /> return;<br /> }<br /> AddNode(node, parent.Right);<br /> }<br /> }</p><p> /// <summary><br /> /// 刪除指定的節點(並保持二叉尋找樹的特性)<br /> /// </summary><br /> /// <param name="node">要刪除的節點</param><br /> public void DeleteNode(BinarySearchTreeNode node)<br /> {<br /> if (node == null)<br /> throw new ArgumentNullException("參數node為空白");</p><p> if (node.Left == null && node.Right == null)<br /> {<br /> // 當前節點為葉子節點,則直接刪除<br /> BinarySearchTreeNode parent = node.Parent;<br /> if (parent.Value >= node.Value)<br /> {<br /> parent.Left = null;<br /> }<br /> else<br /> {<br /> parent.Right = null;<br /> }<br /> }</p><p> if ((node.Left != null && node.Right == null) || (node.Left == null && node.Right != null))<br /> {<br /> // 只有一個子節點的節點,則直接追加該子節點<br /> BinarySearchTreeNode parent = node.Parent;<br /> if (parent.Value >= node.Value)<br /> {<br /> parent.Left = node.Left == null ? node.Right : node.Left;<br /> parent.Left.Parent = parent;<br /> }<br /> else<br /> {<br /> parent.Right = node.Left == null ? node.Right : node.Left;<br /> parent.Right.Parent = parent;<br /> }<br /> }</p><p> if (node.Left != null && node.Right != null)<br /> {<br /> // 備份當前節點<br /> BinarySearchTreeNode copyNode = node.Clone() as BinarySearchTreeNode;</p><p> // 刪除後繼節點<br /> BinarySearchTreeNode postNode = GetSuccessor(node);<br /> DeleteNode(postNode);</p><p> // 用後繼節點代替當前節點<br /> postNode.Left = node.Left;<br /> postNode.Right = node.Right;<br /> postNode.Parent = node.Parent;<br /> postNode.Tag = node.Tag;<br /> postNode.Value = node.Value;<br /> }<br /> }</p><p> #endregion<br /> }</p><p> /// <summary><br /> /// 二叉尋找樹節點<br /> /// </summary><br /> public class BinarySearchTreeNode : ICloneable<br /> {<br /> #region 建構函式</p><p> public BinarySearchTreeNode() { }</p><p> public BinarySearchTreeNode(BinarySearchTreeNode parent, BinarySearchTreeNode left, BinarySearchTreeNode right, long value, object tag)<br /> {<br /> this.Parent = parent;<br /> this.Left = left;<br /> this.Right = right;<br /> this.Value = value;<br /> this.Tag = tag;<br /> }</p><p> #endregion</p><p> #region 屬性節點</p><p> /// <summary><br /> /// 父節點<br /> /// </summary><br /> public BinarySearchTreeNode Parent<br /> {<br /> get;<br /> set;<br /> }</p><p> /// <summary><br /> /// 左兒子<br /> /// </summary><br /> public BinarySearchTreeNode Left<br /> {<br /> get;<br /> set;<br /> }</p><p> /// <summary><br /> /// 右兒子<br /> /// </summary><br /> public BinarySearchTreeNode Right<br /> {<br /> get;<br /> set;<br /> }</p><p> /// <summary><br /> /// 節點值<br /> /// </summary><br /> public long Value<br /> {<br /> get;<br /> set;<br /> }</p><p> /// <summary><br /> /// 儲存其他值<br /> /// </summary><br /> public object Tag<br /> {<br /> get;<br /> set;<br /> }</p><p> #endregion</p><p> #region ICloneable 成員</p><p> public object Clone()<br /> {<br /> return new BinarySearchTreeNode()<br /> {<br /> Left = this.Left,<br /> Right = this.Right,<br /> Parent = this.Parent,<br /> Tag = this.Tag,<br /> Value = this.Value<br /> };<br /> }</p><p> #endregion<br /> }