二叉搜索樹的實現與測試

目錄

1.二叉搜索樹的結構與特性

2.二叉搜索樹的實現

(1)節點

(2)功能實現

插入:

刪除:

查找:

打印:

3.測試

插入刪除:

查找:

4.變種測試,即帶value值

單詞查找:

個數統計:


1.二叉搜索樹的結構與特性

BSTree(二叉搜索樹)是一個神奇的數據結構,其的特點是,左子樹的所有值比根小,而右子樹的所有值比根大

根據這種特性,我們可以從該結構中快速的搜索一個數的存在,速度則為樹的高度次。

類似于這樣的數。

2.二叉搜索樹的實現

(1)節點

因為是樹的結構,所以肯定少不了節點

    template<class K>struct BSTreeNode{BSTreeNode<K>* _left;BSTreeNode<K>* _right;K _key;BSTreeNode(const K& key):_left(nullptr), _right(nullptr), _key(key){}};

利用初始化列表將其進行初始化。

(2)功能實現

該結構應該有插入、刪除功能,因為叫搜索樹,所有肯定有查找功能

插入:
    bool Insert(const K& key){if (_root == nullptr){_root = new Node(key);return true;}Node* parent = nullptr;Node* cur = _root;while (cur){if (key < cur->_key){parent = cur;cur = cur->_left; }else if (key > cur->_key){parent = cur;cur = cur->_right;}else{return false;}}cur = new Node(key);if (parent->_key > key)parent->_left = cur;elseparent->_right = cur;return true;}

插入功能的實現邏輯很簡單,只需要遵循根比左子樹大,比右子樹小即可。

刪除:
bool Erase(const K& key){Node* cur = _root;Node* parent = cur;while (cur){if (key < cur->_key){parent = cur;cur = cur->_left;}else if (key > cur->_key){parent = cur;cur = cur->_right;}else{if (cur->_left == nullptr){if (parent == cur)_root = cur->_right;else{if (parent->_left == cur){parent->_left = cur->_right;}else{parent->_right = cur->_right;}}}else if(cur->_right == nullptr){if (parent == cur)_root = cur->_left;else{if (parent->_left == cur){parent->_left = cur->_left;}else{parent->_right = cur->_left;}}}else{Node* MinRight = cur->_left; parent = cur;while (MinRight->_right){parent = MinRight;MinRight = MinRight->_right;}cur->_key = MinRight->_key;if(parent->_right == MinRight)parent->_right = MinRight->_left;elseparent->_left = MinRight->_left;}return true;}}return false;}

刪除功能的邏輯就比較復雜了,分三種情況討論,一種是cur有兩個子節點,二是cur有一個子節點,三是cur無子節點。

最后可以將二、三中情況合并處理,因為都存在nullptr。

查找:
    bool find(const K& key){Node* cur = _root;while (cur){if (key < cur->_key){cur = cur->_left;}else if (key > cur->_key){cur = cur->_right;}else{return true;}}return false;}

查找邏輯簡單,無須多說,只需根據二叉搜索樹的特性畫圖即可。

同時加入一個打印功能方便觀察:

打印:
        void Inorder(){_Inorder(_root);cout << endl;}void _Inorder(Node* _root){if (_root == nullptr){return;}_Inorder(_root->_left);cout << _root->_key << ' ';_Inorder(_root->_right);}

創建一個_Inorder的原因是方便讀取底層的_root元素,然后中序遍歷即可

3.測試

插入刪除:

查找:

1表示存在,0表示不存在

4.變種測試,即帶value值

namespace YC_Value
{template<class K, class V>struct BSTreeNode{BSTreeNode<K, V>* _left;BSTreeNode<K, V>* _right;K _key;V _value;BSTreeNode(const K& key, const V& value):_left(nullptr), _right(nullptr), _key(key), _value(value){}};template<class K, class V>class BSTree{typedef BSTreeNode<K, V> Node;public:bool Insert(const K& key, const V& value){if (_root == nullptr){_root = new Node(key, value);return true;}Node* parent = nullptr;Node* cur = _root;while (cur){if (key < cur->_key){parent = cur;cur = cur->_left;}else if (key > cur->_key){parent = cur;cur = cur->_right;}else{return false;}}cur = new Node(key, value);if (parent->_key > key)parent->_left = cur;elseparent->_right = cur;return true;}Node* find(const K& key){Node* cur = _root;while (cur){if (key < cur->_key){cur = cur->_left;}else if (key > cur->_key){cur = cur->_right;}else{return cur;}}return cur;}void Inorder(){_Inorder(_root);cout << endl;}bool Erase(const K& key){Node* cur = _root;Node* parent = cur;while (cur){if (key < cur->_key){parent = cur;cur = cur->_left;}else if (key > cur->_key){parent = cur;cur = cur->_right;}else{if (cur->_left == nullptr){if (parent == cur)_root = cur->_right;else{if (parent->_left == cur){parent->_left = cur->_right;}else{parent->_right = cur->_right;}}}else if (cur->_right == nullptr){if (parent == cur)_root = cur->_left;else{if (parent->_left == cur){parent->_left = cur->_left;}else{parent->_right = cur->_left;}}}else{Node* MinRight = cur->_left;parent = cur;while (MinRight->_right){parent = MinRight;MinRight = MinRight->_right;}cur->_key = MinRight->_key;if (parent->_right == MinRight)parent->_right = MinRight->_left;elseparent->_left = MinRight->_left;}return true;}}return false;}private:void _Inorder(Node* root){if (root == nullptr){return;}_Inorder(root->_left);cout << root->_key << ":" << root->_value << endl;_Inorder(root->_right);}private:Node* _root = nullptr;};void TestBSTree2(){BSTree<string, string> dict;dict.Insert("string", "字符串");dict.Insert("left", "左邊");dict.Insert("insert", "插入");//...string str;while (cin >> str){BSTreeNode<string, string>* ret = dict.find(str);if (ret){cout << ret->_value << endl;}else{cout << "無此單詞,請重新輸入" << endl;}}}void TestBSTree3(){// 統計次數string arr[] = { "蘋果", "西瓜", "蘋果", "西瓜", "蘋果", "蘋果", "西瓜",
"蘋果", "香蕉", "蘋果", "香蕉","蘋果","草莓", "蘋果","草莓" };BSTree<string, int> countTree;for (const auto& str : arr){auto ret = countTree.find(str);if (ret == nullptr){countTree.Insert(str, 1);}else{ret->_value++;}}countTree.Inorder();}
};
單詞查找:

