需要注意的地方:

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

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

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

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

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

 #ifndef BST_H
#define BST_H #include <iostream>
#include <queue> /************************************************************************/
/* 抽象二叉树结点类 */
/************************************************************************/
template <typename Val>
class BinNode
{
public:
virtual ~BinNode() {}
virtual bool IsLeaf() const = ;
virtual Val GetValue() const = ;
virtual void SetValue(const Val &val_) = ;
virtual BinNode* GetLeftChild() const = ;
virtual void SetLeftChild(BinNode *lc) = ;
virtual BinNode* GetRightChild() const = ;
virtual void SetRightChild(BinNode *rc) = ;
virtual void InOrderTraverse() const = ;
}; /************************************************************************/
/* 二叉搜索树结点类 */
/************************************************************************/
template <typename Key, typename Val>
class BSTNode : public BinNode<Val>
{
public:
BSTNode()
: key(), val(), left_(nullptr), right_(nullptr) {}
BSTNode(const Key &key_, const Val &val_, BSTNode *lc = nullptr, BSTNode *rc = nullptr)
: key(key_), val(val_), left_(lc), right_(rc) {}
~BSTNode() {}
bool IsLeaf() const { return (left_ == nullptr) && (right_ == nullptr); } //判断是否为叶结点
Key GetKey() const { return key; }
void SetKey(const Key &key_) { key = key_; } //删除结点时用到,其他情况下不可对key值做修改
Val GetValue() const { return val; }
void SetValue(const Val &val_) { val = val_; }
BSTNode* GetLeftChild() const { return left_; }
void SetLeftChild(BinNode<Val> *lc) { left_ = dynamic_cast<BSTNode*>(lc); }
BSTNode* GetRightChild() const { return right_; }
void SetRightChild(BinNode<Val> *rc) { right_ = dynamic_cast<BSTNode*>(rc); }
void InOrderTraverse() const; //中序遍历
private:
Key key;
Val val;
BSTNode *left_;
BSTNode *right_;
}; template <typename Key, typename Val>
void BSTNode<Key, Val>::InOrderTraverse() const
{
if (left_ != nullptr)
{
left_->InOrderTraverse();
}
std::cout << "Key: " << key << ", Value: " << val << "\n";
if (right_ != nullptr)
{
right_->InOrderTraverse();
}
} /************************************************************************/
/* 二叉搜索树类 */
/************************************************************************/
template <typename Key, typename Val>
class BSTree
{
public:
BSTree()
: root(nullptr), node_num() {}
~BSTree() { Deconstructor(root); }
BSTree(const BSTree &bst) = delete; //禁止编译器生成拷贝构造函数
BSTree& operator=(const BSTree &bst) = delete; //禁止编译器重载拷贝赋值运算符
void InOrderTraverse() const; //中序遍历
void Insert(const Key &key, const Val &val); //插入新结点
Val Delete(const Key &key); //删除指定结点,返回结点的值
Val Find(const Key &key) const; //获取指定key值结点对应的val值
void SetEmpty(); //清空树中所有结点
void BFS() const; //广度优先搜索遍历
unsigned int Size() const { return node_num; }
private:
BSTNode<Key, Val> *root;
unsigned int node_num;
/************************************************************************/
/* 私有函数 */
/************************************************************************/
BSTNode<Key, Val>* Inserter(BSTNode<Key, Val> *root, const Key &key, const Val &val); //插入结点的辅助函数
void Deconstructor(BSTNode<Key, Val> *root); //析构函数的辅助函数,delete所有结点
BSTNode<Key, Val>* GetMinValueNode(BSTNode<Key, Val> *root) const; //找到Key值最小的结点
BSTNode<Key, Val>* DeleteMinValueNode(BSTNode<Key, Val> *root); //删除Key值最小的结点
BSTNode<Key, Val>* Deleter(BSTNode<Key, Val> *root, const Key &key); //删除结点的辅助函数
Val Finder(BSTNode<Key, Val> *root, const Key &key) const; //找出指定Key值的结点,并返回val的值
}; template <typename Key, typename Val>
void BSTree<Key, Val>::InOrderTraverse() const
{
if (root == nullptr)
{
return;
}
std::cout << "Inorder Traverse:\n";
root->InOrderTraverse();
} template <typename Key, typename Val>
void BSTree<Key, Val>::Insert(const Key &key, const Val &val)
{
root = Inserter(root, key, val);
++node_num;
} template <typename Key, typename Val>
BSTNode<Key, Val>* BSTree<Key, Val>::Inserter(BSTNode<Key, Val> *root, const Key &key, const Val &val)
{
if (root == nullptr)
{
return new BSTNode<Key, Val>(key, val, nullptr, nullptr);
}
if (key < root->GetKey())
{
root->SetLeftChild(Inserter(root->GetLeftChild(), key, val));
}
else
{
root->SetRightChild(Inserter(root->GetRightChild(), key, val));
}
return root;
} template <typename Key, typename Val>
void BSTree<Key, Val>::Deconstructor(BSTNode<Key, Val> *root)
{
if (root == nullptr)
{
return;
}
Deconstructor(root->GetLeftChild());
Deconstructor(root->GetRightChild());
delete root;
} template <typename Key, typename Val>
BSTNode<Key, Val>* BSTree<Key, Val>::GetMinValueNode(BSTNode<Key, Val> *root) const
{
if (root->GetLeftChild() == nullptr)
{
return root;
}
else
{
return GetMinValueNode(root->GetLeftChild());
}
} template <typename Key, typename Val>
BSTNode<Key, Val>* BSTree<Key, Val>::DeleteMinValueNode(BSTNode<Key, Val> *root)
{
if (root->GetLeftChild() == nullptr)
{
return root->GetRightChild();
}
else
{
root->SetLeftChild(DeleteMinValueNode(root->GetLeftChild()));
return root;
}
} template <typename Key, typename Val>
Val BSTree<Key, Val>::Delete(const Key &key)
{
Val temp_val = Finder(root, key);
if (temp_val != Val())
{
root = Deleter(root, key);
--node_num;
}
return temp_val;
} template <typename Key, typename Val>
BSTNode<Key, Val>* BSTree<Key, Val>::Deleter(BSTNode<Key, Val> *root, const Key &key)
{
if (root == nullptr)
return nullptr;
if (key < root->GetKey())
{
root->SetLeftChild(Deleter(root->GetLeftChild(), key));
}
else if (key > root->GetKey())
{
root->SetRightChild(Deleter(root->GetRightChild(), key));
}
else
{
if (root->GetLeftChild() == nullptr)
{
BSTNode<Key, Val> *temp_node = root;
root = root->GetRightChild();
delete temp_node;
}
else if (root->GetRightChild() == nullptr)
{
BSTNode<Key, Val> *temp_node = root;
root = root->GetLeftChild();
delete temp_node;
}
else
{
BSTNode<Key, Val> *temp_node = GetMinValueNode(root->GetRightChild());
root->SetValue(temp_node->GetValue());
root->SetKey(temp_node->GetKey());
root->SetRightChild(DeleteMinValueNode(root->GetRightChild()));
delete temp_node;
}
}
return root;
} template <typename Key, typename Val>
Val BSTree<Key, Val>::Find(const Key &key) const
{
return Finder(root, key);
} template <typename Key, typename Val>
Val BSTree<Key, Val>::Finder(BSTNode<Key, Val> *root, const Key &key) const
{
if (root == nullptr)
{
return Val(); //对应的结点不存在,返回Val类型的默认值
}
if (key < root->GetKey())
{
return Finder(root->GetLeftChild(), key);
}
else if (key > root->GetKey())
{
return Finder(root->GetRightChild(), key);
}
else
{
return root->GetValue();
}
} template <typename Key, typename Val>
void BSTree<Key, Val>::SetEmpty()
{
Deconstructor(root);
root = nullptr;
node_num = ;
} template <typename Key, typename Val>
void BSTree<Key, Val>::BFS() const
{
std::queue<BSTNode<Key, Val>*> node_queue;
node_queue.push(root);
BSTNode<Key, Val> *temp_node = nullptr;
std::cout << "Breadth First Search Traverse:\n";
while (!node_queue.empty())
{
temp_node = node_queue.front();
node_queue.pop();
std::cout << "Key: " << temp_node->GetKey() << ", Value: " << temp_node->GetValue() << "\n";
if (temp_node->GetLeftChild() != nullptr)
{
node_queue.push(temp_node->GetLeftChild());
}
if (temp_node->GetRightChild() != nullptr)
{
node_queue.push(temp_node->GetRightChild());
}
}
} #endif

