• 二分查找树按照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;
    }
  • 相关阅读:
    Java并发编程(六)——Callable接口
    java基础——反射
    java基础——序列化
    java基础——IO
    java基础——File类
    操作nginx时遇到的各种问题
    linux安装nginx 简单版
    linux 重命名文件和文件夹
    Linux 程序安装目录 /opt 目录和 /usr/local 目录
    Linux 各种安装包
  • 原文地址:https://www.cnblogs.com/li-daphne/p/6637804.html
Copyright © 2020-2023  润新知