C++ --- 二叉搜索樹

1 二叉搜索樹的概念

?叉搜索樹?稱?叉排序樹,它或者是?棵空樹,或者是具有以下性質的?叉樹:

1 若它的左?樹不為空,則左?樹上所有結點的值都?于等于根結點的值

2 若它的右?樹不為空,則右?樹上所有結點的值都?于等于根結點的值

3 它的左右?樹也分別為?叉搜索樹

4 ?叉搜索樹中可以?持插?相等的值,也可以不?持插?相等的值,具體看使?場景定義

2 二叉搜索樹的性能分析?

最優情況下,?叉搜索樹為完全?叉樹(或者接近完全?叉樹),其?度為: logN

最差情況下,?叉搜索樹退化為單?樹(或者類似單?),其?度為: N

所以綜合???叉搜索樹增刪查改時間復雜度為: O(N)

那么這樣的效率顯然是?法滿?我們需求的,我們后續課程需要繼續講解?叉搜索樹的變形,平衡?叉搜索樹AVL樹和紅?樹,才能適?于我們在內存中存儲和搜索數據。

另外需要說明的是,?分查找也可以實現 O(logN) 2 級別的查找效率,但是?分查找有兩?缺陷:

1. 需要存儲在?持下標隨機訪問的結構中,并且有序。

2. 插?和刪除數據效率很低,因為存儲在下標隨機訪問的結構中,插?和刪除數據?般需要挪動數據。

這?也就體現出了平衡?叉搜索樹的價值

?3 二叉搜索樹的插入

?插?的具體過程如下:

1. 樹為空,則直接新增結點,賦值給root指針

2. 樹不空,按?叉搜索樹性質,插?值?當前結點?往右?,插?值?當前結點?往左?,找到空位 置,插?新結點。

3. 如果?持插?相等的值,插?值跟當前結點相等的值可以往右?,也可以往左?,找到空位置,插?新結點。(要注意的是要保持邏輯?致性,插?相等的值不要?會往右?,?會往左?)

????????代碼實現:

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

4 二叉搜索樹的查找?

1.從根開始?較,查找x,x?根的值?則往右邊?查找,x?根值?則往左邊?查找。

2. 最多查找?度次,?到到空,還沒找到,這個值不存在。

3. 如果不?持插?相等的值,找到x即可返回

4. 如果?持插?相等的值,意味著有多個x存在,?般要求查找中序的第?個x。如下圖,查找3,要 找到1的右孩?的那個3返回

????????代碼實現:

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

5 二叉搜索樹的刪除?

??先查找元素是否在?叉搜索樹中,如果不存在,則返回false。

如果查找元素存在則分以下四種情況分別處理:(假設要刪除的結點為N)

1. 要刪除結點N左右孩?均為空

2. 要刪除的結點N左孩?位空,右孩?結點不為空

3. 要刪除的結點N右孩?位空,左孩?結點不為空

4. 要刪除的結點N左右孩?結點均不為空

對應以上四種情況的解決?案:

1. 把N結點的?親對應孩?指針指向空,直接刪除N結點(情況1可以當成2或者3處理,效果是?樣 的)

2. 把N結點的?親對應孩?指針指向N的右孩?,直接刪除N結點

3. 把N結點的?親對應孩?指針指向N的左孩?,直接刪除N結點

4. ?法直接刪除N結點,因為N的兩個孩??處安放,只能?替換法刪除。找N左?樹的值最?結點 R(最右結點)或者N右?樹的值最?結點R(最左結點)替代N,因為這兩個結點中任意?個,放到N的 位置,都滿??叉搜索樹的規則。替代N的意思就是N和R的兩個結點的值交換,轉?變成刪除R結 點,R結點符合情況2或情況3,可以直接刪除。

代碼實現:

