DS二叉排序樹之刪除

38a165c5d38e4b338a02a97eda970bb7.png

Description

給出一個數據序列,建立二叉排序樹,并實現刪除功能

對二叉排序樹進行中序遍歷,可以得到有序的數據序列

Input

第一行輸入t,表示有t個數據序列

第二行輸入n,表示首個序列包含n個數據

第三行輸入n個數據,都是自然數且互不相同,數據之間用空格隔開

第四行輸入m,表示要刪除m個數據

從第五行起,輸入m行,每行一個要刪除的數據,都是自然數

以此類推輸入下一個示例

Output

第一行輸出有序的數據序列,對二叉排序樹進行中序遍歷可以得到

從第二行起,輸出刪除第m個數據后的有序序列,輸出m行

以此類推輸出下一個示例的結果

Sample

#0

Input

Copy

1
6
22 33 55 66 11 44
3
66
22
77

Output

Copy

11 22 33 44 55 66 
11 22 33 44 55 
11 33 44 55 
11 33 44 55 

?

難點:

?

?1.普通的刪除:刪除的是葉子

2df5167fe25446de92aab0bf408d2f74.png

2.刪除的是中間的節點但是只有左右子樹其中一個

467ecde2b99a46b48d2d1802043a0a5f.png

3.刪除的節點是中間的節點且左右子樹都有值

481729665f2242f4a9a15a4221397599.png

?

思路:

?

?1.刪除的是葉子

18c640415c8f47738c35dd4f9035a37f.png
直接把那個葉子刪了,不要了,就是這么大氣!!!

?

2.刪除的是中間的節點,但是只有左右子樹其中一個

f2b02f271721473c8d9cf53b2c93af49.png

直接將要刪掉的他的子樹接上去就好了

3.要刪的節點左右子樹都有值

? 我給此時的樹再加一點,有點突然,別介意
? 分為兩種情況

?1.這個要刪的節點22的左子樹11只有左子樹15沒有右子樹,

02d81826207d41879bcf5281f36e6fa8.jpeg

2.要刪的節點22的左子樹11不只有一個左子樹還有右子樹
abb076dda27848d0b171f792a00695e6.png

tips:
1.為什么要找左子樹最大值?
? ? 因為二叉排序樹左子樹小于根,根小于右子樹,所以找左子樹最大一直向右找就行了
2.為什么20的左子樹是不是null沒有關系?
? ? 因為我們只需要拿20替換22的位置,花圈部分再比20小,也是11的右子樹的位置里,肯定比11大,所以11的右子樹直接指向花圈部分沒有問題

?

刪除節點的的部分:

? ? ? ? ?分為三個部分

1.刪除的節點左子樹為空,那就直接把這個節點的右子樹接上去
2.刪除的節點右子樹為空,那就直接把這個節點的左子樹接上去
3.刪除的節點左右子樹不為空:
? ? root為要被刪除的節點
? ? 一:root的左子樹只有一個左子樹,那就把這個節點替換要刪的節點的值,然后root的左指針指向被替換節點的左子樹,對應這張圖

? ? 二:左子樹不只有一個節點,那就找這個子樹的最大值,跟要刪的節點替換,且這個節點的父節點的右指針指向最大值的左子樹,對應這張圖

?

代碼部分:

?

1.構建二叉排序樹,可以參考我另一篇文章DS二叉排序樹之查找

? ? ?結構體:
72379d02c380400abf411003fdba332d.png

? ?建立根:

7b73c436a92f46d7bd916815cd78c52b.png

? 剩下的元素逐個插入:

1301e5c01a1b4e9eba6a1a07ed4cb04e.png

?

2.刪除元素的函數

? ? 找到要刪除的元素的節點的位置

6a677f7103c843e9af6ee080ab98c0c2.png

? ? ?刪除函數remove

d7f93974415443108b54cc0a04eaf4a9.png

?

完整代碼:

#include <iostream>
#include <queue>
using namespace std;
struct treenod
{int val;treenod* left, * right;//左右子樹指針treenod(){left = NULL;right = NULL;}treenod(int x){val = x;left = NULL;right = NULL;}
};
queue<int>ss;//隊列用來存要建樹的值
void insert(treenod*& root, int num)///元素逐個插入
{if (root == NULL)//遇到空就插入{root = new treenod(num);}if (num < root->val)//插入的值比這個節點小就往左子樹繼續走{insert(root->left, num);}if (num > root->val)//插入的值比這個節點小就往右子樹繼續走{insert(root->right, num);}
}
treenod* buildtree()//建樹
{if (ss.empty())return NULL;treenod* root;root = new treenod(ss.front());//先建立根ss.pop();while (!ss.empty()){insert(root, ss.front());//剩下的元素都一個一個插入ss.pop();}return root;
}
void zhonxu(treenod* root)
{if (root == NULL)return;zhonxu(root->left);cout << root->val << " ";zhonxu(root->right);
}
void remove(treenod*& root)//root是要刪除的節點
{if (root->right == NULL)//要刪的節點只有一個左子樹{root = root->left;return;}if (root->left == NULL)//要刪的節點只有一個右子樹{root = root->right;return;}//要刪的節點存在左右子樹treenod* p = root->left;treenod* pre = root;//可以記為要刪除的節點的父節點while (p->right != NULL){pre = p;            //pre可以理解為最大值的父節點p = p->right;       //向右子樹走找最大值}if (pre == root)//說明要刪的節點左子樹只有一個左分支,沒有右分支{root->val = p->val;//要刪除的節點的值=p的值root->left = p->left;//且這個被刪節點的左子樹要指向,p的左子樹delete p;return;}root->val = p->val;//說明要刪的節點的左子樹有右子樹,有右分支,root=root的左子樹里的最大值pre->right = p->left;//最大值的父節點的右子樹指向最大值的左子樹delete p;return;
}
void removeItem(treenod*& root, int num)//根節點和要刪除的值
{if (root == NULL)//如果遇到空節點說明不存在這個值的節點,不用刪除return;if (root->val == num)//說明存在這個值的節點,刪除{remove(root);//調用刪除函數return;}if (root->val > num)//如果要刪除的值小于這個節點的值,向左子樹走{removeItem(root->left, num);}if (root->val < num)//如果要刪除的值大于這個節點的值,向右子樹走{removeItem(root->right, num);}
}int main()
{int t;cin >> t;while (t--){int n;cin >> n;for (int i = 1; i <= n; i++){int num;cin >> num;ss.push(num);}treenod* root;root = buildtree();zhonxu(root);cout << endl;int m;cin >> m;for (int i = 1; i <= m; i++){int num;cin >> num;removeItem(root, num);zhonxu(root);cout << endl;}}return 0;
}

偷懶下,主函數不想打注釋了,也不長,有讀題的都知道在干嘛


這周估計就更這個吧,因為要備考四級了,而且我也不是大佬,后面的題還不太會,等我慢慢學吧!!!
不要催更,不要催更,不要催更!!!
祝我四級不要再421分好吧有緣人。

我祝你六級輕松拿下600分!!!

?

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

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

相關文章

藍橋杯周賽 第 1 場 強者挑戰賽 6. 小球碰撞【算法賽】(思維題/最長上升子序列LIS)

題目 https://www.lanqiao.cn/problems/9494/learning/?contest_id153 思路來源 Aging代碼 題解 二分時間t&#xff0c;第i個小球對應一個起點pi、終點pit*vi的區間&#xff0c;問題轉化為&#xff0c; 選最多的區間&#xff0c;使得不存在區間包含&#xff08;即li<l…

微信小程序過濾器之計算當前時間差

微信小程序過濾器之計算當前時間差 前言一、wxs簡介二、使用步驟1.定義2.使用 前言 最近遇到了一個需求&#xff0c;將小程序里面的具體時間2023-12-11 09:41:06轉為當前時間差10小時前&#xff0c;這塊可以使用js邏輯函數對數據進行處理&#xff0c;但這里我們采用微信小程序…

