二叉搜索树的插入与删除图解

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

一、二叉搜索树(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     }
时间: 2024-10-13 21:31:08

二叉搜索树的插入与删除图解的相关文章

【算法导论】二叉搜索树的插入和删除

上一篇说了有关二叉树遍历的三种方式,文本将继续探讨如何实现二叉搜索树的插入和删除节点. 在继续之前,我们先来了解两个概念:前驱和后继. 一.后继和前驱 后继:如果所有的关键字互不相同,则一个节点x的后继是大于x.key的最小关键字的节点. 前驱:如果所有的关键字互不相同,则一个节点x的前驱是小于x.key的最大关键字的节点. 如果联系二叉搜索树的性质: 节点的key值总是大于它的左节点(如果存在)的key值并且小于它的右节点(如果存在)的key值.那么我们容易推知:如果一个节点有右子树,它后继即

C++实现二叉搜索树的插入,删除

二叉搜索树即左孩子的值小于根节点,右孩子的值大于根节点. 二叉搜索树的插入: 即检查要插入的数(key,下文都用它表示)是否存在,若存在返回false,不存在即插入,在插入时,若key大于根节点,则插入到右子树中,更新根节点,依次类推:若key小于根节点,则插入到左子树中,更新根节点,以此类推.下面用图表示 现在要插入13,由二叉树的性质可知,13要插到10的右子树上,即 代码实现: bool Insert(const k& key, const v& value) {  if (_roo

二叉搜索树的插入,删除,和中序遍历

构建一个值的类型为int的二叉搜索树,输入N和M,然后进行N次插入操作,每次插入之后进行一次遍历验证代码正确性.然后进行M次删除操作,每次删除之后进行一次遍历验证代码正确性. #include "bits/stdc++.h" using namespace std; typedef long long LL; const int INF = 0x3f3f3f3f; struct BST { int value; BST* lson; BST* rson; }* root; void r

二叉平衡树的插入和删除操作

1.      二叉平衡树 二叉排序树的时间复杂度和树的深度n有关.当先后插入的结点按关键字有序时,二叉排序树退化为单枝树,平均查找长度为(n+1)/2,查找效率比较低.提高查找效率,关键在于最大限度地降低树的深度n.因此需要在构成二叉排序树的过程中进行“平衡化”处理,使之成为二叉平衡树. 二叉平衡树,又称AVL树.它或者是一棵空树,或者是具有下列性质的树: 1)      具备二叉排序树的所有性质: 2)      左子树和右子树深度差的绝对值不超过1: 3)      左子树和右子树都是二叉

二叉搜索树的插入

--------------------siwuxie095 二叉树的插入 程序: BST.h: #ifndef BST_H #define BST_H #include "stdlib.h" #include <queue> //二叉搜索树 template <typename Key, typename Value> class BST { private: struct Node { Key key; Value value; Node *left; No

二叉搜索树的查找与删除

在二叉搜索树中查找一个数,如果存在,则从树中删除. struct Node { Node* left; Node* right; int data; }; void findAndDel(Node*& head, int k) { if (!head) return; Node* node = head; Node* vnode = new Node; vnode->left = vnode->right = head; Node* pnode = vnode; // find nod

Java对二叉搜索树进行插入、查找、遍历、最大值和最小值的操作

1.首先,需要一个节点对象的类.这些对象包含数据,数据代表存储的内容,而且还有指向节点的两个子节点的引用 class Node { public int iData; public double dData; public Node leftChild; public Node rightChild; public void displayNode() { System.out.print("{"); System.out.print(iData); System.out.print(

C++实现二叉搜索树的常用操作

实现操作 (1)二叉搜索树的建立 (2)二叉搜索树的插入 (3)二叉搜索树的三种递归遍历(前序.中序和后续) (4)二叉搜索树的三种非递归遍历(前序.中序和后续) (5)二叉搜索树的逐层打印 (6)搜索某一个字符(递归算法) (7)搜索一个字符(非递归算法) (8)查找最大元素 (9)查找最小元素 有时间再实现: (10)二叉搜索树的前驱和后继查找 (11)二叉搜索树的删除 源码分析: #include <iostream> #include <stack> #include &l

二叉搜索树JavaScript实现

* 什么是二叉搜索树?其形式就是二叉树,对于每个节点x,其左子树的值<=x.value,右子树的值>=x.value. * 对于二叉搜索树,我们可以使用中序遍历,得到树上从小到大所有的元素.时间复杂度平均为O(n). function inorderTreeWalk(x) { if(x!== null) { inorderTreeWalk(x.left); print(x.key); inorderTreeWalk(x.right); } } * 当我们想要查询二叉搜索树中某个关键字应该怎么做