首先是概念:
二叉搜索树又称二叉排序树,它具有以下的性质:

  • 若是左子树不为空,则左子树上所有节点的值小于根节点的值
  • 若是右子树不为空,则右子树上所有结点的值大于根节点的值
  • 二叉搜索树的左右子树也是二叉搜索树
  • 二叉搜索树的中序排列是一个有序数列

再下来是它的实现

首先是构造节点

 template<class K>
struct BStreeNode{
BStreeNode(const K& date = K()) //节点的定义
:leftC(nullptr), // 初始化
rightC(nullptr),
date_(date)
{}
BStreeNode<K> *leftC; //左孩子
BStreeNode<K> *rightC; //右孩子
K date_;
};

然后是类的实现(具体细节都标在了注释里):

 template<class K>
class BStree{
typedef BStreeNode<K> BsNode;
public:
BStree() :
_root(nullptr)
{}
BsNode* Find(const K& date){ //查找节点
BsNode* pNode = _root;
while (pNode){
if (pNode->date_ == date){
return pNode;
}
else if (pNode->date_ > date){
pNode = pNode->rightC;
}
else
pNode = pNode->leftC;
}
return nullptr;
}
bool Insert(const K& date){
BsNode *pNode = _root;
BsNode *parent=nullptr;
if (_root == nullptr){ //空树时开辟空间定义为根节点
_root = new BsNode(date);
return true;
}
else if (Find(date)){ //存在相同结点不进行插入
return false;
}
else{
while (pNode){ //找到插入位置,但是这里循环结束后只确认了父母结点,是做左孩子还是右孩子不确认( 因为此时值为nullptr )
parent = pNode;
if (pNode->date_ > date){
pNode = pNode->leftC;
}
else{
pNode = pNode->rightC;
}
}
pNode = new BsNode(date); //构造结点
if (parent->date_ > date){ //确认是做左孩子还是右孩子
parent->leftC = pNode;
}
else{
parent->rightC = pNode;
}
return true;
}
} bool Delete(const K& date){
BsNode *pNode = _root;
BsNode *parent = nullptr;
if (pNode == nullptr){ //空树情况
return false;
}
while (pNode){ //找到要删除的结点
if (pNode->date_ == date){
break;
}
else if (pNode->date_ < date){
parent = pNode;
pNode = pNode->rightC;
}
else{
parent = pNode;
pNode = pNode->leftC;
}
}
//BsNode *pdel=pNode;
if (pNode == parent){ //要删除的点是根节点
if (pNode->leftC){
pNode = pNode->leftC;
}
else if (pNode->rightC){
pNode = pNode->rightC;
}
else{
pNode = nullptr;
}
}
if (pNode == nullptr){ // 没有找到要删除的节点
return false;
}
if (pNode->rightC && pNode->leftC == nullptr){ //结点只有右子树
if (pNode == parent->leftC){
parent->leftC = pNode->rightC;
}
else{
parent->rightC = pNode->rightC;
}
}
else if (pNode->leftC && pNode->rightC == nullptr){ //结点只有左子树
if (pNode == parent->leftC){
parent->leftC = pNode->leftC;
}
else{
parent->rightC = pNode->leftC;
}
}
else if (pNode->leftC && pNode->rightC){ //儿女俱全
if (pNode == parent->leftC){ //要删除的节点是父母节点的左孩子,删除后的位置要由原先节点的右孩子替代
pNode->rightC->leftC = pNode->leftC;
parent->leftC = pNode->rightC;
}
else{
pNode->leftC->rightC= pNode->rightC; //要删除的节点是父母节点的右孩子,删除后的位置要由原先节点的左孩子替代
parent->rightC = pNode->leftC;
}
}
else{ //无子可依
if (pNode == parent->leftC){
parent->leftC = nullptr;
}
else{
parent->rightC = nullptr;
}
}
delete pNode; //在连接完成后最后再进行删除
return true;
} BsNode* IfLeftMost(){
if (_root == nullptr){
return nullptr;
}
BsNode *pNode = _root;
while (pNode->leftC){
pNode = pNode->leftC;
}
return pNode;
}
BsNode* IfRightMost(){
if (_root == nullptr){
return nullptr;
}
BsNode *pNode = _root;
while (pNode->rightC){
pNode = pNode->rightC;
}
return pNode;
}
void InOrder(){ //定义一个借口给外部调用,因为根节点在这里是private权限
InOrder(_root);
cout << endl;
} private:
void InOrder(BsNode *pNode){ //二叉树的中序遍历,用来检查结果(二叉搜索树中序遍历应该是一个有序序列)
if (pNode){
InOrder(pNode->leftC);
cout << pNode->date_ << ' ';
InOrder(pNode->rightC);
}
}
private:
BsNode *_root;
};

