二叉搜索树(BST)
(第一段日常扯蛋,大家不要看)这几天就要回家了,osgearth暂时也不想弄了,毕竟不是几天就能弄出来的,所以打算过完年回来再弄。这几天闲着也是闲着,就掏出了之前买的算法导论看了看,把二叉搜索树实现了下。
一、算法导论中讲解
1、二叉搜索树
节点
每个节点包含key(关键字)、left(指向左孩子)、right(指向右孩子)、parent(指向父节点)。
额外可有可无num(相同关键字的节点个数)。
规则
整个二叉树的根节点的parent指向NULL,且唯一。
左子树上所有节点的key均小于其根节点的key。
右子树上所有节点的key均大于其根节点的key。
最低层的节点的left与right指向NULL。
2、二叉搜索树的遍历
二叉搜索树的遍历分为先序遍历,中序遍历,后序遍历(由x.key的输出位置决定)。
中序遍历即为按照key从大到小输出。
3、查询二叉树
循环查找
迭代查找
4、最大关键字元素和最小关键字元素
5、后继和前驱
6、插入
对于BST插入只能插入到最下层,例如插入13。
伪代码:
7、删除
删除分为三种情况
1.删除节点的left(或者right)指向NULL,直接把right(或者left)提升到该节点处。
2.删除节点的right和left不为NULL,且其right的left为NULL,直接把right提升到该节点处。
3.删除节点的right和left不为NULL,且其right的left不为NULL,找到删除节点的后继(即大于删除节点key的最小key所在节点y),把后继y的right提到后继y的位置(即让后继y的parent的left指向后继y的right),再用删除节点的right和left分别代替后继y的right和left,最后再用后继y把删除节点替换掉。
伪代码:
节点替换
删除
三、c++代码
#include <iostream>
#include <memory>
#include <vector> using namespace std; //节点结构
struct Node {
int key;
int num;
shared_ptr<Node> parent;
shared_ptr<Node> left;
shared_ptr<Node> right;
Node(int _key) : key(_key), num(),parent(NULL), left(NULL), right(NULL) {}
}; //循环插入
bool Insert(shared_ptr<Node>& root, int _key) {
shared_ptr<Node> node(new Node(_key));
if (root == NULL) {
root = node;
return true;
}
shared_ptr<Node> x = root;
shared_ptr<Node> y;
while(x != NULL) {
y = x;
if (node->key == x->key) {
x->num++;
return true;
}
if (node->key < x->key) x = x->left;
else x = x->right;
}
if (node->key < y->key) {
y->left = node;
node->parent = y;
}
else {
y->right = node;
node->parent = y;
}
return true;
} //迭代插入
bool reInsert(shared_ptr<Node>& root, shared_ptr<Node> node) {
if (root == NULL) {
root = node;
return true;
}
if (node->key == root->key) {
root->num++;
return true;
}
if (node->key < root->key) return reInsert(root->left, node);
else return reInsert(root->right, node);
} //创建二叉树
void BSTCreat(shared_ptr<Node>& root, vector<int> keys) {
for (int key : keys) {
Insert(root, key);
}
} //遍历
void showBST(shared_ptr<Node>& root) {
if (root != NULL) {
// //cout << root->key << " ";//先序遍历
// showBST(root->left);
// cout << root->key << " "; //中序遍历
// showBST(root->right);
// //cout << root->key << " ";//后序遍历
//cout << root->key << " "; //first
showBST(root->left);
cout << root->key << " "; //mid
showBST(root->right);
//cout << root->key << " "; //end
}
} //删除节点
bool Delete(shared_ptr<Node>& root, int _key) {
if(root == NULL) return false;
if(root->key < _key) return Delete(root->right, _key);
else if(root->key > _key)return Delete(root->left, _key);
else {
if (root->right==NULL) {
root = root->left;
return true;
}
if (root->left==NULL) {
root = root->right;
return true;
}
if (root->right->left==NULL) {
root->right->left = root->left;
root = root->right;
return true;
}
shared_ptr<Node> y = root->right;
while(y->left!=NULL) {
y = y->left;
}
y->parent->left = y->right;
y->right = root->right;
y->left = root->left;
root = y;
return true;
}
} bool isSubtree(shared_ptr<Node> pRootA, shared_ptr<Node> pRootB) {
if (pRootB == NULL) return true;
if (pRootA == NULL) return false;
if (pRootB->key == pRootA->key) {
return isSubtree(pRootA->left, pRootB->left)
&& isSubtree(pRootA->right, pRootB->right);
} else return false;
} bool HasSubtree(shared_ptr<Node> pRootA, shared_ptr<Node> pRootB)
{
if (pRootA == NULL || pRootB == NULL) return false;
return isSubtree(pRootA, pRootB) ||
HasSubtree(pRootA->left, pRootB) ||
HasSubtree(pRootA->right, pRootB);
} int main() {
vector<int> keys1{,,,,,,};
vector<int> keys2{,,}; shared_ptr<Node> root1;
shared_ptr<Node> root2;
BSTCreat(root1, keys1);
BSTCreat(root2, keys2); cerr << HasSubtree(root1, root2) << endl; return ; }
二叉搜索树(BST)的更多相关文章
- C++版 - 剑指offer 面试题24:二叉搜索树BST的后序遍历序列(的判断) 题解
剑指offer 面试题24:二叉搜索树的后序遍历序列(的判断) 题目:输入一个整数数组,判断该数组是不是某二叉搜索树的后序遍历的结果.如果是则返回true.否则返回false.假设输入的数组的任意两个 ...
- 萌新笔记之二叉搜索树(BST)
前言,以前搞过线段树,二叉树觉得也就那样= =.然后数据结构的课也没怎么听过,然后下周期中考... 本来以为今天英语考完可以好好搞ACM了,然后这个数据结构期中考感觉会丢人,还是好好学习一波. 二叉搜 ...
- 给定一个二叉搜索树(BST),找到树中第 K 小的节点
问题:给定一个二叉搜索树(BST),找到树中第 K 小的节点. 出题人:阿里巴巴出题专家:文景/阿里云 CDN 资深技术专家. 考察点: 1. 基础数据结构的理解和编码能力 2. 递归使用 参考答案 ...
- 在二叉搜索树(BST)中查找第K个大的结点之非递归实现
一个被广泛使用的面试题: 给定一个二叉搜索树,请找出其中的第K个大的结点. PS:我第一次在面试的时候被问到这个问题而且让我直接在白纸上写的时候,直接蒙圈了,因为没有刷题准备,所以就会有伤害.(面完的 ...
- 二叉搜索树 (BST) 的创建以及遍历
二叉搜索树(Binary Search Tree) : 属于二叉树,其中每个节点都含有一个可以比较的键(如需要可以在键上关联值), 且每个节点的键都大于其左子树中的任意节点而小于右子树的任意节点的键. ...
- [LeetCode] Convert BST to Greater Tree 将二叉搜索树BST转为较大树
Given a Binary Search Tree (BST), convert it to a Greater Tree such that every key of the original B ...
- 二叉搜索树(BST)学习笔记
BST调了一天,最后遍历参数错了,没药救了-- 本文所有代码均使用数组+结构体,不使用指针! 前言--BFS是啥 BST 二叉搜索树是基于二叉树的一种树,一种特殊的二叉树. 二叉搜索树要么是一颗空树, ...
- hdu 3791:二叉搜索树(数据结构,二叉搜索树 BST)
二叉搜索树 Time Limit : 2000/1000ms (Java/Other) Memory Limit : 32768/32768K (Java/Other) Total Submiss ...
- 数据结构---二叉搜索树BST实现
1. 二叉查找树 二叉查找树(Binary Search Tree),也称为二叉搜索树.有序二叉树(ordered binary tree)或排序二叉树(sorted binary tree),是指一 ...
随机推荐
- Qt 编程指南 3_1 按钮弹窗手动和自动关联示例
触发的两种模式 connect() 和 on_控件ID_控件函数(参数) 两者优缺点对比: 虽然 Qt 有比较好用的自动关联大法,但自动关联不是万能的,尤其是涉及到多个窗体的时候,比如 A 窗体私有按 ...
- 使用js切割URL的参数
对于一些开发场景,不使用Jsp或freemarker及其其他的模板引擎时,通常通过切割url获得对应的参数,然后通过AJAX与后台交互得到对应的数据 下面是演示实例: test.html <!D ...
- 邻接表&链式前向星
链式前向星: 适合点多.边少的情况 不适用于大量遍历出边的题目(因为cache miss) 邻接表: 如果用邻接表来实现的话,一般就用vector嘛,我们都知道vector都是自动扩容的,在空间满了以 ...
- Ansible安装及配置
ansible分为以下几个部份: Ansible:核心引擎 Modules:包括 Ansible 自带的核心模块(core modules)及自定义模块 (custom modules): 核心模块: ...
- stream classdesc serialVersionUID = -7218828885279815404, local class serialVersionUID = 1.
序列化类时出现的异常! 当某一个类实现java.io.Serializable接口时,该类默认会生成一个private static final long serialVersionUID = 1L; ...
- SSM项目layui分页实例
最近学了layui,发现其中的分页挺有意思的,所以整理了一下,一遍自己随时查看.(官方文档上已经很详细了,当中有不足的地方欢迎大家指出) 关于前台的js文件,css样式,js样式,大家可以到官网下 本 ...
- BZOJ 2784 时间流逝
BZOJ 2784 时间流逝 古典概率论... 可以发现由于能量圈数量限制,所以所构成的必定为树状结构(即便是转成最小能量圈和能量圈权值和之后存在重复状态,但是每个状态的含义不同,而且不能自身转移自身 ...
- 如何构造树状 JSON 数据 JSON-Tree
十年河东,十年河西,莫欺骚年穷...打错一个字哈.~_~ 接着上一篇博客,上一篇博客是=使用数据库结合LINQ构造的,为了方便理解,本篇采用泛型分组进行构造. 有兴趣的小虎斑可以参考上一篇博客:如何构 ...
- 【Qt】窗口居中显示
w.move((a.desktop()->width() - w.width())/, (a.desktop()->height() - w.height())/); 上述方法可以置中,但 ...
- Java Web应用开发中的一些概念
最近在学习Java Web,发现Java Web的概念很多,而且各个概念之间的关系也挺复杂,本篇博客把这些关系总结于此,主要参考的博客附在文章末尾. 概念 服务器 服务器,硬件角度上说就是一台高性能的 ...