C++ 二叉搜索树的实现
二叉树搜索树
二叉搜索树,同时也称为二叉排序树。它可以为一个空树,或者满足二叉搜索树的性质
- 如果左子树不为空时,左子树的值小于双亲结点
- 如果右子树不为空时,右子树的值大于双亲结点
- 同时,它的左右子树也满足二叉搜索树的性质
当对二叉搜索树进行中序遍历时,会得到有序序列,所以又被称为二叉排序树
例如对上图的树进行中序遍历时会产生:【0 1 2 3 4 5 6 7 8 9】
二叉搜索树的操作
- 树的结构
按照模板将树的结构给出
template<class T>
struct BSNode
{BSNode(const T&_data = T()) //构造函数,如果用户没有给参数,则调用默认参数:left(nullptr),right(nullptr),data(_data){}BSNode<T>* left;BSNode<T>* right;T data;
};
- 查找
根据二叉搜索树的性质,左子树的值比根结点的值小,右子树的值比根结点的值大,进行查找。
Node* Find(const T& _data){Node* cur = root;while (cur){if (cur->data < _data)cur = cur->right;else if (cur->data > _data)cur = cur->left;else if (cur->data == _data)return cur;}return nullptr;}
- 插入 bool Insert(const T&_data)
i.先判断二叉搜索树是不是空树,如果是空树直接插入
if(root == nullptr)
{root = BSNode(_data);return true;
}
ii.如果树不为空,则判断要把数值插入的位置
Node *cur = root; //从根结点开始找要插入的位置
Node *parent = nullptr; // 用来保存要插入位置的双亲结点
while(cur)
{parent = cur; //将双亲结点指向curif (cur->data < _data) // 用cur 开始往下查找cur = cur->right;else if (cur->data > _data)cur = cur->left;elsereturn false;
}
iii.找到结点,插入操作
cur = new Node(_data);
if (_data < parent->data) // 用双亲结点来判断,要插入的结点,应给插入到双亲的哪边parent->left = cur;
elseparent->right = cur;
return true;
代码:
bool Insert(const T&_data) //将一个元素插入{if (root == nullptr){root = new Node(_data);return true;}Node* cur = root;Node* parent = nullptr;while (cur){parent = cur;if (cur->data < _data)cur = cur->right;else if (cur->data > _data)cur = cur->left;elsereturn false;}cur = new Node(_data);if (_data < parent->data)parent->left = cur;elseparent->right = cur;return true;}
- 删除 bool Delete(const T& _data)
i.先判断删除的数值在二叉树中,如果不存在,则返回, 否则要删除的结点可能分下面三种情况
a. 待删除结点只有左孩子
b.待删除结点只有右孩子
c.待删除结点左右孩子都存在
在a类情况和b类情况中需要加一个特判(待删除结点为根结点)
bool Delete(const T& _data){if (root == nullptr) //结点为空{return false;}Node* cur = root;Node* parent = nullptr;while (cur){if (_data == cur->data)break;else if (cur->data < _data){parent = cur;cur = cur->right;}else{parent = cur;cur = cur->left;}}if (cur == nullptr) //未找到return false;//1、只有左孩子if (cur->right == nullptr){if (cur == root)root = cur->left;else{if (cur == parent->left){parent->left = cur->left;}else{parent->right = cur->left;}}}//只有右子树else if(cur->left == nullptr){if (cur == root)root = cur->right;else{if (cur == parent->left){parent->left = cur->right;}else{parent->right = cur->right;}}}//左右子树都存在 /*找一个替换的结点:在左子树找最大值,或者在右子树中找最大值,进行替换*/else {if (cur->left != nullptr || cur->right != nullptr){//在右子树中找最小值进行替换Node *replace = cur->right;parent = cur;while (replace->left)//在右子树中最左边的结点值最小{parent = replace;replace = replace->left;}cur->data = replace->data; //将要删除的结点与右子树中最小结点的值进行替换if (replace == parent->left){parent->left = replace->right;}else{parent->right = replace->right;}delete replace;replace = nullptr;}return true;}return false;}
完整代码
template<class T>
struct BSNode
{BSNode(const T&_data = T()):left(nullptr),right(nullptr),data(_data){}BSNode<T>* left;BSNode<T>* right;T data;
};
template<class T>
class BSTree
{typedef BSNode<T> Node;
public:BSTree():root(nullptr){}~BSTree(){Destory(root);}BSTree(const BSTree<T>& t){root = copy(t);}Node *copy(BSTree* t){if (t.root == nullptr)return nullptr;Node *temp = new Node;temp->data = t->root;temp->left = copy(t->left);temp->right = copy(t->right);return temp;}bool Insert(const T&_data) //将一个元素插入{if (root == nullptr){root = new Node(_data);return true;}Node* cur = root;Node* parent = nullptr;while (cur){parent = cur;if (cur->data < _data)cur = cur->right;else if (cur->data > _data)cur = cur->left;elsereturn false;}cur = new Node(_data);if (_data < parent->data)parent->left = cur;elseparent->right = cur;return true;}Node* Find(const T& _data){Node* cur = root;while (cur){if (cur->data < _data)cur = cur->right;else if (cur->data > _data)cur = cur->left;else if (cur->data == _data)return cur;}return nullptr;}bool Delete(const T& _data){if (root == nullptr) //结点为空{return false;}Node* cur = root;Node* parent = nullptr;while (cur){if (_data == cur->data)break;else if (cur->data < _data){parent = cur;cur = cur->right;}else{parent = cur;cur = cur->left;}}if (cur == nullptr) //未找到return false;//1、只有左孩子if (cur->right == nullptr){if (cur == root)root = cur->left;else{if (cur == parent->left){parent->left = cur->left;}else{parent->right = cur->left;}}}//只有右子树else if(cur->left == nullptr){if (cur == root)root = cur->right;else{if (cur == parent->left){parent->left = cur->right;}else{parent->right = cur->right;}}}//左右子树都存在 /*找一个替换的结点:在左子树找最大值,或者在右子树中找最小值,进行替换*/else {if (cur->left != nullptr || cur->right != nullptr){//在右子树中找最小值进行替换Node *replace = cur->right;parent = cur;while (replace->left)//在右子树中最左边的结点值最小{parent = replace;replace = replace->left;}cur->data = replace->data; //将要删除的结点与右子树中最小结点的值进行替换if (replace == parent->left){parent->left = replace->right;}else{parent->right = replace->right;}delete replace;replace = nullptr;}return true;}return false;}private:void Destory(Node*& root){if (root){Destory(root->left);Destory(root->right);root = nullptr;}}Node *root;
};
性能分析:
每次插入或删除结点时都必须进行查找,所以查找的效率决定删除或者插入的效率,最坏情况下,当二叉搜索树为一个单支,其搜索的时间复杂度为O(n)
C++ 二叉搜索树的实现相关推荐
- LeetCode简单题之二叉搜索树的最小绝对差/最小距离
题目 给你一个二叉搜索树的根节点 root ,返回 树中任意两不同节点值之间的最小差值 . 差值是一个正数,其数值等于两值之差的绝对值. 示例 1: 输入:root = [4,2,6,1,3] 输出: ...
- LeetCode简单题之二叉搜索树的范围和
题目 给定二叉搜索树的根结点 root,返回值位于范围 [low, high] 之间的所有结点的值的和. 示例 1: 输入:root = [10,5,15,3,7,null,18], low = 7, ...
- 【剑指Offer】23、二叉搜索树的后序遍历序列
题目描述: 输入一个整数数组,判断该数组是不是某二叉搜索树的后序遍历的结果.如果是则输出Yes,否则输出No.假设输入的数组的任意两个数字都互不相同. 解题思路: 对于后续遍历序列,序 ...
- 消除左递归实验代码_「leetcode」108. 构造二叉搜索树【递归】【迭代】详解!
构造二叉搜索树,一不小心就平衡了 ❞ 108.将有序数组转换为二叉搜索树 将一个按照升序排列的有序数组,转换为一棵高度平衡二叉搜索树. 本题中,一个高度平衡二叉树是指一个二叉树每个节点 的左右两个子树 ...
- 剑指offer:面试题36. 二叉搜索树与双向链表
题目: 二叉搜索树与双向链表 输入一棵二叉搜索树,将该二叉搜索树转换成一个排序的循环双向链表.要求不能创建任何新的节点,只能调整树中节点指针的指向. 为了让您更好地理解问题,以下面的二叉搜索树为例: ...
- 剑指offer:面试题33. 二叉搜索树的后序遍历序列
题目:二叉搜索树的后序遍历序列 输入一个整数数组,判断该数组是不是某二叉搜索树的后序遍历结果.如果是则返回 true,否则返回 false.假设输入的数组的任意两个数字都互不相同. 参考以下这颗二叉搜 ...
- 二叉树:二叉搜索树实现 逆序数问题
关于逆序数的问题描述如下: 已知数组nums,求新数组count,count[i]代表了在nums[i]右侧且比 nums[i]小的元素个数. 例如: nums = [5, 2, 6, 1], cou ...
- 二叉树:二叉搜索树的编码和解码
二叉搜索树的编码和解码描述: 编码:即将一个二叉搜索树编码,节点数值转换为字符串 解码:即将一个字符串解码,数值转换为对应的二叉搜索树的节点 过程导图如下: 针对性编码实现如下: /*数字转字符串*/ ...
- 二叉树:二叉搜索树的创建和插入
二叉搜索树又名二叉排序树. 大概简略的思维导图如下,方便记忆特性 基本二叉搜索树创建过程如下 /*数据结构如下*/ typedef struct tree {int data;struct tree ...
- 6-12 二叉搜索树的操作集
6-12 二叉搜索树的操作集(30 分) 本题要求实现给定二叉搜索树的5种常用操作. 函数接口定义: BinTree Insert( BinTree BST, ElementType X ); Bin ...
最新文章
- Python 标准库之 json
- HDU 4738 Caocao‘s Bridges(桥、任何位运算一定都要加括号、因为有重边所以用前向星)
- 优秀的程序员都在哪里 如何寻找优秀的程序员?
- android WebView总结
- CSS样式----文字样式
- AlertDialog和自定义对话框
- 美团产品顾问马占凯:关于育儿,你需要知道的一切
- Web 3.0 信息聚合的时代
- linux系统 个人使用情况,个人使用Linux操作系统常要做的事
- IIS6.0应用程序池回收和工作进程【转:http://www.cnblogs.com/freshman0216/archive/2008/06/02/1212460.html】...
- Linux 多线程编程使用pthread_creat()函数条件
- AI学习笔记(十四)CNN之图像分割
- Vxscan:一款实用综合扫描工具
- Vue:返回上一个路由
- iOS 网络图片转为UIImage 和微信分享时缩略图片的压缩
- POJ 1182	 食物链
- vue 下载文件的两种方法
- BoundsChecker 使用
- 「津津乐道播客」#380 津津有味:厨房重地举目皆是刚需,将就不得
- MPI中的Bcast, Reduce和Gather使用举例