二叉搜索樹的插入與刪除圖解

===================================================================

一、二叉搜索樹(BSTree)的概念

? ? ? ?二叉搜索樹又被稱為二叉排序樹,那么它本身也是一棵二叉樹,那么滿足以下性質的二叉樹就是二叉搜索樹:
? ? ? ?1、若左子樹不為空,則左子樹上左右節點的值都小于根節點的值
? ? ? ?2、若它的右子樹不為空,則它的右子樹上所有的節點的值都大于根節點的值
? ? ? ?3、它的左右子樹也要分別是二叉搜索樹
===================================================================

二、二叉搜索樹的插入

? 1、搜索
? ? ? ?插入之前我們先來說說它的搜索,像上圖這樣的一棵二叉搜索樹,我們要查找某一個元素是很簡單的。因為它的節點分布是有規律的,所以查找一棵元素只需要如下的步驟就可以了:
? ? ? ??
? ? ? ?2、插入
? ? ? ?由于二叉搜索樹的特殊性質確定了二叉搜索樹中每個元素只可能出現一次,所以在插入的過程中如果發現這個元素已經存在于二叉搜索樹中,就不進行插入。
否則就查找合適的位置進行插入。
第一種情況:_root為空
直接插入,return ?true;
第二種情況:要插入的元素已經存在
如上面所說,如果在二叉搜索樹中已經存在該元素,則不再進行插入,直接return ?false;
第三種情況:能夠找到合適位置
===================================================================

三、二叉搜索樹的刪除

對于二叉搜索樹的刪除操作,主要是要理解其中的幾種情況,寫起來還是比較簡單的。
當然一開始還是需要判斷要刪除的節點是否存在于我們的樹中,如果要刪除的元素都不在樹中,就直接返回false;否則,再分為以下四種情況來進行分析:
? ? ?》要刪除的節點無左右孩子
? ? ?》要刪除的節點只有左孩子
? ? ?》要刪除的節點只有右孩子
? ? ?》要刪除的節點有左、右孩子
?
刪除方法解釋:
? ? ?對于第一種情況,我們完全可以把它歸為第二或者第三種情況,就不用再單獨寫一部分代碼進行處理;
? ? ?》如果要刪除的節點只有左孩子,那么就讓該節點的父親結點指向該節點的左孩子,然后刪除該節點,返回true;
? ? ? ? ??
? ? ?》如果要刪除的節點只有右孩子,那么就讓該節點的父親結點指向該節點的右孩子,然后刪除該節點,返回true;
? ? ? ? ? ??
? ? ? ? ? 對于上面這兩種情況我們還應該在之前進行一個判斷,就是判斷這個節點是否是根節點,如果是根節點的話,就直接讓根節點指向這個節點的左孩子或右孩子,然后刪除這個節點。
? ? ? ?》最后一種也是最麻煩的一種就是要刪除的節點的左右孩子都存在。此時我們的刪除方法如下:
? ? ? ? ? ?1、找到該節點的右子樹中的最左孩子(也就是右子樹中序遍歷的第一個節點)
? ? ? ? ? ?2、把它的值和要刪除的節點的值進行交換
? ? ? ? ? ?3、然后刪除這個節點即相當于把我們想刪除的節點刪除了,返回true;
===================================================================
程序代碼:
1、二叉搜索樹的插入操作
 1  bool Insert(const K& key)
 2     {
 3         if (_root == NULL)
 4         {
 5             _root = new Node(key);
 6             return true;
 7         }
 8         Node* parent=NULL;
 9         Node* pcur = _root;
10         while (pcur)
11         {
12             if (pcur->_key == key)  //有key節點,則不再插入
13                 return false;
14             if (pcur->_key > key)
15             {
16                 parent = pcur;
17                 pcur = pcur->_left;
18             }
19             else if (pcur->_key < key)
20             {
21                 parent = pcur;
22                 pcur = pcur->_right;
23             }
24         }
25         if (parent->_key < key)
26             parent->_right = new Node(key);
27         else
28             parent->_left = new Node(key);
29         return true;
30     }