bool Erase(const K& key)
{Node* cur = _root;Node* parent = nullptr;while (cur){if (cur->_key > key){parent = cur;cur = cur->_left;}else if (cur->_key < key){parent = cur;cur = cur->_right;}else{//準備刪除if (cur->_left == nullptr){if (cur == _root){_root = cur->_right;}else{if (cur == parent->_left){parent->_left = cur->_right;}else{parent->_right = cur->_right;}}delete cur;}else if (cur->_right == nullptr){if (cur == _root){_root = _root->_left;}else{if (cur == parent->_left){parent->_left = cur->_left;}else{parent->_right = cur->_left;}}delete cur;}else{Node* replaceParent = cur;Node* replace = cur->_right;while (replace->_left){replaceParent = replace;replace = replace->_left;}swap(cur->_key, replace->_key);if (replaceParent->_left == replace)replaceParent->_left = replace->_right;elsereplaceParent->_right = replace->_right;delete replace;}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并不作為public對象對外可以進行訪問的,因此單純的寫一個InOrder函數達不到打印的效果,但是可以在創建一個無參的InOrder來進行調用,這樣內部的函數進行調用就不會出現那種情況了,那么就可以達到我們想要的效果了。

?到這里關于二叉搜索樹的介紹就到這里了,感謝你的觀看!

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

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

相關文章

跨語言語言模型預訓練

摘要 最近的研究表明&#xff0c;生成式預訓練在英語自然語言理解任務中表現出較高的效率。在本研究中&#xff0c;我們將這一方法擴展到多種語言&#xff0c;并展示跨語言預訓練的有效性。我們提出了兩種學習跨語言語言模型&#xff08;XLM&#xff09;的方法&#xff1a;一種…

文件描述符,它在哪里存的,exec()后還存在嗎

學過計系肯定了解 寄存器、程序計數器、堆棧這些 程序運行需要的資源。 這些是進程地址空間。 而操作系統分配一個進程資源時&#xff0c;分配的是 PCB 進程控制塊。 所以進程控制塊還維護其他資源——程序與外部交互的資源——文件、管道、套接字。 文章目錄 文件描述符進程管…

Slidev使用(一)安裝

文章目錄 1. **安裝位置**2. **使用方式**3. **適用場景**4. **管理和維護** 全局安裝1. **檢查 Node.js 和 npm 是否已安裝**2. **全局安裝 Slidev CLI**3. **驗證安裝是否成功**4. **創建幻燈片文件**5. **啟動 Slidev**6. **實時編輯和預覽**7. **構建和導出&#xff08;可選…

第二十一章:模板與繼承_《C++ Templates》notes

模板與繼承 重點和難點編譯與測試說明第一部分&#xff1a;多選題 (10題)第二部分&#xff1a;設計題 (5題)答案與詳解多選題答案&#xff1a;設計題參考答案 測試說明 重點和難點 21.1 空基類優化&#xff08;EBCO&#xff09; 知識點 空基類優化&#xff08;Empty Base Cla…

AOA與TOA混合定位,MATLAB例程,自適應基站數量,三維空間下的運動軌跡,濾波使用EKF

本代碼實現了一個基于 到達角(AOA) 和 到達時間(TOA) 的混合定位算法,結合 擴展卡爾曼濾波(EKF) 對三維運動目標的軌跡進行濾波優化。代碼通過模擬動態目標與基站網絡,展示了從信號測量、定位解算到軌跡濾波的全流程,適用于城市峽谷、室內等復雜環境下的定位研究。 文…

量子計算:開啟未來計算的新紀元

一、引言 在當今數字化時代&#xff0c;計算技術的飛速發展深刻地改變了我們的生活和工作方式。從傳統的電子計算機到如今的高性能超級計算機&#xff0c;人類在計算能力上取得了巨大的進步。然而&#xff0c;隨著科技的不斷推進&#xff0c;我們面臨著越來越多的復雜問題&…

AMD機密計算虛擬機介紹

一、什么機密計算虛擬機 機密計算虛擬機 是一種基于硬件安全技術(如 AMD Secure Encrypted Virtualization, SEV)的虛擬化環境,旨在保護虛擬機(VM)的 ?運行中數據?(包括內存、CPU 寄存器等)免受外部攻擊或未經授權的訪問,即使云服務提供商或管理員也無法窺探。 AMD …

如何通過數據可視化提升管理效率

通過數據可視化提升管理效率的核心方法包括清晰展示關鍵指標、及時發現和解決問題、支持決策優化。其中&#xff0c;清晰展示關鍵指標尤為重要。通過數據可視化工具直觀地呈現關鍵績效指標&#xff08;KPI&#xff09;&#xff0c;管理者能快速、準確地理解業務現狀&#xff0c…

.git 文件夾

文件夾介紹 &#x1f34e; 在 macOS 上如何查看 .git 文件夾&#xff1f; ? 方法一&#xff1a;終端查看&#xff08;最推薦&#xff09; cd /你的項目路徑/ ls -a-a 參數表示“顯示所有文件&#xff08;包括隱藏的&#xff09;”&#xff0c;你就能看到&#xff1a; .git…

MongoDB 與 Elasticsearch 使用場景區別及示例

一、核心定位差異 ?MongoDB? ?定位?&#xff1a;通用型文檔數據庫&#xff0c;側重數據的存儲、事務管理及結構化查詢&#xff0c;支持 ACID 事務?。?典型場景?&#xff1a; 動態數據結構存儲&#xff08;如用戶信息、商品詳情&#xff09;?。需事務支持的場景&#xf…

【深度學習基礎 2】 PyTorch 框架

目錄 一、 PyTorch 簡介 二、安裝 PyTorch 三、PyTorch 常用函數和操作 3.1 創建張量&#xff08;Tensor&#xff09; 3.2 基本數學運算 3.3 自動求導&#xff08;Autograd&#xff09; 3.4 定義神經網絡模型 3.5 訓練與評估模型 3.6 使用模型進行預測 四、注意事項 …

uniapp中APP上傳文件

uniapp提供了uni.chooseImage&#xff08;選擇圖片&#xff09;&#xff0c; uni.chooseVideo&#xff08;選擇視頻&#xff09;這兩個api&#xff0c;但是對于打包成APP的話就沒有上傳文件的api了。因此我采用了plus.android中的方式來打開手機的文件管理從而上傳文件。 下面…

推陳換新系列————java8新特性(編程語言的文藝復興)

文章目錄 前言一、新特性秘籍二、Lambda表達式2.1 語法2.2 函數式接口2.3 內置函數式接口2.4 方法引用和構造器引用 三、Stream API3.1 基本概念3.2 實戰3.3 優勢 四、新的日期時間API4.1 核心概念與設計原則4.2 核心類詳解4.2.1 LocalDate&#xff08;本地日期&#xff09;4.2…

樹莓派5從零開發至脫機腳本運行教程——1.系統部署篇

樹莓派5應用實例——工創視覺 前言 哈嘍&#xff0c;各位小伙伴&#xff0c;大家好。最近接觸了樹莓派&#xff0c;然后簡單的應用了一下&#xff0c;學習程度并不是很深&#xff0c;不過足夠剛入手樹莓派5的小伙伴們了解了解。后面的幾篇更新的文章都是關于開發樹莓派5的內容…

GPT Researcher 的win docker安裝攻略

github網址是&#xff1a;https://github.com/assafelovic/gpt-researcher 因為docker安裝方法不夠清晰&#xff0c;因此寫一個使用方法 以下是針對 Windows 系統 使用 Docker 運行 AI-Researcher 項目的 詳細分步指南&#xff1a; 步驟 1&#xff1a;安裝 Docker 下載 Docke…

【后端】【Django DRF】從零實現RBAC 權限管理系統

Django DRF 實現 RBAC 權限管理系統 在 Web 應用中&#xff0c;權限管理 是一個核心功能&#xff0c;尤其是在多用戶系統中&#xff0c;需要精細化控制不同用戶的訪問權限。本文介紹如何使用 Django DRF 設計并實現 RBAC&#xff08;基于角色的訪問控制&#xff09;系統&…

C#基礎學習(五)函數中的ref和out

1. 引言&#xff1a;為什么需要ref和out&#xff1f; ?問題背景&#xff1a;函數參數默認按值傳遞&#xff0c;值類型在函數內修改不影響外部變量&#xff1b;引用類型重新賦值時外部對象不變。?核心作用&#xff1a;允許函數內部修改外部變量的值&#xff0c;實現“雙向傳參…

八綱辨證總則

一、八綱辨證的核心定義 八綱即陰、陽、表、里、寒、熱、虛、實&#xff0c;是中醫分析疾病共性的綱領性辨證方法。 作用&#xff1a;通過八類證候歸納疾病本質&#xff0c;為所有辨證方法&#xff08;如臟腑辨證、六經辨證&#xff09;的基礎。 二、八綱分類與對應關系 1. 總…

【linux重設gitee賬號密碼 克隆私有倉庫報錯】

出現問題時 Cloning into xxx... remote: [session-1f4b16a4] Unauthorized fatal: Authentication failed for https://gitee.com/xxx/xxx.git/解決方案 先打開~/.git-credentials vim ~/.git-credentials或者創建一個 torch ~/.git-credentials 添加授權信息 username/pa…

綠聯NAS安裝內網穿透實現無公網IP也能用手機平板遠程訪問經驗分享

文章目錄 前言1. 開啟ssh服務2. ssh連接3. 安裝cpolar內網穿透4. 配置綠聯NAS公網地址 前言 大家好&#xff0c;今天給大家帶來一個超級炫酷的技能——如何在綠聯NAS上快速安裝cpolar內網穿透工具。想象一下&#xff0c;即使沒有公網IP&#xff0c;你也能隨時隨地遠程訪問自己…