首页 > 其他分享 >考研数据结构——每日一题[二叉排序树]

考研数据结构——每日一题[二叉排序树]

时间:2023-08-05 16:01:35浏览次数:30  
标签:左子 结点 right val int 二叉 数据结构 root 考研

3786. 二叉排序树

你需要写一种数据结构,来维护一些数,其中需要提供以下操作:

插入数值 x。 删除数值 x。 输出数值 x 的前驱(前驱定义为现有所有数中小于 x 的最大的数)。 输出数值 x 的后继(后继定义为现有所有数中大于 x 的最小的数)。 题目保证:

操作 1 插入的数值各不相同。 操作 2 删除的数值一定存在。 操作 3 和 4 的结果一定存在。 输入格式 第一行包含整数 n,表示共有 n 个操作命令。

接下来 n 行,每行包含两个整数 opt 和 x,表示操作序号和操作数值。

输出格式 对于操作 3,4,每行输出一个操作结果。

数据范围 1≤n≤2000, −10000≤x≤10000 输入样例: 6 1 1 1 3 1 5 3 4 2 3 4 2 输出样例: 3 5

左旋、右旋不改变中序遍历,且互逆 背过:①最小不平衡树,从下往上找,找到第一个不平衡的子树 ②按照类型规则旋转 四种类型 :LL、RR、LR、RL 在这里插入图片描述 看图的感悟:LR:左C后变LL,再右旋A ;RL:右C后变RR,再左旋A ; 手写二叉排序树【前驱和后继为遍历序列左右相邻元素】 先序【根左右】、中序【左根右】、后序【左右根】 [小三角判断]

insert(TreeNode* &root, int x) 递归查找左<根<右
remove(TreeNode* &root, int x) 先找再分类删
get_pre(TreeNode* root, int x) 寻找前驱【找小于的最大值,不存在用-INF负无穷】
get_suc(TreeNode* root, int x) 寻找后继   【找大于的最小值,不存在用INF正无穷】
#include <iostream>
#include <cstring>
#include <algorithm>

using namespace std;

const int INF = 1e8;

struct TreeNode
{
    int val;
    TreeNode *left, *right;//记住定义指针变量,每个都要加*
    TreeNode(int _val): val(_val), left(NULL), right(NULL) {}
}*root;

void insert(TreeNode* &root, int x)//改变指针所指的值 取引用 
{
    if (!root) root = new TreeNode(x);//【找到位置后,指针指向new的新结点】
    else if (x < root->val) insert(root->left, x);//小于父结点值,放左子树,递归判断下一次插入
    else insert(root->right, x);//大于父结点值,放右子树,递归判断下一次插入
}

void remove(TreeNode* &root, int x)//先找再分类删【左右子树是否为空分四类】 
{
    if (!root) return;//树为空,删除的数不存在 【注意判空分支是提前判断 没有if-else关系】 
    if (x < root->val) remove(root->left, x);//x小于根结点,x在左子树,去左子树删
    else if (x > root->val) remove(root->right, x);//x大于根结点值,x在右子树,
    else//找到x后:分类删除
    {
        if (!root->left && !root->right) root = NULL; //如果没有左右孩子,则为叶子结点,直接删除【root指针指向NULL】
        else if (!root->left) root = root->right;//如果左子树为空,把右子树填上来   ,往右找最右侧【取最大值】,
        else if (!root->right) root = root->left;//如果右子树为空,把左子树填上来 
        else//如果左右子树都有 【则把左子树最右侧的结点值替换删除结点,然后删除最右侧结点】
        {
            auto p = root->left; //替换法删除【保持左<父<右 && 中序遍历不变】
            while (p->right) p = p->right;//找左子树最右侧最大值,替换父结点,再删除最右侧结点
            root->val = p->val;
            remove(root->left, p->val);//删除左子树的最右侧结点,值为p->val
        }
    }
}

int get_pre(TreeNode* root, int x)//寻找前驱【找小于的最大值,不存在用-INF负无穷】 【查找不需要修改,不用加引用】 
{
    if (!root) return -INF;//找最大值,没有答案用-INF(负无穷) 
    if (root->val >= x) return get_pre(root->left, x);//值大于x,返回左子树的查找结果 
    return max(root->val, get_pre(root->right, x));//否则返回根的结果和右子树的值的max(看根有没有右子树,有则前驱为右子树的最右侧)
}

