需要注意的地方:

①二叉搜索树删除一个指定结点R,若R为叶子结点,则将R的父结点中指向R的指针改为指向nullptr;若R的左右子结点一个为空,一个非空,则将R的父结点中指向R的指针改为指向R的非空子结点;若R有两个非空子结点,则找出R的右子树中的最小值结点,将其删除并将R的值置为该最小值结点的值。

②对二叉搜索树进行中序遍历,将得到按升序排序的输出结果。

③使用了多态,二叉搜索树结点类BSTNode继承自抽象类BinNode(二叉树结点类)。

④二叉搜索树不是自平衡的,二叉搜索树的平衡性取决于结点的插入顺序,在极端情况二叉搜索树会退化成链表,查找元素的时间复杂度会退化为O(N)。

代码如下,写在头文件中:

  1 #ifndef BST_H
  2 #define BST_H
  3
  4 #include <iostream>
  5 #include <queue>
  6
  7
  8 /************************************************************************/
  9 /* 抽象二叉树结点类                                                     */
 10 /************************************************************************/
 11 template <typename Val>
 12 class BinNode
 13 {
 14 public:
 15     virtual ~BinNode() {}
 16     virtual bool IsLeaf() const = 0;
 17     virtual Val GetValue() const = 0;
 18     virtual void SetValue(const Val &val_) = 0;
 19     virtual BinNode* GetLeftChild() const = 0;
 20     virtual void SetLeftChild(BinNode *lc) = 0;
 21     virtual BinNode* GetRightChild() const = 0;
 22     virtual void SetRightChild(BinNode *rc) = 0;
 23     virtual void InOrderTraverse() const = 0;
 24 };
 25
 26
 27 /************************************************************************/
 28 /* 二叉搜索树结点类                                                     */
 29 /************************************************************************/
 30 template <typename Key, typename Val>
 31 class BSTNode : public BinNode<Val>
 32 {
 33 public:
 34     BSTNode()
 35         : key(), val(), left_(nullptr), right_(nullptr) {}
 36     BSTNode(const Key &key_, const Val &val_, BSTNode *lc = nullptr, BSTNode *rc = nullptr)
 37         : key(key_), val(val_), left_(lc), right_(rc) {}
 38     ~BSTNode() {}
 39     bool IsLeaf() const { return (left_ == nullptr) && (right_ == nullptr); } //判断是否为叶结点
 40     Key GetKey() const { return key; }
 41     void SetKey(const Key &key_) { key = key_; } //删除结点时用到,其他情况下不可对key值做修改
 42     Val GetValue() const { return val; }
 43     void SetValue(const Val &val_) { val = val_; }
 44     BSTNode* GetLeftChild() const { return left_; }
 45     void SetLeftChild(BinNode<Val> *lc) { left_ = dynamic_cast<BSTNode*>(lc); }
 46     BSTNode* GetRightChild() const { return right_; }
 47     void SetRightChild(BinNode<Val> *rc) { right_ = dynamic_cast<BSTNode*>(rc); }
 48     void InOrderTraverse() const; //中序遍历
 49 private:
 50     Key key;
 51     Val val;
 52     BSTNode *left_;
 53     BSTNode *right_;
 54 };
 55
 56 template <typename Key, typename Val>
 57 void BSTNode<Key, Val>::InOrderTraverse() const
 58 {
 59     if (left_ != nullptr)
 60     {
 61         left_->InOrderTraverse();
 62     }
 63     std::cout << "Key: " << key << ", Value: " << val << "\n";
 64     if (right_ != nullptr)
 65     {
 66         right_->InOrderTraverse();
 67     }
 68 }
 69
 70
 71 /************************************************************************/
 72 /* 二叉搜索树类                                                         */
 73 /************************************************************************/
 74 template <typename Key, typename Val>
 75 class BSTree
 76 {
 77 public:
 78     BSTree()
 79         : root(nullptr), node_num(0) {}
 80     ~BSTree() { Deconstructor(root); }
 81     BSTree(const BSTree &bst) = delete; //禁止编译器生成拷贝构造函数
 82     BSTree& operator=(const BSTree &bst) = delete; //禁止编译器重载拷贝赋值运算符
 83     void InOrderTraverse() const; //中序遍历
 84     void Insert(const Key &key, const Val &val); //插入新结点
 85     Val Delete(const Key &key); //删除指定结点,返回结点的值
 86     Val Find(const Key &key) const; //获取指定key值结点对应的val值
 87     void SetEmpty(); //清空树中所有结点
 88     void BFS() const; //广度优先搜索遍历
 89     unsigned int Size() const { return node_num; }
 90 private:
 91     BSTNode<Key, Val> *root;
 92     unsigned int node_num;
 93     /************************************************************************/
 94     /* 私有函数                                                             */
 95     /************************************************************************/
 96     BSTNode<Key, Val>* Inserter(BSTNode<Key, Val> *root, const Key &key, const Val &val); //插入结点的辅助函数
 97     void Deconstructor(BSTNode<Key, Val> *root); //析构函数的辅助函数,delete所有结点
 98     BSTNode<Key, Val>* GetMinValueNode(BSTNode<Key, Val> *root) const; //找到Key值最小的结点
 99     BSTNode<Key, Val>* DeleteMinValueNode(BSTNode<Key, Val> *root); //删除Key值最小的结点
100     BSTNode<Key, Val>* Deleter(BSTNode<Key, Val> *root, const Key &key); //删除结点的辅助函数
101     Val Finder(BSTNode<Key, Val> *root, const Key &key) const; //找出指定Key值的结点,并返回val的值
102 };
103
104 template <typename Key, typename Val>
105 void BSTree<Key, Val>::InOrderTraverse() const
106 {
107     if (root == nullptr)
108     {
109         return;
110     }
111     std::cout << "Inorder Traverse:\n";
112     root->InOrderTraverse();
113 }
114
115 template <typename Key, typename Val>
116 void BSTree<Key, Val>::Insert(const Key &key, const Val &val)
117 {
118     root = Inserter(root, key, val);
119     ++node_num;
120 }
121
122 template <typename Key, typename Val>
123 BSTNode<Key, Val>* BSTree<Key, Val>::Inserter(BSTNode<Key, Val> *root, const Key &key, const Val &val)
124 {
125     if (root == nullptr)
126     {
127         return new BSTNode<Key, Val>(key, val, nullptr, nullptr);
128     }
129     if (key < root->GetKey())
130     {
131         root->SetLeftChild(Inserter(root->GetLeftChild(), key, val));
132     }
133     else
134     {
135         root->SetRightChild(Inserter(root->GetRightChild(), key, val));
136     }
137     return root;
138 }
139
140 template <typename Key, typename Val>
141 void BSTree<Key, Val>::Deconstructor(BSTNode<Key, Val> *root)
142 {
143     if (root == nullptr)
144     {
145         return;
146     }
147     Deconstructor(root->GetLeftChild());
148     Deconstructor(root->GetRightChild());
149     delete root;
150 }
151
152 template <typename Key, typename Val>
153 BSTNode<Key, Val>* BSTree<Key, Val>::GetMinValueNode(BSTNode<Key, Val> *root) const
154 {
155     if (root->GetLeftChild() == nullptr)
156     {
157         return root;
158     }
159     else
160     {
161         return GetMinValueNode(root->GetLeftChild());
162     }
163 }
164
165 template <typename Key, typename Val>
166 BSTNode<Key, Val>* BSTree<Key, Val>::DeleteMinValueNode(BSTNode<Key, Val> *root)
167 {
168     if (root->GetLeftChild() == nullptr)
169     {
170         return root->GetRightChild();
171     }
172     else
173     {
174         root->SetLeftChild(DeleteMinValueNode(root->GetLeftChild()));
175         return root;
176     }
177 }
178
179 template <typename Key, typename Val>
180 Val BSTree<Key, Val>::Delete(const Key &key)
181 {
182     Val temp_val = Finder(root, key);
183     if (temp_val != Val())
184     {
185         root = Deleter(root, key);
186         --node_num;
187     }
188     return temp_val;
189 }
190
191 template <typename Key, typename Val>
192 BSTNode<Key, Val>* BSTree<Key, Val>::Deleter(BSTNode<Key, Val> *root, const Key &key)
193 {
194     if (root == nullptr)
195         return nullptr;
196     if (key < root->GetKey())
197     {
198         root->SetLeftChild(Deleter(root->GetLeftChild(), key));
199     }
200     else if (key > root->GetKey())
201     {
202         root->SetRightChild(Deleter(root->GetRightChild(), key));
203     }
204     else
205     {
206         if (root->GetLeftChild() == nullptr)
207         {
208             BSTNode<Key, Val> *temp_node = root;
209             root = root->GetRightChild();
210             delete temp_node;
211         }
212         else if (root->GetRightChild() == nullptr)
213         {
214             BSTNode<Key, Val> *temp_node = root;
215             root = root->GetLeftChild();
216             delete temp_node;
217         }
218         else
219         {
220             BSTNode<Key, Val> *temp_node = GetMinValueNode(root->GetRightChild());
221             root->SetValue(temp_node->GetValue());
222             root->SetKey(temp_node->GetKey());
223             root->SetRightChild(DeleteMinValueNode(root->GetRightChild()));
224             delete temp_node;
225         }
226     }
227     return root;
228 }
229
230 template <typename Key, typename Val>
231 Val BSTree<Key, Val>::Find(const Key &key) const
232 {
233     return Finder(root, key);
234 }
235
236 template <typename Key, typename Val>
237 Val BSTree<Key, Val>::Finder(BSTNode<Key, Val> *root, const Key &key) const
238 {
239     if (root == nullptr)
240     {
241         return Val(); //对应的结点不存在,返回Val类型的默认值
242     }
243     if (key < root->GetKey())
244     {
245         return Finder(root->GetLeftChild(), key);
246     }
247     else if (key > root->GetKey())
248     {
249         return Finder(root->GetRightChild(), key);
250     }
251     else
252     {
253         return root->GetValue();
254     }
255 }
256
257 template <typename Key, typename Val>
258 void BSTree<Key, Val>::SetEmpty()
259 {
260     Deconstructor(root);
261     root = nullptr;
262     node_num = 0;
263 }
264
265 template <typename Key, typename Val>
266 void BSTree<Key, Val>::BFS() const
267 {
268     std::queue<BSTNode<Key, Val>*> node_queue;
269     node_queue.push(root);
270     BSTNode<Key, Val> *temp_node = nullptr;
271     std::cout << "Breadth First Search Traverse:\n";
272     while (!node_queue.empty())
273     {
274         temp_node = node_queue.front();
275         node_queue.pop();
276         std::cout << "Key: " << temp_node->GetKey() << ", Value: " << temp_node->GetValue() << "\n";
277         if (temp_node->GetLeftChild() != nullptr)
278         {
279             node_queue.push(temp_node->GetLeftChild());
280         }
281         if (temp_node->GetRightChild() != nullptr)
282         {
283             node_queue.push(temp_node->GetRightChild());
284         }
285     }
286 }
287
288 #endif