Error: Failed to resolve vue/compiler-sfc——vite項目啟動報錯——npm run serve

運行項目時&#xff0c;報錯如下&#xff1a; Error: Failed to resolve vue/compiler-sfc 根據報錯信息的提示&#xff1a;vue的版本必須大于3.2.25&#xff0c;經過查看package.json文件&#xff0c;可以看到vue的版本為3.2.36&#xff0c;是滿足條件的。 因此考慮緩存問題&…

【OPNEGIS】Geoserver原地升級jetty,解決Apache HTTP/2拒絕服務漏洞 (CVE-2023-44487)

Geoserver是我們常用的地圖服務器&#xff0c;在開源系統中的應用比較廣泛。在實際環境中&#xff0c;我們可能會選用官方的二進制安裝包進行部署&#xff0c;這樣只要服務器上有java環境就可以運行&#xff0c;方便在現場進行部署。 1.問題來源 這次由于甲方一月一次的漏洞掃…

Mysql表的數據類型

數據類型 https://www.sjkjc.com/mysql/varchar/ MySQL 中的數據類型包括以下幾個大類&#xff1a; 字符串類型 數字類型 日期和時間類型 二進制類型 地理位置數據類型 JSON 數據類型 MySQL 字符串數據類型 VARCHAR&#xff1a;純文本字符串&#xff0c;字符串長度是可變的…

智能優化算法應用:基于陰陽對算法3D無線傳感器網絡(WSN)覆蓋優化 - 附代碼

智能優化算法應用&#xff1a;基于陰陽對算法3D無線傳感器網絡(WSN)覆蓋優化 - 附代碼 文章目錄 智能優化算法應用&#xff1a;基于陰陽對算法3D無線傳感器網絡(WSN)覆蓋優化 - 附代碼1.無線傳感網絡節點模型2.覆蓋數學模型及分析3.陰陽對算法4.實驗參數設定5.算法結果6.參考文…

云計算、邊緣計算、霧計算

目錄 云計算邊緣計算霧計算 云計算 云計算是基于互聯網的計算模式&#xff0c;允許用戶通過網絡獲取計算資源、存儲資源、數據庫等服務&#xff0c;無需了解和管理底層 云計算是分布式計算的一種&#xff0c;指的是通過網絡“云”將巨大的數據計算處理程序分解成無數個小程序…

Java - Mybatis的緩存機制、集成SpringBoot后緩存相關問題

mybaits提供一級緩存&#xff0c;和二級緩存 一級緩存&#xff08;默認開啟&#xff09; 一級緩存是SqlSession級別的緩存。在操作數據庫時需要構造 sqlSession對象&#xff0c;在對象中有一個(內存區域)數據結構&#xff08;HashMap&#xff09;用于存儲緩存數據。不同的sqlSe…

STM32F407-14.3.1-01 時基單元

時基單元 可編程高級控制定時器的主要模塊是一個 16 位計數器及其相關的自動重載寄存器。計數器可遞增計數、遞減計數或交替進行遞增和遞減計數。計數器的時鐘可通過預分頻器進行分頻。 計數器、自動重載寄存器和預分頻器寄存器可通過軟件進行讀寫。即使在計數器運行時也可執行…

Linux ln命令教程:如何創建符號鏈接(附案例詳解和注意事項)

Linux ln命令介紹 Linux ln命令&#xff08;全稱&#xff1a;link files&#xff09;是一個非常重要的命令&#xff0c;它的功能是為某一個文件在另外一個位置建立一個同步的鏈接。當我們需要在不同的目錄&#xff0c;用到相同的文件時&#xff0c;我們不需要在每一個需要的目…

Python:核心知識點整理大全14-筆記