使用C++实现二叉搜索树的数据结构的更多相关文章

  1. hdu 3791:二叉搜索树(数据结构,二叉搜索树 BST)

    二叉搜索树 Time Limit : 2000/1000ms (Java/Other)   Memory Limit : 32768/32768K (Java/Other) Total Submiss ...

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

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

  3. [数据结构]——二叉树(Binary Tree)、二叉搜索树(Binary Search Tree)及其衍生算法

    二叉树(Binary Tree)是最简单的树形数据结构,然而却十分精妙.其衍生出各种算法,以致于占据了数据结构的半壁江山.STL中大名顶顶的关联容器--集合(set).映射(map)便是使用二叉树实现 ...

  4. 【算法与数据结构】二叉搜索树的Java实现

    为了更加深入了解二叉搜索树,博主自己用Java写了个二叉搜索树,有兴趣的同学可以一起探讨探讨. 首先,二叉搜索树是啥?它有什么用呢? 二叉搜索树, 也称二叉排序树,它的每个节点的数据结构为1个父节点指 ...

  5. 数据结构之二叉搜索树、AVL自平衡树

    前言 最近在帮公司校招~~ 所以来整理一些数据结构方面的知识,这些知识呢,光看一遍理解还是很浅的,看过跟动手做过一遍的同学还是很容易分辨的哟~ 一直觉得数据结构跟算法,就好比金庸小说里的<九阳神 ...

  6. 自己动手实现java数据结构(六)二叉搜索树

    1.二叉搜索树介绍 前面我们已经介绍过了向量和链表.有序向量可以以二分查找的方式高效的查找特定元素,而缺点是插入删除的效率较低(需要整体移动内部元素):链表的优点在于插入,删除元素时效率较高,但由于不 ...

  7. 用Python实现数据结构之二叉搜索树

    二叉搜索树 二叉搜索树是一种特殊的二叉树,它的特点是: 对于任意一个节点p,存储在p的左子树的中的所有节点中的值都小于p中的值 对于任意一个节点p,存储在p的右子树的中的所有节点中的值都大于p中的值 ...

  8. 【Java】 大话数据结构(11) 查找算法(2)(二叉排序树/二叉搜索树)

    本文根据<大话数据结构>一书,实现了Java版的二叉排序树/二叉搜索树. 二叉排序树介绍 在上篇博客中,顺序表的插入和删除效率还可以,但查找效率很低:而有序线性表中,可以使用折半.插值.斐 ...

  9. 数据结构-二叉搜索树(BST binary search tree)

    本文由@呆代待殆原创,转载请注明出处:http://www.cnblogs.com/coffeeSS/ 二叉搜索树简介 顾名思义,二叉搜索树是以一棵二叉树来组织的,这样的一棵树可以用一个链表数据结构来 ...