转载于:https://www.cnblogs.com/jzincnblogs/p/5333641.html

使用C++实现二叉搜索树的数据结构相关推荐

  1. 二叉搜索树 【数据结构】

    二叉搜索树 概念 特点 基本操作 1.插入元素 2.查找元素 3.删除元素 概念 二叉搜索树是一种特殊的二叉树 特点 左子树中的值都小于根节点,右子树中的值都大于根节点 故:中序遍历结果就会得到一个有 ...

  2. 二叉搜索树简介和部分题目

    引言 二叉搜索树是一个有序树,遵循以下规则: 若它的左子树不空,则左子树上所有结点的值均小于它的根结点的值: 若它的右子树不空,则右子树上所有结点的值均大于它的根结点的值: 它的左.右子树也分别为二叉 ...

  3. c++实现二叉搜索树

    自己实现了一下二叉搜索树的数据结构.记录一下: #include <iostream>using namespace std;struct TreeNode{int val;TreeNod ...

  4. 有序二叉树c语言,二叉搜索树(BST)的实现(C语言)(原创)

    叉搜索树(Binary Search Tree)的一般形式如下图所示,每个节点中的元素大于它的左子树中的所有元素,小于它的右子树中的所有元素.对该图中的二叉树进行中序遍历得到一个从小到大排列的有序序列 ...

  5. 剑指offer | 面试题54:二叉搜索树的第k大节点

    转载本文章请标明作者和出处 本文出自<Darwin的程序空间> 本文题目和部分解题思路来源自<剑指offer>第二版 开始行动,你已经成功一半了,献给正在奋斗的我们 题目 给定 ...

  6. 二叉搜索树(BST)——基本概念及基本实现代码

    二叉搜索树(BST)--基本概念及基本实现代码 1.二叉搜索树概念 二叉搜索树是以一棵二叉树来组织的.每个节点是一个对象,包含的属性有left,right,p和key,其中,left指向该节点的左孩子 ...

  7. java 二叉查找树_如何在Java中实现二叉搜索树( binary search tree)?

    二叉搜索树或BST是一种流行的数据结构,用于保持元素的顺序.二叉搜索树是二叉树,其中左子节点的值小于或等于父节点,右子节点的值大于或等于父节点.由于它是二叉树,它只能有0,1或2个子节点.二叉搜索树之 ...

  8. 数据结构之二叉搜索树(BST)

    数据结构之二叉搜索树(BST) 1. 二叉搜索树定义 二叉搜索树(Binary Search Tree),又名二叉排序树(Binary Sort Tree). 二叉搜索树是具有有以下性质的二叉树: ( ...

  9. 数据结构之二叉搜索树/二叉查找数/有序二叉树/排序二叉树

    概念~ 二叉查找树(英语:Binary Search Tree),也称二叉搜索树.有序二叉树(英语:ordered binary tree),排序二叉树(英语:sorted binary tree), ...

最新文章

  1. Widget上实时刷新图片,造成anr问题
  2. 【thymeleaf】分页代码
  3. 【BZOJ 2432】 [Noi2011]兔农 矩乘+数论
  4. 【sklearn学习】数据预处理和特征工程
  5. vue 如何获取图片的原图尺寸_公众号封面图片尺寸是多少?如何在公众号里制作封面图?...
  6. 调试LCD反被调戏了
  7. 怎样快速画出一个正方体_小学数学非常有效的“画图”解题法,快速解题的“金钥匙”...
  8. 如何使用JavaScript 结合XSLT转换XML文档
  9. Access2016学习1
  10. The following paths are ignored by one of your .gitignore
  11. 受保护的Word文档如何编辑?
  12. 虚拟机全屏后隐藏vmware菜单栏的问题
  13. 2021的科技卦象·雷·到元宇宙玩“躲猫猫”
  14. java微信公众号短信验证码_解决微信端公众号网页获取短信验证码ajax重复调用两次的问题...
  15. 逐梦电竞:雷神“光追”游戏电脑新年首发
  16. 搜索框输入内容进行查找匹配
  17. 列表/元组/切片/字典/字符串处理方法
  18. 组件化之路 - ViewModel一知半解
  19. 英辞流——坚若金刚与穿行无碍:物质的三态
  20. 手把手教你将普通wifi路由器变为智能广告路由器

热门文章

  1. python怎么存为动图_Python将视频或者动态图gif逐帧保存为图片的方法
  2. 【CCCC】L3-019 代码排版 (30分),大模拟
  3. 【Luogu1631】序列合并(优先队列)
  4. 微信h5实现分享给朋友url改变_h5微信自定义分享
  5. 示波器1m和50欧姆示阻抗匹配_为什么示波器阻抗一般是1M欧或者50欧
  6. 农行运营合规管理心得体会_老员工写诗讲述农行40年运营风采
  7. JSP→基本语法/静态内容/指令/动作/表达式/小脚本(Scriptlet)/声明/注释、JSP页面声明周期、代码样例、九大隐式内置对象及方法代码样例
  8. JQueryDOM之修改节点
  9. 并查集路径压缩和按rank合并代码实现
  10. printf()的冷门用法+格子中输出--蓝桥杯