二分查找树按照key值划分
#include <iostream>
#include <vector>
#include <algorithm>
#include <string>
#include <map>
#include <set>
#include <string.h>
#include <stdio.h>
#include <unistd.h>
#include <cstdio>
#include <queue>
using namespace std; class TreeNode{
public:
int val;
TreeNode *left;
TreeNode *right;
TreeNode(int v):val(v),left(nullptr),right(nullptr){}
}; TreeNode* buildBST(vector<int> &data,int s,int e){
TreeNode *root = nullptr;
if(s<=e) {
int mid = (s + e) / 2;
root = new TreeNode(data[mid]);
root->left = buildBST(data,s,mid-1);
root->right = buildBST(data,mid+1,e);
}
return root;
} bool checkBST(TreeNode *root){
if(root== nullptr){
return true;
}
int rootv = root->val;
bool isleft = true;
bool isright = true;
if(root->left){
isleft = rootv >=root->left->val? true:false;
isleft = isleft && checkBST(root->left);
}
if(root->right){
isright = rootv < root->right->val? true:false;
isright = isright && checkBST(root->right);
}
return isleft&&isright;
} void printBST(TreeNode *root){
deque<TreeNode*> myd;
myd.push_back(root);
int num = 1;
int nextlineNumbers = 0;
while(!myd.empty()){
while(num--){
TreeNode *t = myd[0];
if(t->left){
nextlineNumbers++;
myd.push_back(t->left);
}
if(t->right){
nextlineNumbers++;
myd.push_back(t->right);
}
cout<<t->val<<" ";
myd.pop_front();
}cout<<endl;
num = nextlineNumbers;
nextlineNumbers = 0;
}//while
} /*根据bst的性质,我们只需要对树的边界边调整即可,
* 树的边界边分为下面两种;
> //大于key
/
/
<= //小于等于key
后者是
<= //小于等于key
\
\
> //大于key
* */
//我当时卡在了BST树的性质对于这道题的认知,
//对root节点的左子树中所有的节点值都比root节点小
//对root节点的右子树中所有的节点值都比root节点大
//将边界边切开,分为左右两个树,按照性质,只需要对两棵树其中的一课继续做拆分操作即可。
vector<TreeNode*> splitByKey(TreeNode *root,int key){
vector<TreeNode*> re;
TreeNode *r1,*r2;//分别指向被拆开得新bst树的,左侧部分和右侧部分;
r1 = r2 = nullptr;
if(root== nullptr){//对于叶子节点来说,查分完后的两部分都是nullptr
re.push_back(nullptr);
re.push_back(nullptr);
return re;
}
TreeNode *curr = root;//当前访问节点,为了找到被分割的临界边,指向临界边的“上节点”
while(curr->val<=key && curr->right){//将curr节点向右下划行
if(curr->right->val > key){
break;
}
curr= curr->right;
} while(curr->val > key && curr->left){//将curr节点向左下划行
if(curr->left->val <= key){
break;
}
curr = curr->left;
}
if(curr->val <= key){
r1 = root;
r2 = curr->right;
curr->right = nullptr;
if(r2!= nullptr){
vector<TreeNode*> t = splitByKey(r2,key);
curr->right = t[0];
r2 = t[1];
}
}else{
r1 = curr->left;
r2 = root;
curr->left = nullptr;
if(r1!= nullptr){
vector<TreeNode*> t = splitByKey(r1,key);
curr->left = t[1];
r1 = t[0];
}
}
re.push_back(r1);
re.push_back(r2);
return re;
} int main(){
vector<int> data;
for(int i = 0;i<10;i++){
data.push_back(i);
} TreeNode *root = buildBST(data,0,data.size()-1);
printBST(root);
cout<<"=========="<<endl;
vector<TreeNode*> re = splitByKey(root,5);
printBST(re[0]);
cout<<"check left bst: "<<checkBST(re[0])<<endl;
cout<<"==="<<endl;
printBST(re[1]);
cout<<"check right bst: "<<checkBST(re[1])<<endl;
return false;
}
二分查找树按照key值划分的更多相关文章
- Go 数据结构--二分查找树
Go 数据结构--二分查找树 今天开始一个Go实现常见数据结构的系列吧.有时间会更新其他数据结构. 一些概念 二叉树:二叉树是每个节点最多有两个子树的树结构. 完全二叉树:若设二叉树的高度为h,除第 ...
- 手把手教你用java实现二分查找树及其相关操作
二分查找树(Binary Search Tree)的基本操作有搜索.求最大值.求最小值.求前继.求后继.插入及删除. 对二分查找树的进行基本操作所花费的时间与树的高度成比例.例如有n个节点的完全二叉树 ...
- 笔试算法题(58):二分查找树性能分析(Binary Search Tree Performance Analysis)
议题:二分查找树性能分析(Binary Search Tree Performance Analysis) 分析: 二叉搜索树(Binary Search Tree,BST)是一颗典型的二叉树,同时任 ...
- lintcode-106-排序列表转换为二分查找树
106-排序列表转换为二分查找树 给出一个所有元素以升序排序的单链表,将它转换成一棵高度平衡的二分查找树 样例 标签 递归 链表 思路 类似于二分查找,每次将链表二分,中间节点作为根节点,在建立左子树 ...
- SPOJ TEMPLEQ - Temple Queues(二分查找+树状数组)
题意: 有N个队伍(1 <= N <= 100,000),每个队伍开始有ai个人[0 <= ai<= 100,000,000],有Q个操作[0<=Q<= 500,0 ...
- python数据结构之树(二分查找树)
本篇学习笔记记录二叉查找树的定义以及用python实现数据结构增.删.查的操作. 二叉查找树(Binary Search Tree) 简称BST,又叫二叉排序树(Binary Sort Tree),是 ...
- Holedox Eating HDU - 4302 2012多校C 二分查找+树状数组/线段树优化
题意 一个长度$n<=1e5$的数轴,$m<=1e5$个操作 有两种一些操作 $0$ $x$ 在$x$放一个食物 $1$ 一个虫子去吃最近的食物,如果有两个食物一样近,不转变方向的去吃 ...
- 51nod1287(二分/线段树区间最值&单点更新)
题目链接:http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1287 题意:中文题诶- 解法1:b[i] 存储 max(a[0 ...
- js二分查找树实现
function BinaryTree() { var Node = function(key) { this.key = key; this.left = null; this.right = nu ...
随机推荐
- 卷积神经网络CNN理解
自今年七月份以来,一直在实验室负责卷积神经网络(Convolutional Neural Network,CNN),期间配置和使用过theano和cuda-convnet.cuda-convnet2. ...
- 第十五章 函数————函数的递归、生成器send 、匿名函数
1.生成器send方法 send的工作原理 1.send发生信息给当前停止的yield 2.再去调用__next__()方法,生成器接着往下指向,返回下一个yield值并停止 例: persons=[ ...
- JS无限添加HTML到指定位置
用JS把HTML添加到指定位置有两种写法,一种是用字符串,一种是用javascript中的方法 第一种: 用字符串写 <h2>利用JS无限添加一个相同部分</h2> <h ...
- 最近的阅读list
fast rcnn 统一了sppnet和rcnn,将原来rcnn分stage的训练合为一个整体的stage,一次完成cls, regression的训练.引入两个loss函数,一个是用来进行cls的, ...
- C编程经验总结5(剧终)
Prolog是AI编程语言 Git(分布式) svn(集中式) commit(委托,犯罪) patch补丁) merge(融入) repository(仓库) Ctrl+s(保存) r ...
- jquery 操作css 尺寸
.height() 获取元素集合中的第一个元素的当前计算高度值,或设置每一个匹配元素的高度值. .height() 获取匹配元素集合中的第一个元素的当前计算高度值. 这个方法不接受参数. $(wind ...
- 全文检索(Lucene&Solr)
全文检索(Lucene&Solr) 1)什么是全文检索?为什么需要全文检索? 结构化数据(mysql等)方便查询,而非结构化数据(如多篇文章)是难以查询到自己需要的,所以要使用全文检索. 全文 ...
- input属性总结
<input type="text" readonly="readonly" /> 这个是不能输入的 readonly="readonly ...
- Java OOP——第七章 多线程
1.进程:是指运行中的应用程序,每个进程都有自己独立的地址空间(内存空间): Eg:用户点击桌面的IE浏览器,就启动了一个进程,操作系统就会为该进程分配独立的地址空间.当用户再次点击左面的IE浏览器, ...
- PHP 使用GD库合成带二维码和圆形头像的海报步骤以及源码实现
PHP 使用GD库合成带二维码和圆形头像的海报步骤以及源码实现 之前记录过一篇文章,不过那只是简单将二维码合成到海报中去,这次还要合成头像,而且是圆形.所需要素材就不一一列举,直接代码吧 1.先获取用 ...