個數統計:

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/38592.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/38592.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/38592.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

vue3 【提效】自動注冊組件 unplugin-vue-components 實用教程

還在為每次都要導入組件而煩惱嗎 &#xff1f; // 每次都需手動導入組件 import webName from /components/webName.vue用 unplugin-vue-components 來幫你吧&#xff0c;以后組件直接拿來用即可&#xff0c;無需再導入啦 &#xff01; <webName />使用流程 1. 安裝 un…

audio ref獲取后 pause失效

this.$refs[soundaudititem].pause()失效&#xff0c;通過ref獲取后&#xff0c;調用pause不生效 后來使用id&#xff0c;生效 let audio document.getElementById(soundaudititem) audio.pause()

機器學習模型訓練過程和預測過程 用孩子來生動的比喻 --九五小龐

訓練過程&#xff1a;孩子在學習知識 想象一下&#xff0c;一個年幼的孩子剛開始學習新知識&#xff0c;這就像是機器學習的模型訓練過程。 收集教材&#xff1a;孩子首先得到了一本教科書或一系列學習材料&#xff0c;這些材料就像機器學習中的數據集&#xff0c;包含了各種…

邏輯這回事(七)---- 器件基礎

Xilinx FPGA創建了先進的硅模塊(ASMBL)架構,以實現FPGA具有針對不同應用程序領域優化的各種功能組合的平臺。通過這一創新,Xilinx提供了更多的設備選擇,使客戶能夠為其特定設計選擇具有正確的功能和功能組合的FPGA。ASMBL體系結構通過以下方式突破了傳統的設計障礙:消除幾…

LINUX系統編程:多線程互斥

目錄 1.鋪墊 2.線程鎖接口的認識 靜態鎖分配 動態鎖的分配 互斥量的銷毀 互斥量加鎖和解鎖 3.加鎖版搶票 4.互斥的底層實現 1.鋪墊 先提一個小場景&#xff0c;有1000張票&#xff0c;現在有4個進程&#xff0c;這四個進程瘋狂的去搶這1000張票&#xff0c;看看會發生什…

新書速覽|Adobe Firefly:螢火蟲:AI繪畫快速創意設計

《Adobe Firefly&#xff1a;螢火蟲&#xff1a;AI繪畫快速創意設計》 本書內容 人工智能&#xff08;Artificial Intelligence&#xff0c;AI&#xff09;浪潮的席卷已經變成不可阻擋的趨勢&#xff0c;伴隨著這種變化&#xff0c;在圖形設計、圖像制作、繪畫領域也相應發生了…

什么是接口測試,我們如何實現接口測試?

1. 什么是接口測試 顧名思義&#xff0c;接口測試是對系統或組件之間的接口進行測試&#xff0c;主要是校驗數據的交換&#xff0c;傳遞和控制管理過程&#xff0c;以及相互邏輯依賴關系。其中接口協議分為HTTP,WebService,Dubbo,Thrift,Socket等類型&#xff0c;測試類型又主…

NewspaceGPT帶你玩系列之SQL專家(強烈推薦)

目錄 注冊一個賬號&#xff0c;用qq郵箱&#xff0c;然后登錄選一個可用的Plus&#xff0c;不要選3.5探索GPT今天的主角是SQL Expert&#xff08;SQL 專家&#xff09;問題1&#xff1a;答1. 索引原因&#xff1a;優化措施&#xff1a;示例&#xff1a; 2. 查詢設計原因&#x…

一個利用WebBrowser(古董)控件實現網頁爬蟲的代碼片段