目錄 ?編輯 7.2.2 讓用戶選擇何時退出 parrot.py 7.2.3 使用標志 7.2.4 使用 break 退出循環 cities.py 7.2.5 在循環中使用 continue counting.py 7.2.6 避免無限循環 counting.py 7.3 使用 while 循環來處理列表和字典 7.3.1 在列表之間移動元素 confirmed_user…

數字圖像處理(實踐篇)二十二 使用opencv進行人臉、眼睛、嘴的檢測

目錄 1 xml文件 2 涉及的函數 3 實踐 使用opencv進行人臉、眼睛、嘴的檢測。 1 xml文件 方法① 下載 地址&#xff1a;https://github.com/opencv/opencv/tree/master/data/haarcascades 點擊haarcascade_frontalface_default.xml文件 對著Raw右鍵&#xff0c;選擇“鏈接…

【JVM從入門到實戰】(二)字節碼文件的組成

一、Java虛擬機的組成 二、字節碼文件的組成 字節碼文件的組成 – 應用場景 字節碼文件的組成部分-Magic魔數 什么是魔數&#xff1f; Java字節碼文件中的魔數 文件是無法通過文件擴展名來確定文件類型的&#xff0c;文件擴展名可以隨意修改&#xff0c;不影響文件的內容。…

機器學習筆記 - 隨機樣本共識(RANSAC) 算法

一、什么是 RANSAC? RANSAC(隨機樣本共識)是一種用于機器學習和計算機視覺的算法,隨機樣本共識(RANSAC)是一種迭代方法,用于根據包含異常值的數據集估計數學模型。RANSAC 算法的工作原理是識別數據集中的異常值,并使用不包含異常值的數據來估計所需的模型。 …

在Go中定義結構體

引言 圍繞具體細節構建抽象是編程語言可以提供給開發人員的最好工具。結構體允許Go開發人員描述Go程序運行的世界。結構體允許我們討論Address,而不是描述Street、 City或PostalCode的字符串。它們是我們努力告訴未來開發人員(包括我們自己)哪些數據對我們的Go程序是重要的,…

UE引擎 LandscapeGrass 實現機制分析(UE5.2)

前言 隨著電腦和手機硬件性能越來越高&#xff0c;游戲越來越追求大世界&#xff0c;而大世界非常核心的一環是植被&#xff0c;目前UE5引擎提供給植被生成的主流兩種方式為 手刷植被和LandscapeGrass(WeightMap程序化植被)。當然UE5.3推出新一代PCGFramework 節點程序化生成框…

MyBatis:緩存

MyBatis 緩存一級緩存二級緩存注 緩存 緩存&#xff0c;是數據交換的緩沖區&#xff08;臨時保存數據的地方&#xff09;。即將數據&#xff08;數據一般為頻繁查詢且不易改變&#xff09;保存在計算機內存中&#xff0c;下次讀取數據時直接從內存中獲取&#xff0c;以避免頻繁…

OpenAI接口調用示例

最近為公司做了一個ChatGPT工具&#xff0c;這里展示一下OpenAI接口的調用 前提條件 訪問OpenAI官網&#xff08;國內需要翻墻&#xff09;的賬號&#xff0c;需要sk 地址&#xff1a;https://platform.openai.com 依賴 使用開源工具調用OpenAI接口&#xff0c;依賴如下&am…

js中箭頭函數簡單介紹

1.箭頭函數是 ES6 中新增的一種函數定義方式&#xff0c; 簡單舉例為 var nameA function(a){return a} 可以用箭頭函數簡化為 var nameA a >a; 返回的是你輸入的值 比如 nameA(5) 返回的就是5 nameA(2) 返回的就是2 以上兩個表達的含義是一樣的。nameA為名字 2.…

Vue3封裝一個輪播圖組件

先看效果 編寫組件代碼 CarouselChart.vue <template><div classimg-box><el-button clickpreviousImages v-ifprops.showBtn>←</el-button><div classimg><div styledisplay: flex;gap: 20px idmove><imgclassimg-item v-for(item…