【C++】-- 搜索二叉树(二)

简介: 【C++】-- 搜索二叉树

三、二叉搜索树操作(递归)

理解了非递归操作以后, 递归操作就很简单了:

1. #include<iostream>
2. using namespace std;
3. 
4. //树的节点可以支持多种类型
5. template<class K>
6. //树节点结构
7. struct BSTreeNode
8. {
9.  BSTreeNode<K>* _left;//左指针
10.   BSTreeNode<K>* _right;//右指针
11.   K _key;//值
12. 
13.   //构造函数
14.   BSTreeNode(const K& key)
15.     :_left(nullptr)
16.     , _right(nullptr)
17.     , _key(key)
18.   {}
19. };
20. 
21. template<class K>
22. class BStree//树结构
23. {
24.   typedef BSTreeNode<K> Node;
25. public:
26.   //递归查找
27.   Node* FindR(const K& key)
28.   {
29.     return _FindR(_root, key);
30.   }
31. 
32.   //递归插入
33.   bool InsertR(const K& key)
34.   {
35.     return _InsertR(_root, key);
36.   }
37. 
38.   //递归删除
39.   bool EraseR(const K& key)
40.   {
41.     return _EraseR(_root, key);
42.   }
43. private:
44.   Node* _root;
45. };

 由于_root是私有的,可以把递归子函数查找、插入、删除都定义成私有的

1.二叉搜索树的查找(递归)

递归查找:

1. private:
2. //查找
3.  Node* _FindR(Node* root, const K& key)
4.  {
5.    if (root == nullptr)//没找到
6.    {
7.      return nullptr;
8.    }
9. 
10.     if (key < root->_key)//到左子树去找
11.     {
12.       FindR(root->_left, key);
13.     }
14.     else if (key > root->_key)//到右子树去找
15.     {
16.       FindR(root->_right, key);
17.     }
18.     else//找到了
19.     {
20.       return root;
21.     }
22.   }

2.二叉搜索树的插入(递归)

递归插入:当找到的位置为空时才插入

1.  //插入 加了&,root是_root的别名,修改root就直接修改到上一层调用,不用找父亲
2.  bool _InsertR(Node*& root, const K& key)
3.  {
4.    if (root == nullptr)//找到位置了
5.    {
6.      root = new Node(key);
7.      return true;
8.    }
9.    if (key < root->_key)//到左子树去找位置
10.     {
11.       _InsertR(root->_left, key);
12.     }
13.     else if (key > root->_key)//到右子树去找位置
14.     {
15.       _InsertR(root->_right, key);
16.     }
17.     else//已存在,无需插入
18.     {
19.       return false;
20.     }
21.   }

3.二叉搜索树的删除(递归)

递归删除:和二叉树的删除(非递归)一样,找到后的删除也有两种方式,递归和非递归

找到后的非递归删除:

1. //插入 加了&,root是_root的别名,修改root就直接修改到上一层调用,不用找父亲 
2. bool _EraseR(Node*& root, const K& key)
3.  {
4.    if (root == nullptr)//没找到
5.    {
6.      return false;
7.    }
8.    if (key < root->_key)//到左子树去找
9.    {
10.       _EraseR(root->_left, key);
11.     }
12.     else if (key > root->_key)//到右子树去找
13.     {
14.       _EraseR(root->_right, key);
15.     }
16.     else
17.     {
18.       //找到了,root就是要删除的节点
19.       if (root->_left == nullptr)//root左为空
20.       {
21.         Node* del = root;
22.         root = root->_right;
23.         delete del;
24.       }
25.       else if (root->_right == nullptr)//root右为空
26.       {
27.         Node* del = root;
28.         root = root->_left;
29.         delete del;
30.       }
31.       else//root左右都不为空
32.       {
33.         //找到右子树最左节点替换
34.         Node* minParent = root;
35.         Node* minRight = root->_right;
36. 
37.         while (minRight->_left)
38.         {
39.           minParent = minRight;
40.           minRight = minRight->_left;
41.         }
42. 
43.         //保存替换节点的值
44.         cur->_key = minRight->_key;
45. 
46.         //链接
47.         if (minParent->_left == minRight)
48.         {
49.           minParent->_left = minRight->_right;
50.         }
51.         else
52.         {
53.           minParent->_right = minRight->_right;
54.         }
55. 
56.         //删除
57.         delete minRight;
58.       }
59.       return true;
60.     }
61.   }

找到后的递归删除:

1.      else//root左右都不为空
2.      {       
3. //找右子树最左节点
4.        Node* minRight = root->_right;
5.        while (minRight->_left)
6.        {
7.          minRight = minRight->_left;
8.        }
9. 
10.         //保存右子树最左节点的值
11.         K min = minRight->_key;
12. 
13.         //使用递归方法删除右子树最左节点
14.         _Erase(root->_right, min);
15.       }

四、二叉搜索树的默认成员函数

现在还剩下二叉搜索树的构造、拷贝构造、赋值运算符重载、析构函数。

1.构造

前面已经写过构造函数了, 即只需要把根初始化为空就行了:

1. public:
2.  //构造函数需要将根初始化为空就行了
3.  BSTree()
4.    :_root(nullptr)
5.  {}

2.拷贝构造

拷贝构造利用递归调用子函数不断拷贝节点:

1.  //拷贝构造
2.  BSTree(const BSTree<K>& t)
3.  {
4.    _root = t.copy(t._root);
5.  }

在子函数处:

1.  Node* _copy(Node* root)
2.  {
3.    if (root == nullptr)//如果根为空,直接返回
4.    {
5.      return;
6.    }
7. 
8.    Node* copyNode = new Node(root->_key);//创建根节点
9.    copyNode->_left = _copy(root->_left);//递归拷贝左子树节点
10.     copyNode->_right = _copy(root->_right);//递归拷贝右子树节点
11. 
12.     return copyNode;//返回根
13.   }

3.赋值运算符重载

借助拷贝构造用现代写法写:

1.  //赋值运算符重载(现代写法)
2.  BSTree& operator=(const BSTree<K>& t)
3.  {
4.    swap(_root,t._root);
5.    return *this;
6.  }

4.析构

递归调用子函数去析构

1.  //析构
2.  ~BSTree()
3.  {
4.    _Destroy(_root);
5.    _root = nullptr;
6.  }

在子函数处:

1.  _Destroy(root)
2.  {
3.    if (root == nullptr)
4.    {
5.      return;
6.    }
7.    _Destroy(root->_left);
8.    _Destroy(root->_right);
9.    delete root;
10.   }

相关文章
二叉树进阶面试题(精华总结)【C++版本】
二叉树进阶面试题(精华总结)【C++版本】
118 1
|
存储 编译器 数据库
【C/C++ 数据结构 】线索二叉树全解析:从数学原理到C++实现
【C/C++ 数据结构 】线索二叉树全解析:从数学原理到C++实现
355 0
|
14天前
|
C++
基本二叉树与排序二叉树(C++源码)
本程序实现二叉树基本操作与二叉排序树应用。支持前序建树、四种遍历、求深度、叶子数、第K层节点数及查找功能;并实现二叉排序树的构建、中序输出与查找比较次数统计,分析不同插入顺序对树形态和查找效率的影响。
|
算法 C++ 开发者
【C/C++ 数据结构 】二叉树基本性质:对于任何一颗二叉树T,若其终端结点为n0 ,那么度数为2的结点数为n2。则n0=n2+1...
【C/C++ 数据结构 】二叉树基本性质:对于任何一颗二叉树T,若其终端结点为n0 ,那么度数为2的结点数为n2。则n0=n2+1...
284 0
|
9月前
|
Java C++
【C++数据结构——树】二叉树的基本运算(头歌实践教学平台习题)【合集】
本关任务:编写一个程序实现二叉树的基本运算。​ 相关知识 创建二叉树 销毁二叉树 查找结点 求二叉树的高度 输出二叉树 //二叉树节点结构体定义 structTreeNode{ intval; TreeNode*left; TreeNode*right; TreeNode(intx):val(x),left(NULL),right(NULL){} }; 创建二叉树 //创建二叉树函数(简单示例,手动构建) TreeNode*create
193 12
|
9月前
|
C++
【C++数据结构——树】二叉树的性质(头歌实践教学平台习题)【合集】
本文档介绍了如何根据二叉树的括号表示串创建二叉树,并计算其结点个数、叶子结点个数、某结点的层次和二叉树的宽度。主要内容包括: 1. **定义二叉树节点结构体**:定义了包含节点值、左子节点指针和右子节点指针的结构体。 2. **实现构建二叉树的函数**:通过解析括号表示串,递归地构建二叉树的各个节点及其子树。 3. **使用示例**:展示了如何调用 `buildTree` 函数构建二叉树并进行简单验证。 4. **计算二叉树属性**: - 计算二叉树节点个数。 - 计算二叉树叶子节点个数。 - 计算某节点的层次。 - 计算二叉树的宽度。 最后,提供了测试说明及通关代
169 10
|
9月前
|
存储 算法 测试技术
【C++数据结构——树】二叉树的遍历算法(头歌教学实验平台习题) 【合集】
本任务旨在实现二叉树的遍历,包括先序、中序、后序和层次遍历。首先介绍了二叉树的基本概念与结构定义,并通过C++代码示例展示了如何定义二叉树节点及构建二叉树。接着详细讲解了四种遍历方法的递归实现逻辑,以及层次遍历中队列的应用。最后提供了测试用例和预期输出,确保代码正确性。通过这些内容,帮助读者理解并掌握二叉树遍历的核心思想与实现技巧。
279 3
|
存储 算法 C++
【搜索算法】 跳马问题(C/C++)
【搜索算法】 跳马问题(C/C++)
|
人工智能 算法 Java
【搜索算法】数字游戏(C/C++)
【搜索算法】数字游戏(C/C++)
|
存储 C++
【C++】二叉树进阶之二叉搜索树(下)
【C++】二叉树进阶之二叉搜索树(下)
83 4