int get_suc(TreeNode* root, int x)//寻找后继   【找大于的最小值,不存在用INF正无穷】
{
    if (!root) return INF;//找最小值,没有答案用正无穷 
    if (root->val <= x) return get_suc(root->right, x); //值大于,往右子树找
    return min(root->val, get_suc(root->left, x));//返回根与其左子树min(若根有左子树则左子树作为后继,min=左子树)
}

int main()//若输出就是中序遍历
{
    int n;
    cin >> n;
    while (n -- )
    {
        int t, x;
        cin >> t >> x;
        if (t == 1) insert(root, x);
        else if (t == 2) remove(root, x);
        else if (t == 3) cout << get_pre(root, x) << endl;
        else cout << get_suc(root, x) << endl;
    }

    return 0;
} 

标签:左子,结点,right,val,int,二叉,数据结构,root,考研
From: https://blog.51cto.com/u_15623277/6976299

相关文章

  • C/C++ 数据结构五大核心算法之回溯法-N皇后问题
    N皇后问题:在n*n的棋盘上要摆n个皇后,要求:任何两个皇后不同行,不同列也不在同一条斜线上,求给一个整数n,返回n皇后的摆法数。#include<iostream>#include<math.h>#defineN8usingnamespacestd;intq[N+1];//q[i]表示第i个皇后在第i行上的第q[i]列intcheck(i......
  • 剑指 Offer 27. 二叉树的镜像(简单)
    题目:classSolution{public:voidtraversal(TreeNode*cur){if(cur==nullptr)return;swap(cur->left,cur->right);//从上换到下面就完事了traversal(cur->left);traversal(cur->right);}TreeNode*mirrorTree(TreeNode*root){traversal(root);ret......
  • 数据结构-算法-01-算法初步
     ......
  • 树上数据结构
    树上问题树链剖分学习笔记重链剖分对树进行重链优先搜索,暴力求一条路径的复杂度为logn模板voidtree_build(intu,intfa){//重链优先搜索 siz[u]=1; f[u]=fa; hson[u]=0; for(auto&v:adj[u]){deep[v]=deep[u]+1; if(v==fa)continue; tree_build(v,u);......
  • 【数据结构 | 入门】堆栈与队列(问题引入&实现&算法优化)
    ......
  • 数据结构(二)
    目录4.树4.1树和二叉树4.2二叉树4.2.1顺序结构4.2.2链式结构4.2.3二叉树的遍历4.2.4二叉排序树4.2.5平衡二叉树4.5.6哈夫曼树4.3非二叉树和森林5.图5.1图的存储结构5.1.1数组表示法5.1.2邻接表5.2图的遍历5.2.1深度优先搜索(DFS:DepthFirstSearch)5.2.2广度优先搜索(BFS:Breadt......
  • 王不留,混迹基层八年穷屌丝,考研准备四个月,考上中国科技大学MBA,成为一家软件上市公司中
      我叫王不留,2018年,我在知乎分享了我的备考经历。  分享了在职备考中科大研究生的经历和全年备考计划。 这两年,很多朋友通过努力,考上了北大光华、中科大、同济、中海大……祝贺他们! 今天,2020年12月26号,又是经历一年付出,真正收获成果的一天。 在此日子,我起笔重写我的备考经历......
  • 数据结构学习3
    树型结构:1、树的基本概念:一种表示层次关系(一对多)的数据结构有且仅有一个特定节点,该节点没有前趋节点,称为这棵树的根节点剩余有n个(n>=0)有限个多节点组成互不相交的子集,每个子集都可以是一棵树,都被称为根节点的子树注意:树中有树,树型结构具有递归性2、树的表示方式:倒悬树、凹......
  • 数据结构
    线段树线段树可以在O(logN)的时间复杂度内实现单点修改、区间修改、区间查询(区间求和,求区间最大值,求区间最小值)等操作。注意点:线段树的数组一般要开到4*N; 位运算的写法为N>>2对于懒标记:修改的时候不用用到下面的区间,查询的时候才会用到下面的区间故每次插入懒标......
  • GO 数据结构操作:栈
        ......