C++: 二叉搜索樹及實現

目錄

一、二叉搜索樹的概念

二、二叉搜索樹的操作

2.1插入

2.2刪除

1.有左子樹,無右子樹

2.有右子樹,無左子樹

3.有左子樹和右子樹

三、二叉搜索樹的實現

要點


前言:為了學習map和set,需要先學二叉搜索樹作為鋪墊。

一、二叉搜索樹的概念

二叉搜索樹是一棵二叉樹,又稱為二叉排序樹,它有以下特性:

1.若左子樹不為空,則左子樹的節點值比根要小

2.若右子樹不為空,則右子樹的節點值比根要大

3.整棵樹都遵循以上規則

需要注意,二叉樹也可以是空樹。

二、二叉搜索樹的操作

2.1插入

插入的思路是,先用遞歸將樹搜索一遍,用key和樹的根的節點比大小,比它大往右走,比它小往左走,直到走到空,那么就在空的位置插入。

2.2刪除

刪除的思路比較復雜。刪除情況分三種,分別是所要刪除的節點情況,若刪除的是key節點:

1.有左子樹,無右子樹

這里就將key節點的前一個節點,指向它的后一個節點,然后釋放key節點。

2.有右子樹,無左子樹

和上面類似。

3.有左子樹和右子樹

這里比較復雜,需要將key節點與它的左子樹中的最大的一個,或者右子樹中最小的一個交換,然后再刪除key。

右子樹中最小的一個,是第一個右節點的最左的節點。若沒有最左節點,那就只能和右節點交換。

交換以后,就可以刪除key節點也就是4了。

最后一種無左子樹也無右子樹可以放在1和2中討論,歸為一種。操作比較簡單,此處不再贅述。

三、二叉搜索樹的實現

要點

1.為了體現封裝,我們只留接口放在類的public中,把具體實現的細節放在private中,這樣也方便代碼日后維護。同時由于使用遞歸,所以需要取root的引用,參數就要給root,而在類外是沒有辦法獲取作為私有的root的,因此只能把實現的細節寫在private里。

2.搜索二叉樹可以用來匹配,比如說當字典使用和門禁系統,這里可以再放入一個類模板。

3.插入的時候要新建一個節點再插入,這里會改變root的地址,所以傳引用會更好,不然就要傳二級指針了,這個很麻煩,而且在C++中是避免的。

4.刪除的時候,要先找到這個節點,再刪除。刪除時,一共涉及三個指針的操作。建議先理清思路再寫代碼。

