#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值划分的更多相关文章

  1. Go 数据结构--二分查找树

    Go 数据结构--二分查找树 今天开始一个Go实现常见数据结构的系列吧.有时间会更新其他数据结构. 一些概念 二叉树:二叉树是每个节点最多有两个子树的树结构. 完全二叉树:若设二叉树的高度为h,除第 ...

  2. 手把手教你用java实现二分查找树及其相关操作

    二分查找树(Binary Search Tree)的基本操作有搜索.求最大值.求最小值.求前继.求后继.插入及删除. 对二分查找树的进行基本操作所花费的时间与树的高度成比例.例如有n个节点的完全二叉树 ...

  3. 笔试算法题(58):二分查找树性能分析(Binary Search Tree Performance Analysis)

    议题:二分查找树性能分析(Binary Search Tree Performance Analysis) 分析: 二叉搜索树(Binary Search Tree,BST)是一颗典型的二叉树,同时任 ...

  4. lintcode-106-排序列表转换为二分查找树

    106-排序列表转换为二分查找树 给出一个所有元素以升序排序的单链表,将它转换成一棵高度平衡的二分查找树 样例 标签 递归 链表 思路 类似于二分查找,每次将链表二分,中间节点作为根节点,在建立左子树 ...

  5. SPOJ TEMPLEQ - Temple Queues(二分查找+树状数组)

    题意: 有N个队伍(1 <= N <= 100,000),每个队伍开始有ai个人[0 <= ai<= 100,000,000],有Q个操作[0<=Q<= 500,0 ...

  6. python数据结构之树(二分查找树)

    本篇学习笔记记录二叉查找树的定义以及用python实现数据结构增.删.查的操作. 二叉查找树(Binary Search Tree) 简称BST,又叫二叉排序树(Binary Sort Tree),是 ...

  7. Holedox Eating HDU - 4302 2012多校C 二分查找+树状数组/线段树优化

    题意 一个长度$n<=1e5$的数轴,$m<=1e5$个操作 有两种一些操作 $0$  $x$ 在$x$放一个食物 $1$ 一个虫子去吃最近的食物,如果有两个食物一样近,不转变方向的去吃 ...

  8. 51nod1287(二分/线段树区间最值&单点更新)

    题目链接:http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1287 题意:中文题诶- 解法1:b[i] 存储 max(a[0 ...

  9. js二分查找树实现

    function BinaryTree() { var Node = function(key) { this.key = key; this.left = null; this.right = nu ...

随机推荐

  1. 整合ssm集成框架

    第一步:配置pom.xml 该代码放在<dependencies>里面 <!--spring 所需要的jar包 web.aop.jdbc.webmvc--> <!--1. ...

  2. 关于vue中的nextTick深入理解

    定义[nextTick.事件循环] nextTick的由来: 由于VUE的数据驱动视图更新,是异步的,即修改数据的当下,视图不会立刻更新,而是等同一事件循环中的所有数据变化完成之后,再统一进行视图更新 ...

  3. 前端面试题(来自前端网http://www.qdfuns.com/notes/23515/c9163ddd620baac5dd23141d41982bb8.html)

    HTML&CSS 1. 常用那几种浏览器测试?有哪些内核(Layout Engine)? (Q1)浏览器:IE,Chrome,FireFox,Safari,Opera. (Q2)内核:Trid ...

  4. 创建自己的网站博客--Hexo

    原文地址:https://www.xingkongbj.com/blog/hexo/creat-hexo.html 安装环境 安装 node 下载对应版本并安装 node . 安装 Git Windo ...

  5. C#进阶学习笔记(个人整理)

    学习笔记 第一章: 一.回顾数组 1.变量 : 只能存储一个数据 2.数组 :存储固定大小的相同类型的数据 3.对象 : 存储多个相同/不同类型的数据 4.集合 : 特殊的容器,存储N个相同/不同类型 ...

  6. selenium学习总结

    selenium主要用来做web自动化,分1.0和2.0两个版本,1.0包括selenium IDE.selenium Grid.selenium Remote Control,2.0在1.0的基础上 ...

  7. Linux基础知识随笔记

    linux文件属性 ls -h human-readable以人类可读的形式显示 -i 显示inode号码 [root@oldboyedu55-bjb ~]# ls -ihl total 8.0K 3 ...

  8. 如何设置 html 中 select 标签不可编辑、只读

    转载自: https://blog.csdn.net/hjm4702192/article/details/33729767 1. <select style="width:195px ...

  9. 多线程(threading module)

    一.线程与进程 线程定义:线程是操作系统能够进行运算调度的最小单位.它被包含在进程之中,是进程中的实际运作单位.一条线程指的是进程中一个单一顺序的控制流,一个进程中可以并发多个线程,每条线程并行执行不 ...

  10. IDEA 工具项目的配置及如何打war包

    1. Project Structure 1.1 首先点击File-ProjectStructure,进入项目配置: 2.Project Settings配置 2.1 Project  2.1.1 f ...