C#二叉搜索樹算法實(shí)現(xiàn)步驟和實(shí)例代碼
二叉搜索樹算法實(shí)現(xiàn)原理
二叉搜索樹(Binary Search Tree,簡稱BST)是一種節(jié)點(diǎn)有序排列的二叉樹數(shù)據(jù)結(jié)構(gòu)。它具有以下性質(zhì):
- 每個節(jié)點(diǎn)最多有兩個子節(jié)點(diǎn)。
- 對于每個節(jié)點(diǎn),其左子樹的所有節(jié)點(diǎn)值都小于該節(jié)點(diǎn)值,其右子樹的所有節(jié)點(diǎn)值都大于該節(jié)點(diǎn)值。
實(shí)現(xiàn)基本步驟和代碼示例
步驟
- 定義節(jié)點(diǎn)類:包含節(jié)點(diǎn)值、左子節(jié)點(diǎn)和右子節(jié)點(diǎn)。
- 插入節(jié)點(diǎn):遞歸或迭代地將新值插入到樹中合適的位置。
- 搜索節(jié)點(diǎn):根據(jù)節(jié)點(diǎn)值在樹中查找特定值。
- 刪除節(jié)點(diǎn):從樹中刪除特定值的節(jié)點(diǎn),并維護(hù)樹的結(jié)構(gòu)。
- 遍歷樹:包括前序遍歷、中序遍歷、后序遍歷和層次遍歷等。
完整代碼示例
namespace HelloDotNetGuide.常見算法
{
public class 二叉搜索樹算法
{
public static void BinarySearchTreeRun()
{
var bst = new BinarySearchTree();
// 插入一些值到樹中
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");
// 刪除某個值
bst.Delete(50);
Console.WriteLine("刪除50后:");
bst.InorderTraversal();
}
}
/// <summary>
/// 定義二叉搜索樹的節(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>
/// 定義二叉搜索樹類
/// </summary>
public class BinarySearchTree
{
private TreeNode root;
public BinarySearchTree()
{
root = null;
}
#region 插入節(jié)點(diǎn)
/// <summary>
/// 插入新值到二叉搜索樹中
/// </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)存在于樹中,不再插入
return;
}
}
#endregion
#region 查找節(jié)點(diǎn)
/// <summary>
/// 查找某個值是否存在于二叉搜索樹中
/// </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;
}
// 遞歸查找左子樹或右子樹
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>
/// 刪除某個值
/// </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)有兩個子節(jié)點(diǎn)
if (node.Left != null && node.Right != null)
{
// 使用右子樹中的最小節(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)有一個子節(jié)點(diǎn)或沒有子節(jié)點(diǎn)
else
{
TreeNode? temp = node.Left != null ? node.Left : node.Right;
node = temp;
}
}
return node;
}
/// <summary>
/// 找到樹中的最小節(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ù)組與搜索樹的效率對比
二叉搜索樹的各項(xiàng)操作的時間復(fù)雜度都是對數(shù)階,具有穩(wěn)定且高效的性能。只有在高頻添加、低頻查找刪除數(shù)據(jù)的場景下,數(shù)組比二叉搜索樹的效率更高。

二叉搜索樹常見應(yīng)用
- 用作系統(tǒng)中的多級索引,實(shí)現(xiàn)高效的查找、插入、刪除操作。
- 作為某些搜索算法的底層數(shù)據(jù)結(jié)構(gòu)。
- 用于存儲數(shù)據(jù)流,以保持其有序狀態(tài)。
C#數(shù)據(jù)結(jié)構(gòu)與算法實(shí)戰(zhàn)入門指南
參考文章
- https://www.hello-algo.com/chapter_tree/binary_search_tree
- https://www.hello-algo.com/chapter_tree/binary_tree_traversal
到此這篇關(guān)于C#二叉搜索樹算法的文章就介紹到這了,更多相關(guān)C#二叉搜索樹算法內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Unity實(shí)現(xiàn)卡片循環(huán)滾動效果的示例詳解
這篇文章主要為大家詳細(xì)介紹了如何利用Unity實(shí)現(xiàn)卡片循環(huán)滾動的效果,文中的實(shí)現(xiàn)步驟講解詳細(xì),具有一定的借鑒價值,需要的可以參考一下2022-12-12
C#使用DateTime.Now靜態(tài)屬性動態(tài)獲得系統(tǒng)當(dāng)前日期和時間
本文主要介紹了C#使用DateTime.Now靜態(tài)屬性動態(tài)獲得系統(tǒng)當(dāng)前日期和時間,DateTime結(jié)構(gòu)的Now靜態(tài)屬性只是得到一個系統(tǒng)時間對象,該時間對象不會隨著系統(tǒng)時間的變化而變化,如果要動態(tài)顯示系統(tǒng)時間,可以使用計(jì)時器間隔地獲取系統(tǒng)時間對象并顯示,感興趣的可以了解一下2024-01-01