namespace ting
{template<class K, class V>struct BSTreeNode{BSTreeNode(const K& content, const V& value):_content(content),_left(nullptr),_right(nullptr),_value(value){}K  _content;BSTreeNode<K,V>* _left;BSTreeNode<K,V>* _right;V _value;};template<class K, class V>class BSTree{typedef BSTreeNode<K, V> Node;public:bool Insert(const K& key, const V& value){return _Insert(_root, key, value);}Node* Find(const K& key){return _Find(_root, key);}bool Erase(const K& key){return _Erase(_root, key);}void InOrder(){_InOrder(_root);}private:Node* _root = nullptr;Node* _Find(Node* root, const K& key){while (root != nullptr){if (root->_content < key){root = root->_right;}else if (root->_content > key){root = root->_left;}else if (root->_content == key){return root;}}return nullptr;}void _InOrder(Node* root){if (root == nullptr)return;_InOrder(root->_left);cout << root->_content<<" "<<root->_value << endl;_InOrder(root->_right);}bool _Insert(Node*& root, const K& key, const V& value){if (root == nullptr){/*root->_content = key;root->_value = value;return true;*/root = new Node(key, value);//這里要給root建一個節點return true;}if (root->_content < key){return _Insert(root->_right, key, value);}else if (root->_content > key){return _Insert(root->_left, key, value);}else{return false;}}bool _Erase(Node*& root, const K& key){if (root == nullptr)return false;if (root->_content < key){return _Erase(root->_right, key);}else if (root->_content > key){return _Erase(root->_left, key);}else{Node* del = root;if (root->_left == nullptr){root = root->_right;}else if (root->_right == nullptr){root = root->_left;}else{Node* prev = root;Node* minNode = root->_right;while (minNode->_left != nullptr){prev = minNode;minNode = minNode->_left;}root->_content = minNode->_content;root->_value = minNode->_value;if (prev->_left == minNode){prev->_left = minNode->_right;}else{prev->_right = minNode->_right;}del = minNode;}delete del;return true;		}}};void TestBSTree(){BSTree<string, string> dict;dict.Insert("insert", "插入");dict.Insert("erase", "刪除");dict.Insert("left", "左邊");dict.Insert("string", "字符串");string str;while (cin >> str){auto ret = dict.Find(str);if (ret){cout << str << ":" << ret->_value << endl;}else{cout << "單詞拼寫錯誤" << endl;}}string strs[] = { "蘋果", "西瓜", "蘋果", "櫻桃", "蘋果", "櫻桃", "蘋果", "櫻桃", "蘋果" };// 統計水果出現的次BSTree<string, int> countTree;for (auto str : strs){auto ret = countTree.Find(str);if (ret == NULL){countTree.Insert(str, 1);}else{ret->_value++;}}countTree.InOrder();}
}

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

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

相關文章

基于51單片機的函數發生器設計

一.硬件方案 此函數信號發生器是基于單片機AT89C51設計而成的&#xff0c;能夠產生頻率范圍在0Hz—535Hz的鋸齒波、正弦波、三角波、矩形波四種波形&#xff0c;并且能夠通過液晶屏1602顯示各自的波形類型以及頻率數值。電路主要由51單片機最小系統DA0832模數轉換模塊運放模塊…

AI代理的類型、優勢及示例

AI 代理的類型、優勢和示例 AI 代理是重塑商業動態的關鍵技術進步。了解這些代理的運作方式&#xff0c;發現它們的關鍵優勢包括效率、可擴展性和成本效益。我們將探索代理的實例及它們在各領域的應用&#xff0c;為未來的人工智能趨勢和對客戶體驗的影響鋪平道路。 想象一支由…

`“use strict“`在JavaScript中是什么?它背后的原理是什么?

JavaScript的嚴格模式(strict mode)是ECMAScript 5引入的一項特性。如果你在腳本或函數的頂部聲明 use strict;,你就啟用了嚴格模式: use strict;當JavaScript引擎看到這個指令時,它將開始以一種特殊的模式解釋代碼。在這種模式下,當檢測到某些可能導致潛在錯誤的編碼實…

多重繼承引起的二義性問題和虛基類

多重繼承容易引起的問題就是因為繼承的成員同名而產生的二義性問題。 例&#xff1a;類A和類B中都有成員函數display和數據成員a,類C是類A和類B的直接派生類 情況一&#xff1a; class A {public:int a;void display(); }; class B {public:int a;void display; }; class C:…

添加AXI主IP(AXI4 Lite和AXI4)示例

添加AXI主IP&#xff08;AXI4 Lite和AXI4&#xff09;示例 將等效IP添加到框圖中。以下是AXI Central的示例步驟 直接存儲器存取&#xff08;CDMA&#xff09;&#xff1a; 1.右鍵單擊方框圖中的任意位置&#xff0c;然后選擇“添加IP”。 2.搜索并雙擊AXI Central Direct Memo…

Android 錄音AudioRecord

AudioRecord是安卓多媒體框架中用于錄制音頻的工具。它支持錄制原始音頻數據&#xff0c;即PCM數據&#xff0c;PCM數據不能被播放器直接播放&#xff0c;需要編碼壓縮成常見音頻格式才能被播放器識別。通常生成PCM文件之后可將PCM文件轉成WAV文件一般的播放器便可直接播放了。…

前端開發技巧 --判斷文本是否溢出

const isTextOverflower()>{if(element){return element.offsetWidth > element.scrollWidth}return false}實現javascript 判斷文本是否溢出

【除了知乎,大家都在逛什么?持續更新~~】

除了知乎&#xff0c;大家都在逛什么&#xff1f; 中文博客瑯琊榜 https://github.com/qianguyihao/blog-list 中文博客瑯琊榜&#xff0c;只收錄優質的中文獨立博客&#xff0c;全網最精品。已收錄博客數量&#xff1a;328 個博客站點。 這些博主才華橫溢&#xff0c;滿懷自由…

【2024最新】軟考資料大全(免費)

IT行業越來越卷&#xff0c;大家都在忙著搞證&#xff0c;你免費不搞一個&#xff1f; 不管有沒有用&#xff0c;有總比沒有好噻~ 【初級】&#xff0c;【中級】&#xff0c;【高級】 都有&#xff0c;而且全部免費&#xff0c;全部最新的&#xff01;真題&#xff0c;論文都…

Java查看線上對象的變量值

背影 有時候線上有些配置類&#xff0c;想查看下配置修改是否生效&#xff0c;傳統的方法要通過打日志的方法&#xff0c;如果不想通過打日志的方法&#xff0c;有沒有好的方案能解決這個問題呢 解決方案 arthas 步驟 得到類加載器的hashcode sc -d com.example.MyService…

眼底項目經驗

眼底項目經驗 可解釋性不足問題眼底項目有多牛逼可解釋性不足解法數據、算力、算法都免費送不僅預測當下&#xff0c;還能預測未來和慢病管理整合&#xff0c;形成一個實時健康檢測生態 可解釋性不足問題 今天下午和騰訊眼底項目人員討論, 他們不準備做全身性的多疾種, 因為深…

LINUX環境基礎練習題(附帶答案)

&#x1f525; 交流討論&#xff1a;歡迎加入我們一起學習&#xff01; &#x1f525; 資源分享&#xff1a;耗時200小時精選的「軟件測試」資料包 &#x1f525; 教程推薦&#xff1a;火遍全網的《軟件測試》教程 &#x1f4e2;歡迎點贊 &#x1f44d; 收藏 ?留言 &#x1…

【typescript - tsc 編譯后路徑問題/路徑別名問題】

這幾天在寫typescript&#xff0c;遇到個路徑依賴問題&#xff0c;編寫的.ts文件直接運行OK&#xff0c;但是編譯成.js后&#xff0c;運行提示 Error: Cannot find module xxx&#xff0c;&#x1f4dd;記錄分析和解決過程 。 問題描述 原始文件&#xff0c;有index.ts 其會引…

小白不知道怎么投稿?記住這個好方法

作為一名單位信息宣傳員,我最初踏上這條道路時,滿心憧憬著通過文字傳遞我們單位的精彩瞬間,讓社會聽見我們的聲音。然而,理想與現實之間的距離,卻在一次次郵箱投稿的石沉大海中漸漸清晰。那時的我,像所有“小白”一樣,以為只要用心撰寫稿件,通過電子郵件發給各大媒體,就能收獲滿…

4 CSS的 變換、過渡與動畫

CSS3引入了變換、過渡和動畫特性&#xff0c;使得網頁可以呈現出豐富的視覺效果和交互體驗。通過這些新特性&#xff0c;開發者可以創建復雜的動畫效果&#xff0c;而不需要使用JavaScript。 4.1 變換&#xff08;Transforms&#xff09; 變換允許開發者對元素進行旋轉、縮放…

Python考試復習--day2

1.出租車計費 mile,waitmap(int,input().split(,)) if mile<3:money13wait*1 elif mile>3 and mile<15:money13(mile-3)*2.3wait*1 else:money1312*2.3(mile-15)*2.3*(10.5)wait*1 print({:.0f}.format(money)) 【知識點1】&#xff1a; map() 函數 【知識點1】&…

代碼隨想錄算法訓練營第五十一天|300.最長遞增子序列,674. 最長連續遞增序列,718. 最長重復子數組

300.最長遞增子序列 dp數組的含義為dp[i]表示字符串以第i位置為末尾的最長遞增子序列的長度。 for (int i 1; i < nums.size(); i) {for (int j 0; j < i; j) {if (nums[i] > nums[j]) dp[i] max(dp[i], dp[j] 1);}if (dp[i] > result) result dp[i]; // 取…

設計模式 20 中介者模式 Mediator Pattern

設計模式 20 中介者模式 Mediator Pattern 1.定義 中介者模式&#xff08;Mediator Pattern&#xff09;是一種行為型設計模式&#xff0c;它通過封裝對象之間的交互&#xff0c;促進對象之間的解耦合。中介者模式的核心思想是引入一個中介者對象&#xff0c;將系統中對象之間…

Vue中,點擊提交按鈕,路由多了個問號

問題 當點擊提交按鈕是路由多了問號&#xff1a; http://localhost:8100/#/ 變為 http://localhost:8100/?#/原因 路由中出現問號通常是由于某些路徑或參數處理不當造成的。在該情況下&#xff0c;是因為表單的默認行為導致的。提交表單時&#xff0c;如果沒有阻止表單的默…

React Router v6:路由管理的最新進展

React Router v6 是 React 應用程序路由管理的一個重大更新&#xff0c;它引入了許多改進和簡化&#xff0c;包括對嵌套路由的更友好處理&#xff0c;以及對鉤子函數的使用。 2500G計算機入門到高級架構師開發資料超級大禮包免費送&#xff01; 1. Routes 重構 在 v6 中&…