2、二叉搜索樹的刪除操作?bool Remove(const K& key)

 1 bool Remove(const K& key)
 2     {
 3         assert(_root);
 4         Node* parent = NULL;
 5         Node* pcur = _root;
 6         Node* del = pcur;
 7         while (pcur != NULL  && pcur->_key != key)
 8         {
 9             if (pcur->_key > key)
10             {
11                 parent = pcur;
12                 pcur = pcur->_left;
13             }
14             else if (pcur->_key < key)
15             {
16                 parent = pcur;
17                 pcur = pcur->_right;
18             }
19         }
20         if (pcur == NULL)
21             return false;
22         if (pcur->_left == NULL)      //只有右孩子
23         {
24             //如果pcur就是根節點的話,讓根節點指向根的右
25             if (pcur == _root)
26                 _root = pcur->_right;
27             else if (pcur == parent->_left) 
28             {
29                 parent->_left = pcur->_right;
30             }
31             else
32             {
33                 parent->_right = pcur->_right;
34             }
35             del = pcur;
36         }
37         else if (pcur->_right == NULL)     //只有左孩子
38         {
39            //如果是根節點,讓根節點指向根的左
40             if (pcur == _root)
41                 _root = pcur->_left;
42             else if (parent->_left == pcur)
43             {
44                 parent->_left = pcur->_left;
45             }
46             else
47                 parent->_right = pcur->_left;
48             del = pcur;
49         }
50         //pcur左右孩子都不為空
51         else
52         {
53            //找到節點右子樹的最左節點
54             Node* left = pcur->_right;
55             parent = pcur;
56             while (left->_left)     
57             {
58                 parent=left;
59                 left = left->_left;
60             }
61             del = left;
62             pcur->_key = left->_key;   //交換節點的值
63             if (parent->_left == left)
64             {
65                 parent->_left = left->_right;
66             }
67             else
68             {
69                 parent->_right = left->_right;
70             }
71 
72         }
73         delete del;
74         return true;
75     }

?

轉載于:https://www.cnblogs.com/MrListening/p/5782752.html

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

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

相關文章

AlienVault Ossim各版本鏡像下載地址

AlienVault Ossim各版本鏡像下載地址 OSSIM V5.0.3 ISO網盤下載地址 了解Ossim的架構、工作原理和使用方法可以參考我的新書以及http://edu.51cto.com/course/course_id-1186.html 這里提供的視頻教程。 本文轉自 李晨光 51CTO博客&#xff0c;原文鏈接&#xff1a;http://blo…

面試總結

lru算法&#xff1a;最近最少使用  1.新數據插入到鏈表頭部&#xff1b;  2.每當緩存命中&#xff08;即緩存數據被訪問&#xff09;&#xff0c;則將數據移到鏈表頭部&#xff1b;  3.當鏈表滿的時候&#xff0c;將鏈表尾部的數據丟棄。 自定義控件&#xff1a; 1.measu…

win10+anaconda安裝tensorflow和keras遇到的坑小結

win10下利用anaconda安裝tensorflow和keras的教程都大同小異&#xff08;針對CPU版本&#xff0c;我的gpu是1050TI的MAX-Q&#xff0c;不知為啥一直沒安裝成功&#xff09;&#xff0c;下面簡單說下步驟。 一 Anaconda安裝 一般來說&#xff0c;python選擇3.6的&#xff0c;目…

rman備份恢復命令之switch

一 switch 命令 1 switch命令用途 更新數據文件名為rman下鏡像拷貝時指定的數據文件名 更新數據文件名為 set newname 命令指定的名字。 2 switch 命令使用前提條件 rman 必須連接到目標數據庫 當switch tablespaces、datafiles、tempfiles時&#xff0c;這些文件必須離線 當…

服務核心 - 工具類

雖然類名稱為CWHService&#xff0c;我理解更多的是工具函數。 主要接口功能有&#xff1a; 1&#xff09;SetClipboardString設置字符串到windows剪貼板 2&#xff09;GetMachineID獲取機器標識&#xff0c;網卡地址MD5加密&#xff1b; 3&#xff09;GetMachineIDEx獲取機器標…

現代制造工程課堂筆記07——應力應變分析(考點應力莫爾圓)

目錄 選擇判斷題&#xff0c;簡單計算在莫爾圓那里出 一、單向拉伸中的應力應變 手寫筆記 選擇判斷題&#xff0c;簡單計算在莫爾圓那里出 一、單向拉伸中的應力應變 、 手寫筆記

