C#二叉搜索樹(shù)算法實(shí)現(xiàn)步驟和實(shí)例代碼
二叉搜索樹(shù)算法實(shí)現(xiàn)原理
二叉搜索樹(shù)(Binary Search Tree,簡(jiǎn)稱(chēng)BST)是一種節(jié)點(diǎn)有序排列的二叉樹(shù)數(shù)據(jù)結(jié)構(gòu)。它具有以下性質(zhì):
- 每個(gè)節(jié)點(diǎn)最多有兩個(gè)子節(jié)點(diǎn)。
- 對(duì)于每個(gè)節(jié)點(diǎn),其左子樹(shù)的所有節(jié)點(diǎn)值都小于該節(jié)點(diǎn)值,其右子樹(shù)的所有節(jié)點(diǎn)值都大于該節(jié)點(diǎn)值。
實(shí)現(xiàn)基本步驟和代碼示例
步驟
- 定義節(jié)點(diǎn)類(lèi):包含節(jié)點(diǎn)值、左子節(jié)點(diǎn)和右子節(jié)點(diǎn)。
- 插入節(jié)點(diǎn):遞歸或迭代地將新值插入到樹(shù)中合適的位置。
- 搜索節(jié)點(diǎn):根據(jù)節(jié)點(diǎn)值在樹(shù)中查找特定值。
- 刪除節(jié)點(diǎn):從樹(shù)中刪除特定值的節(jié)點(diǎn),并維護(hù)樹(shù)的結(jié)構(gòu)。
- 遍歷樹(shù):包括前序遍歷、中序遍歷、后序遍歷和層次遍歷等。
完整代碼示例
namespace HelloDotNetGuide.常見(jiàn)算法
{
public class 二叉搜索樹(shù)算法
{
public static void BinarySearchTreeRun()
{
var bst = new BinarySearchTree();
// 插入一些值到樹(shù)中
bst.Insert(50);
bst.Insert(30);
bst.Insert(20);
bst.Insert(40);
bst.Insert(70);
bst.Insert(60);
bst.Insert(80);
bst.Insert(750);
Console.WriteLine("中序遍歷(打印有序數(shù)組):");
bst.InorderTraversal();
Console.WriteLine("\n");
// 查找某些值
Console.WriteLine("Search for 40: " + bst.Search(40)); // 輸出: True
Console.WriteLine("Search for 25: " + bst.Search(25)); // 輸出: False
Console.WriteLine("\n");
// 刪除某個(gè)值
bst.Delete(50);
Console.WriteLine("刪除50后:");
bst.InorderTraversal();
}
}
/// <summary>
/// 定義二叉搜索樹(shù)的節(jié)點(diǎn)結(jié)構(gòu)
/// </summary>
public class TreeNode
{
public int Value;
public TreeNode Left;
public TreeNode Right;
public TreeNode(int value)
{
Value = value;
Left = null;
Right = null;
}
}
/// <summary>
/// 定義二叉搜索樹(shù)類(lèi)
/// </summary>
public class BinarySearchTree
{
private TreeNode root;
public BinarySearchTree()
{
root = null;
}
#region 插入節(jié)點(diǎn)
/// <summary>
/// 插入新值到二叉搜索樹(shù)中
/// </summary>
/// <param name="value">value</param>
public void Insert(int value)
{
if (root == null)
{
root = new TreeNode(value);
}
else
{
InsertRec(root, value);
}
}
private void InsertRec(TreeNode node, int value)
{
if (value < node.Value)
{
if (node.Left == null)
{
node.Left = new TreeNode(value);
}
else
{
InsertRec(node.Left, value);
}
}
else if (value > node.Value)
{
if (node.Right == null)
{
node.Right = new TreeNode(value);
}
else
{
InsertRec(node.Right, value);
}
}
else
{
//值已經(jīng)存在于樹(shù)中,不再插入
return;
}
}
#endregion
#region 查找節(jié)點(diǎn)
/// <summary>
/// 查找某個(gè)值是否存在于二叉搜索樹(shù)中
/// </summary>
/// <param name="value">value</param>
/// <returns></returns>
public bool Search(int value)
{
return SearchRec(root, value);
}
private bool SearchRec(TreeNode node, int value)
{
// 如果當(dāng)前節(jié)點(diǎn)為空,表示未找到目標(biāo)值
if (node == null)
{
return false;
}
// 如果找到目標(biāo)值,返回true
if (node.Value == value)
{
return true;
}
// 遞歸查找左子樹(shù)或右子樹(shù)
if (value < node.Value)
{
return SearchRec(node.Left, value);
}
else
{
return SearchRec(node.Right, value);
}
}
#endregion
#region 中序遍歷
/// <summary>
/// 中序遍歷(打印有序數(shù)組)
/// </summary>
public void InorderTraversal()
{
InorderTraversalRec(root);
}
private void InorderTraversalRec(TreeNode root)
{
if (root != null)
{
InorderTraversalRec(root.Left);
Console.WriteLine(root.Value);
InorderTraversalRec(root.Right);
}
}
#endregion
#region 刪除節(jié)點(diǎn)
/// <summary>
/// 刪除某個(gè)值
/// </summary>
/// <param name="val">val</param>
public void Delete(int val)
{
root = DeleteNode(root, val);
}
private TreeNode DeleteNode(TreeNode node, int val)
{
if (node == null)
{
return null;
}
if (val < node.Value)
{
node.Left = DeleteNode(node.Left, val);
}
else if (val > node.Value)
{
node.Right = DeleteNode(node.Right, val);
}
else
{
// 節(jié)點(diǎn)有兩個(gè)子節(jié)點(diǎn)
if (node.Left != null && node.Right != null)
{
// 使用右子樹(shù)中的最小節(jié)點(diǎn)替換當(dāng)前節(jié)點(diǎn)
TreeNode minNode = FindMin(node.Right);
node.Value = minNode.Value;
node.Right = DeleteNode(node.Right, minNode.Value);
}
// 節(jié)點(diǎn)有一個(gè)子節(jié)點(diǎn)或沒(méi)有子節(jié)點(diǎn)
else
{
TreeNode? temp = node.Left != null ? node.Left : node.Right;
node = temp;
}
}
return node;
}
/// <summary>
/// 找到樹(shù)中的最小節(jié)點(diǎn)
/// </summary>
/// <param name="node"></param>
/// <returns></returns>
private TreeNode FindMin(TreeNode node)
{
while (node.Left != null)
{
node = node.Left;
}
return node;
}
#endregion
}
}輸出結(jié)果:

