網站首頁 編程語言 正文
與鏈表、堆棧和隊列不一樣,二叉查找樹不是線性數據結構,是二維數據結構。每個節點都包含一個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();
原文鏈接:https://www.cnblogs.com/darrenji/p/3897426.html
相關推薦
- 2022-08-30 MQTT - 消息隊列遙測傳輸協議
- 2022-05-18 Python繪制散點圖的教程詳解_python
- 2022-12-03 C?++迭代器iterator在string中使用方法介紹_C 語言
- 2022-04-19 Android實現一個倒計時自定義控件_Android
- 2022-05-20 Python?文件處理之open()函數_python
- 2022-09-08 詳解Dijkstra算法原理及其C++實現_C 語言
- 2023-03-16 PostgreSQL?復制表的?5?種方式詳解_PostgreSQL
- 2022-11-23 關于vba代碼運行時錯誤1004?應用程序定義或對象定義錯誤問題_VBA
- 最近更新
-
- window11 系統安裝 yarn
- 超詳細win安裝深度學習環境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權
- redisson分布式鎖中waittime的設
- maven:解決release錯誤:Artif
- restTemplate使用總結
- Spring Security之安全異常處理
- MybatisPlus優雅實現加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務發現-Nac
- Spring Security之基于HttpR
- Redis 底層數據結構-簡單動態字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應用詳解
- 聊聊消息隊列,發送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支