使用WebBrowser控件進行網頁爬蟲的一個基本方式并不是最常見的方法&#xff0c;因為WebBrowser控件主要是為了提供一個嵌入式的瀏覽器界面&#xff0c;而不是為了網頁抓取。然而&#xff0c;你仍然可以通過監聽WebBrowser控件的DocumentCompleted事件來獲取網頁的內容。 以下是…

ros中teleop_twist_keyboard安裝使用

目錄 1.安裝 2.使用 3.說明 1.安裝 sudo apt-get install ros-noetic-teleop-twist-keyboard 其中noetic替換成你自己的ros版本 2.使用 roscore #啟動roscore rosrun teleop_twist_keyboard teleop_twist_keyboard.py …

零基礎STM32單片機編程入門(五)FreeRTOS實時操作系統詳解及實戰含源碼視頻

文章目錄 一.概要二.什么是實時操作系統三.FreeRTOS的特性四.FreeRTOS的任務詳解1.任務函數定義2.任務的創建3.任務的調度原理 五.CubeMX配置一個FreeRTOS例程1.硬件準備2.創建工程3.調試FreeRTOS任務調度 六.CubeMX工程源代碼下載七.講解視頻鏈接地址八.小結 一.概要 FreeRTO…

[SwiftUI 開發] 嵌套的ObservedObject中的更改不會更新UI

1. 發生問題的demo 業務邏輯代碼 class Address: ObservableObject {Published var street "123 Apple Street"Published var city "Cupertino" }class User: ObservableObject {Published var name "Tim Cook"Published var address Addr…

解決 Win11 微軟拼音輸入法下 JetBrains IDE Shift+F6 失效的問題

一、使用舊版微軟拼音輸入法 1.在任務欄中輸入法圖標上右鍵&#xff0c;點擊“設置”&#xff0c;或者在系統設置中進入“時間和語言 -> 語言和區域 -> 微軟拼音輸入法”設置項。 2.點擊進入“常規”類別&#xff0c;滾動到頁面底部&#xff0c;找到“兼容性 -> 使用…

nacos漏洞小結

Alibaba Nacos是阿里巴巴推出來的一個新開源項目&#xff0c;是一個更易于構建云原生應用的動態服務發現、配置管理和服務管理平臺。致力于幫助發現、配置和管理微服務。Nacos提供了一組簡單易用的特性集&#xff0c;可以快速實現動態服務發現、服務配置、服務元數據及流量管理…

我的創作紀念日 第四年 我在人間遭罪,也在人間享樂

回顧 一晃四年過去了&#xff0c;從畢業到現在依舊沒有后悔自己當初的選擇是工作而不是繼續讀研。 讀研雖然可以給我更高的起點&#xff0c;但破碎的底層建筑和生活壓力讓我沒的選擇&#xff0c;畢竟只是一介凡人&#xff0c;而且還是底層出身&#xff0c;環境差&#xff0c;觀…

64、哥倫比亞大學:CU-Net-目前腦腫瘤分割的最先進模型

本文已被接受發表在2024年IEEE MLISE會議上&#xff08;c&#xff09;2024 IEEE。準確地將腦腫瘤從MRI掃描中分割出來對于制定有效的治療方案和改善患者預后至關重要。本研究引入了一種新的哥倫比亞大學網絡&#xff08;CU-Net&#xff09;架構實現&#xff0c;用于使用BraTS 2…

收銀系統源碼-千呼新零售2.0【移動管理端】

千呼新零售2.0系統是零售行業連鎖店一體化收銀系統&#xff0c;包括線下收銀線上商城連鎖店管理ERP管理商品管理供應商管理會員營銷等功能為一體&#xff0c;線上線下數據全部打通。 適用于商超、便利店、水果、生鮮、母嬰、服裝、零食、百貨、寵物等連鎖店使用。 詳細介紹請…

如何循環遍歷循環中的剩余元素

1、問題背景 給定一段文本&#xff0c;文本中包含多條錯誤信息&#xff0c;每條錯誤信息包含行號、錯誤路徑和錯誤信息。需要從文本中提取出這些錯誤信息&#xff0c;并以特定的格式輸出。 line, Error 12, This is the Error line, Error 34, Another Error line, Error …

【Linux】線程周邊002之線程安全

&#x1f440;樊梓慕&#xff1a;個人主頁 &#x1f3a5;個人專欄&#xff1a;《C語言》《數據結構》《藍橋杯試題》《LeetCode刷題筆記》《實訓項目》《C》《Linux》《算法》 &#x1f31d;每一個不曾起舞的日子&#xff0c;都是對生命的辜負 目錄 前言 1.Linux線程互斥 1…

每日一題——Python實現PAT乙級1050 螺旋矩陣(舉一反三+思想解讀+逐步優化)6千字好文

一個認為一切根源都是“自己不夠強”的INTJ 個人主頁&#xff1a;用哲學編程-CSDN博客專欄&#xff1a;每日一題——舉一反三Python編程學習Python內置函數 Python-3.12.0文檔解讀 目錄 我的寫法 時間復雜度分析 空間復雜度分析 總結 我要更強 代碼解釋 時間復雜度 …