數(shù)組與搜索樹(shù)的效率對(duì)比
二叉搜索樹(shù)的各項(xiàng)操作的時(shí)間復(fù)雜度都是對(duì)數(shù)階,具有穩(wěn)定且高效的性能。只有在高頻添加、低頻查找刪除數(shù)據(jù)的場(chǎng)景下,數(shù)組比二叉搜索樹(shù)的效率更高。

二叉搜索樹(shù)常見(jiàn)應(yīng)用
- 用作系統(tǒng)中的多級(jí)索引,實(shí)現(xiàn)高效的查找、插入、刪除操作。
- 作為某些搜索算法的底層數(shù)據(jù)結(jié)構(gòu)。
- 用于存儲(chǔ)數(shù)據(jù)流,以保持其有序狀態(tài)。
C#數(shù)據(jù)結(jié)構(gòu)與算法實(shí)戰(zhàn)入門(mén)指南
參考文章
- https://www.hello-algo.com/chapter_tree/binary_search_tree
- https://www.hello-algo.com/chapter_tree/binary_tree_traversal
到此這篇關(guān)于C#二叉搜索樹(shù)算法的文章就介紹到這了,更多相關(guān)C#二叉搜索樹(shù)算法內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
C#讀取本地網(wǎng)絡(luò)配置信息的方法小結(jié)
在現(xiàn)代軟件開(kāi)發(fā)中,處理網(wǎng)絡(luò)配置信息是一個(gè)常見(jiàn)需求,無(wú)論是開(kāi)發(fā)桌面、移動(dòng)還是服務(wù)器應(yīng)用程序,了解如何在C#中讀取和管理網(wǎng)絡(luò)配置信息都是非常有用的,本文將探討在C#中讀取本地網(wǎng)絡(luò)配置信息的方法,并提供幾個(gè)實(shí)際應(yīng)用場(chǎng)景的示例,需要的朋友可以參考下2024-10-10
c# checked和unchecked關(guān)鍵字的使用
C#中的checked關(guān)鍵字用于啟用整數(shù)運(yùn)算的溢出檢查,可以捕獲并拋出System.OverflowException異常,而unchecked關(guān)鍵字則禁用這種檢查,允許結(jié)果溢出,下面就來(lái)具體介紹一下2025-01-01
基于C#實(shí)現(xiàn)圖片滑動(dòng)驗(yàn)證碼的示例代碼
這篇文章主要為大家介紹了如何利用C#語(yǔ)言制作一個(gè)圖片滑動(dòng)驗(yàn)證碼,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以了解一下2022-04-04
數(shù)字金額大寫(xiě)轉(zhuǎn)換器制作代碼分享(人民幣大寫(xiě)轉(zhuǎn)換)
一個(gè)人民幣大寫(xiě)的擴(kuò)展方法,可以做成數(shù)字金額大寫(xiě)轉(zhuǎn)換器,大家參考使用吧2013-12-12
C#獲取哈希加密生成隨機(jī)安全碼的類(lèi)實(shí)例
這篇文章主要介紹了C#獲取哈希加密生成隨機(jī)安全碼的類(lèi),涉及C#哈希加密及字符串操作的相關(guān)技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下2015-03-03
用C#對(duì)ADO.NET數(shù)據(jù)庫(kù)完成簡(jiǎn)單操作的方法
用C#對(duì)ADO.NET數(shù)據(jù)庫(kù)完成簡(jiǎn)單操作的方法...2007-03-03