win10+tensorflow CPU 部署CTPN環境

剛弄明白CTPN部署的時候&#xff0c;CTPN作者剛更新了簡易代碼版本&#xff0c;看介紹是把代碼優化了不需要多的配置。。。感覺好憂傷&#xff01; 源碼地址&#xff1a;https://github.com/eragonruan/text-detection-ctpn/tree/master 新版本地址&#xff1a;https://githu…

css如何實現背景透明,文字不透明?

之前做了個半透明彈層&#xff0c;但設置背景半透明時&#xff0c;子元素包含的字體及其它元素也都變成了半透明。對opacity這個屬性認識的不透徹&#xff0c;在這里做一些總結&#xff0c;方便以后使用。 背景透明&#xff0c;文字不透明的解決方法&#xff1a;為元素添加一個…

SQL Server 使用OPENROWSET訪問ORACLE遇到的各種坑總結

在SQL Server中使用OPENROWSET訪問ORACLE數據庫時&#xff0c;你可能會遇到各種坑&#xff0c;下面一一梳理一下你會遇到的一些坑。 1&#xff1a;數據庫沒有開啟"Ad Hoc Distributed Queries"選項&#xff0c;那么你就會遇到下面坑。 SELECT TOP 10 * FROM OPENROWS…

matlab——FFT傅里葉快速變換

目錄 一、自身的理解與補充 二、其他參考鏈接 一、轉載:https://blog.csdn.net/u013215903/article/details/48091359 FFT是Fast Fourier Transform(快速傅里葉變換)的簡稱,這種算法可以減少計算DFT(離散傅里葉變換,關于此更詳細的說明見后文)的時間,大大提高了運算效…

win10+tensorflow import cv2 bug解決

https://blog.csdn.net/sinat_21591675/article/details/82595812

設計理念 : popup login 在前后臺

popup 意思是一個遮罩層頂在整個網頁最前方&#xff0c;在前臺設計是這樣的&#xff0c;當用戶想在那個界面登入時&#xff0c;就可以有一個遮罩層出現。 在employer或admin&#xff08;后臺&#xff09;操作界面是同個理念&#xff0c;在所有的界面都是有control panel為根節點…

input和raw_input

12345678910python 2#!/usr/bin/env python#coding:utf-8nameraw_input("plese input you name") print namepython3#!/usr/bin/env python#coding:utf-8nameinput("plese input you name") print name本文轉自 小小三郎1 51CTO博客&#xff0c;原文鏈接…

MAATLAB GUI——回調函數的設置(Callbacks)

目錄 1.回調函數創建步驟 1)命令窗口中輸入guide,創建一個新的GUI界面窗口

是什么時候開始學習gulp了

轉自&#xff1a;http://www.ydcss.com/archives/18 簡介&#xff1a; gulp是前端開發過程中對代碼進行構建的工具&#xff0c;是自動化項目的構建利器&#xff1b;她不僅能對網站資源進行優化&#xff0c;而且在開發過程中很多重復的任務能夠使用正確的工具自動完成&#xff1…

011——數組(十一)array_merge array_merge_recursive array_change_key_case

<?php /***/ //array_merge() 將多個數組合并&#xff0c;生成新數組。當鍵名相同時&#xff0c;后者覆蓋前者 /*$array1array(weburl>"bbs.blog.com",webname>"博客"); $array2array(db_hot>"localhost",db_user>"root&qu…

matlab GUI——按下按鈕在指定的坐標下繪制函數圖像

目錄 1.組件布局 2.回調函數設置 3.編寫回調函數 1.組件布局 2.回調函數設置 右鍵單擊plot按鈕——查看回調——call backs

【轉】【UML】使用Visual Studio 2010 Team System中的架構師工具(設計與建模)

Lab 1: 應用程序建模 實驗目標 這個實驗的目的是展示如何在Visual Studio 2010旗艦版中進行應用程序建模。團隊中的架構師會通過建模確定應用程序是否滿足客戶的需求。 你可以創建不同級別的詳細模型&#xff0c;并將它們彼此結合、測試然后發布到你的開發計劃里。 在這個實驗中…