C++ 二叉搜索树原理及其实现的更多相关文章

  1. java二叉搜索树原理与实现

    计算机里面的数据结构 树 在计算机存储领域应用作用非常大,我之前也多次强调多磁盘的存取速度是目前计算机飞速发展的一大障碍,计算机革命性的的下一次飞跃就是看硬盘有没有质的飞跃,为什么这么说?因为磁盘是永 ...

  2. AVL平衡二叉搜索树原理及各项操作编程实现

    C语言版 #include<stdio.h> #include "fatal.h" struct AvlNode; typedef struct AvlNode *Po ...

  3. 【算法学习】AVL平衡二叉搜索树原理及各项操作编程实现(C语言)

    #include<stdio.h> #include "fatal.h" struct AvlNode; typedef struct AvlNode *Positio ...

  4. BinarySearchTree(二叉搜索树)原理及C++代码实现

    BST是一类用途极广的数据结构.它有如下性质:设x是二叉搜索树内的一个结点.如果y是x左子树中的一个结点,那么y.key<=x.key.如果y是x右子树中的一个结点,那么y.key>=x. ...

  5. [LeetCode] Recover Binary Search Tree 复原二叉搜索树

    Two elements of a binary search tree (BST) are swapped by mistake. Recover the tree without changing ...

  6. 二叉搜索树 (BST) 的创建以及遍历

    二叉搜索树(Binary Search Tree) : 属于二叉树,其中每个节点都含有一个可以比较的键(如需要可以在键上关联值), 且每个节点的键都大于其左子树中的任意节点而小于右子树的任意节点的键. ...

  7. 二叉搜索树的java实现

    转载请注明出处 一.概念 二叉搜索树也成二叉排序树,它有这么一个特点,某个节点,若其有两个子节点,则一定满足,左子节点值一定小于该节点值,右子节点值一定大于该节点值,对于非基本类型的比较,可以实现Co ...

  8. 二叉搜索树、AVL平衡二叉搜索树、红黑树、多路查找树

    1.二叉搜索树 1.1定义 是一棵二叉树,每个节点一定大于等于其左子树中每一个节点,小于等于其右子树每一个节点 1.2插入节点 从根节点开始向下找到合适的位置插入成为叶子结点即可:在向下遍历时,如果要 ...

  9. 编程算法 - 二叉搜索树 与 双向链表 代码(C++)

    二叉搜索树 与 双向链表 代码(C++) 本文地址: http://blog.csdn.net/caroline_wendy 题目:输入一颗二叉搜索树, 将该二叉搜索树转换成一个排序的双向链表. 要求 ...

随机推荐

  1. cf 1179 C

    目录 A B C A 模拟出A不是最大值的情况,存起来. 最多有n个.当A为最大值的时候,后面n-1个数开始循环. 查询分两种情况讨论就行了 #include <bits/stdc++.h> ...

  2. 【概率DP】$P2059$ 卡牌游戏

    链接 题目描述 N个人坐成一圈玩游戏.一开始我们把所有玩家按顺时针从1到N编号.首先第一回合是玩家1作为庄家.每个回合庄家都会随机(即按相等的概率)从卡牌堆里选择一张卡片,假设卡片上的数字为X,则庄家 ...

  3. 同余and乘法逆元学习笔记

    目录 数学符号 快速幂 方法一 方法二 同余 概念 同余的性质 乘法逆元 概念: 求逆元的方法 扩展欧几里得 快速幂法\(o(n*log(n))\) 递推法\(o(n)\) sjp大佬让我写同余那就只 ...

  4. 洛谷 P1621 集合

    目录 题目 思路 \(Code\) 题目 P1621 集合 思路 并查集+埃氏筛,一开始连通块的个数是\(b-a+1\)个,在筛素数的过程中只要当前素数大于\(p\)就对该素数筛出来的数进行判断,如果 ...

  5. jmeter压力测试中的疑难杂症

    概述 大部分新手在用jmeter做压力测试的时候,对一些性能术语十分模糊,直接导致的后果就是对测试出来的结果数据根本不能理解,更谈不上分析了.今天的文章就着重给大家解释一下压力测试中的一些专有名词 问 ...

  6. 一分钟理解什么是REST和RESTful

    从事web开发工作有一小段时间,REST风格的接口,这样的词汇总是出现在耳边,然后又没有完全的理解,您是不是有和我相同的疑问呢?那我们一起来一探究竟吧! 就是用URL定位资源,用HTTP描述操作. 知 ...

  7. linux 下查看redis是否启动

    make make PREFIX=/usr/local/redis install mkdir /etc/redis/ cp redis.conf /etc/redis/ 打开redis.conf文件 ...

  8. 使用uiautomator2自动化测试app(二)------操作篇

    提示: 1. 推荐使用python3以上的版本来进行开发 2. 手机使用安卓手机,版本最好不要太老,一根数据线 3. 安装虚拟机(博主使用雷电) 操作: 这里只简单的介绍一些uiautomator2的 ...

  9. Centos7下把python 2.7升级到python 3.6(升级过程遇到的一些相关问题)

    Centos 7 默认安装的Python 的版本是2.7的,现在不少人用的是3.x上的版本,故而需要了解下如何从Python2.7升级到Python 3.6. 在虚拟机安装时,网络不通会先遇到一个错误 ...

  10. CentOS7.6 X64搭建mysql服务

    1.官方安装文档 http://dev.mysql.com/doc/mysql-yum-repo-quick-guide/en/ 2.下载 Mysql yum包 http://dev.mysql.co ...