【二叉搜索树】的详细实现(C++)
二叉搜索树的概念
二叉搜索树的建立
//构造BST
BST(T value) :root(NULL), RefValue(value)
{
T x;
cin >> x;
while (x != RefValue)
{
Insert(x, root); //新建一个结点,调用Insert插入到树中
cin >> x;
}
}
二叉搜索树的插入
//以ptr为根的二叉搜索树中插入所含值为e1的结点
bool Insert(const T& e1, BSTNode<T>* &ptr) //第二个参数是指针的引用
{
if (ptr == NULL)
{
ptr = new BSTNode<T>(e1); //构造新结点
if (ptr == NULL)
{
cout << "Memory allocation failed!" << endl;
exit();
}
return true;
}
else if (e1 < ptr->data) //小于,插入左子树
{
Insert(e1, ptr->left);
}
else if (e1 > ptr->data) //大于,插入右子树
{
Insert(e1, ptr->right);
}
else //x已在树中,不插入
{
return false;
}
}
二叉搜索树的递归搜索
//在ptr为根的二叉搜索树中搜索含x的结点。若找到,返回该结点地址,否则返回NULL
BSTNode<T>* Search(T x, BSTNode<T>* ptr)
{
if (ptr == NULL)
{
return NULL;
}
else if (x < ptr->data)
{
return Search(x, ptr->left);
}
else if (x > ptr->data)
{
return Search(x, ptr->right);
}
else
{
return ptr;
}
}
二叉搜索树的删除
//以ptr为根的二叉搜索树中删除含x的结点
bool Remove(T x, BSTNode<T>* &ptr)
{
BSTNode<T>* temp;
if (ptr != NULL) //ptr不为空进行操作
{
if (x < ptr->data)
{
Remove(x, ptr->left);
}
else if (x > ptr->data)
{
Remove(x, ptr->right);
}
//找到了要删除的结点
//1.要删除的结点ptr同时有左右子树
else if (ptr->left != NULL&&ptr->right != NULL)
{
temp = ptr->right; //在右子树中搜索中序下的第一个结点
while (temp->left != NULL)
{
temp = temp->left;
}
//用右子树中序下的第一个结点的值填充要删除的结点
ptr->data = temp->data;
//然后再新填充值ptr的右子树中删除temp的data值
Remove(ptr->data, ptr->right);
}
else //不同时有左右子树
{
temp = ptr; //temp记住要删除的ptr结点
if (ptr->left == NULL) //只有右子树
{
ptr = ptr->right;
}
else //只有左子树
{
ptr = ptr->left;
}
delete temp; //删除结点
temp = NULL;
return true;
}
}
else //ptr为空直接返回false
{
return false;
}
}
二叉搜索树的销毁
//销毁以root为根的二叉树搜索树函数
void Destroy(BSTNode<T>* &root)
{
if (root == NULL)
{
return;
}
if (root->left != NULL)
{
Destroy(root->left);
}
if (root->right != NULL)
{
Destroy(root->right);
}
delete root;
root = NULL;
}
二叉搜索树的源码
//二叉搜索树结点类型
template<typename T>
struct BSTNode
{
T data; //数据域
BSTNode<T> *left, *right; //左子女、右子女
BSTNode() :left(NULL), right(NULL) {} //构造函数
//构造函数
BSTNode(const T d, BSTNode<T>* L = NULL, BSTNode<T>* R = NULL) :data(d), left(L), right(R) {}
}; //二叉搜索树的定义
template <class T>
class BST
{
public:
//普通构造函数
BST() :root(NULL) {}
//构造BST
BST(T value) :root(NULL), RefValue(value)
{
T x;
cin >> x;
while (x != RefValue)
{
Insert(x, root); //新建一个结点,调用Insert插入到树中
cin >> x;
}
}
//析构
~BST() { Destroy(root); } //插入
bool Insert(T x) { return Insert(x, root); } //删除
bool Remove(T x) { return Remove(x, root); } //搜索
bool Search(T x) { return (Search(x, root) != NULL) ? true : false; } //中序遍历
void InOrder() { InOrder(root); } protected: //以ptr为根的二叉搜索树中插入所含值为e1的结点
bool Insert(const T& e1, BSTNode<T>* &ptr) //第二个参数是指针的引用
{
if (ptr == NULL)
{
ptr = new BSTNode<T>(e1); //构造新结点
if (ptr == NULL)
{
cout << "Memory allocation failed!" << endl;
exit();
}
return true;
}
else if (e1 < ptr->data) //小于,插入左子树
{
Insert(e1, ptr->left);
}
else if (e1 > ptr->data) //大于,插入右子树
{
Insert(e1, ptr->right);
}
else //x已在树中,不插入
{
return false;
}
} //以ptr为根的二叉搜索树中删除含x的结点
bool Remove(T x, BSTNode<T>* &ptr)
{
BSTNode<T>* temp;
if (ptr != NULL) //ptr不为空进行操作
{
if (x < ptr->data)
{
Remove(x, ptr->left);
}
else if (x > ptr->data)
{
Remove(x, ptr->right);
}
//找到了要删除的结点
//1.要删除的结点ptr同时有左右子树
else if (ptr->left != NULL&&ptr->right != NULL)
{
temp = ptr->right; //在右子树中搜索中序下的第一个结点
while (temp->left != NULL)
{
temp = temp->left;
}
//用右子树中序下的第一个结点的值填充要删除的结点
ptr->data = temp->data;
//然后再新填充值ptr的右子树中删除temp的data值
Remove(ptr->data, ptr->right);
}
else //不同时有左右子树
{
temp = ptr; //temp记住要删除的ptr结点
if (ptr->left == NULL) //只有右子树
{
ptr = ptr->right;
}
else //只有左子树
{
ptr = ptr->left;
}
delete temp; //删除结点
temp = NULL;
return true;
}
}
else //ptr为空直接返回false
{
return false;
}
} //在ptr为根的二叉搜索树中搜索含x的结点。若找到,返回该结点地址,否则返回NULL
BSTNode<T>* Search(T x, BSTNode<T>* ptr)
{
if (ptr == NULL)
{
return NULL;
}
else if (x < ptr->data)
{
return Search(x, ptr->left);
}
else if (x > ptr->data)
{
return Search(x, ptr->right);
}
else
{
return ptr;
}
} //中序遍历
void InOrder(BSTNode<T>* root)
{
if (root != NULL)
{
InOrder(root->left);
cout << root->data << " ";
InOrder(root->right);
}
} //销毁以root为根的二叉树搜索树函数
void Destroy(BSTNode<T>* &root)
{
if (root == NULL)
{
return;
}
if (root->left != NULL)
{
Destroy(root->left);
}
if (root->right != NULL)
{
Destroy(root->right);
}
delete root;
root = NULL;
}
private:
BSTNode<T>* root; //根指针
T RefValue; //输入结束标识
}; int main(int argc, char* argv[])
{
//g a e d f h j i l k #
BST<char> tree('#');
tree.InOrder();
cout << endl;
cout << tree.Search('e') << endl;
cout << tree.Insert('z') << endl;
tree.InOrder();
cout << endl;
cout << tree.Remove('z') << endl;
cout << tree.Remove('j') << endl;
tree.InOrder();
cout << endl;
return ;
}
源代码
【二叉搜索树】的详细实现(C++)的更多相关文章
- Interview----判断整数序列是否是二叉搜索树的后序遍历结果
题目:输入一个整数数组,判断该数组是不是某二元查找树的后序遍历的结果. 如果是返回true,否则返回false. 例如输入5.7.6.9.11.10.8,由于这一整数序列是如下树的后序遍历结果: ...
- 【算法与数据结构】二叉搜索树的Java实现
为了更加深入了解二叉搜索树,博主自己用Java写了个二叉搜索树,有兴趣的同学可以一起探讨探讨. 首先,二叉搜索树是啥?它有什么用呢? 二叉搜索树, 也称二叉排序树,它的每个节点的数据结构为1个父节点指 ...
- [CareerCup] 4.6 Find Next Node in a BST 寻找二叉搜索树中下一个节点
4.6 Write an algorithm to find the'next'node (i.e., in-order successor) of a given node in a binary ...
- 在二叉搜索树(BST)中查找第K个大的结点之非递归实现
一个被广泛使用的面试题: 给定一个二叉搜索树,请找出其中的第K个大的结点. PS:我第一次在面试的时候被问到这个问题而且让我直接在白纸上写的时候,直接蒙圈了,因为没有刷题准备,所以就会有伤害.(面完的 ...
- 二叉搜索树、AVL平衡二叉搜索树、红黑树、多路查找树
1.二叉搜索树 1.1定义 是一棵二叉树,每个节点一定大于等于其左子树中每一个节点,小于等于其右子树每一个节点 1.2插入节点 从根节点开始向下找到合适的位置插入成为叶子结点即可:在向下遍历时,如果要 ...
- 剑指offer二十六之二叉搜索树与双向链表
一.题目 输入一棵二叉搜索树,将该二叉搜索树转换成一个排序的双向链表.要求不能创建任何新的结点,只能调整树中结点指针的指向. 二.思路 对二叉搜索树中序遍历的结果即为排序的结果,在中序遍历的过程中,建 ...
- 树-二叉搜索树-AVL树
树-二叉搜索树-AVL树 树 树的基本概念 节点的度:节点的儿子数 树的度:Max{节点的度} 节点的高度:节点到各叶节点的最大路径长度 树的高度:根节点的高度 节点的深度(层数):根节点到该节点的路 ...
- 「面试高频」二叉搜索树&双指针&贪心 算法题指北
本文将覆盖 「字符串处理」 + 「动态规划」 方面的面试算法题,文中我将给出: 面试中的题目 解题的思路 特定问题的技巧和注意事项 考察的知识点及其概念 详细的代码和解析 开始之前,我们先看下会有哪些 ...
- 95题--不同的二叉搜索树II(java、中等难度)
题目描述:给定一个整数 n,生成所有由 1 ... n 为节点所组成的 二叉搜索树 . 示例如下: 分析:这一题需要对比LeetCode96题来分析:https://www.cnblogs.com/K ...
随机推荐
- 《深入理解java虚拟机》读书笔记六——第七章
第七章 虚拟机类加载机制 1.类加载的时机 虚拟机的类加载机制: 虚拟机把描述类的数据从class文件中加载到内存,并对数据进行校验.转换解析和初始化,最终形成了可以被虚拟机直接使用的Java类型,这 ...
- windows安装python64位和32位的方法
1.先安装python 64位的 python,创建一个64位的python虚拟环境: 2.再安装python 32位的 python,创建一个32位的python虚拟环境即可. 注意:两个版本安装在 ...
- [HAOI2011] Problem b - 莫比乌斯反演
复习一下莫比乌斯反演 首先很显然用一下容斥把它转化成求 \(ans=\sum_{i=1}^a \sum_{j=1}^b [{gcd(i,j)=d}]\) 我们可以定义 f(d) 和 F(d) 如下: ...
- Oracle 数据库,远程访问 ora-12541:TNS:无监听程序
1.修改网络连接IPV4设置为固定IP IP地址:192.168.100.8子网掩码:255.255.255.0默认网关:192.168.100.1首选DNS:192.168.100.1 2.修改.. ...
- String.format()的用法记录
stirng.format("redirect:http://%s:%s%s",ip,port,path) 相当于http://localhost:8080/user/list S ...
- sql语言分类及区别、显示和隐示提交的指令
SQL的发展是从1974年开始的,其发展过程如下: 1974年-----由Boyce和Chamberlin提出,当时称SEQUEL. 1976年-----IBM公司的Sanjase研究所在研制RDBM ...
- 在用vue-cli4创建的vue2.x项目中通过vue-fontawesome使用fontawesome5
前言 本文写于2020年1月11日,仅提供最基本的引用方法,参考fontawesome5英文官方文档和vue-fontawesome英文官方文档. 正文 在vue项目中使用fontawesome5图标 ...
- VSCode配置Go插件和第三方拓展包
前言 VSCode现在已经发展的相当完善,很多语言都比较推荐使用其来编写,Go语言也一样,前提你电脑已经有了Go环境和最新版本的VSCode 插件安装 直接在拓展插件中搜索Go,就可以安装Go插件 安 ...
- docker镜像相关的常用操作
1.保存镜像 #docker save 镜像名称 -o 保存的完整地址和文件名 docker save zhoushiya/zhiboyuan -o d:/zhiboyuan.tar 2.载入镜像 # ...
- mysql行级锁 select for update
mysql行级锁 select for update 1.属于行级锁 2.where条件后需要写出明确的索引条件(如果有多个条件,可以建立联合索引) 3.如果其所在的事务提交或者回滚后,或者更新该条数 ...