随机推荐

  1. word安装mathtype

    1:window版本的mathtype:https://pan.baidu.com/s/1Yn8kPG9Y9nBPGaotFJaL2Q  ,密码spwm 2:点击exe安装   (安装到c盘,将不会出 ...

  2. 用Python实现的数据结构与算法:堆栈

    一.概述 堆栈(Stack)是一种后进先出(LIFO)的线性数据结构,对堆栈的插入和删除操作都只能在栈顶(top)进行. 二.ADT 堆栈ADT(抽象数据类型)一般提供以下接口: Stack() 创建 ...

  3. Python实现支付宝在线支付

    windows系统安装Python虚拟环境 首先保证你的系统已经安装好了Python 安装virtualenv C:\WINDOWS\system32>pip3 install virtuale ...

  4. C# 使用BackgroundWorker实现WinForm异步

    写了一个基于BackgorundWorker演示异步操作的例子.由于这个理基本上实现了BackgorundWorker的大部分功能:异步操作的启动.操作结束后的回调.异步操作的撤销和进度报告等等.尽管 ...

  5. (5)调度器(scheduler)

    继承关系 原理介绍 Cocos2d-x调度器为游戏提供定时事件和定时调用服务.所有Node对象都知道如何调度和取消调度事件,使用调度器有几个好处: 每当Node不再可见或已从场景中移除时,调度器会停止 ...

  6. VS2010/MFC编程入门之二十三(常用控件:按钮控件的编程实例)

    上一节VS2010/MFC编程入门教程中鸡啄米讲了按钮控件Button.Radio Button和Check Box的基本用法,本节就继续讲按钮控件的内容,通过一个实例让大家更清楚按钮控件在实际的软件 ...

  7. Bootstrap风格zTree树形菜单插件

    这是一款bootstrap风格jQuery zTree树形菜单插件,支持自定义编辑.添加列表菜单.删除列表等功能的jQuery树形菜单代码.在线演示 具体代码实现: <!DOCTYPE html ...

  8. Sublime Text 3图标更改

    Sublime Text 3图标更改 步骤: 1.下载ico图标 2.然后更改图标 注意:重点讲解下,如何将png文件转换为ico图标: 网络上单独找sublime text 3的ico图标比较不好找 ...

  9. (转载)Ubuntu 16.04+1080Ti机器学习基本环境配置

    转载自:https://blog.csdn.net/mahonesun/article/details/80808930 一.设置网络 机器有两张网卡,将当前正在使用的"有线连接1" ...

  10. 【转载】make: Nothing to be done for `all'. 解决方法

    转自:make: Nothing to be done for `all'.解决方法 make: Nothing to be done for `all' 解决方法 1.这句提示是说明你已经编译好了, ...