AcWing 3595:二叉排序树 ← BST

【题目来源】
https://www.acwing.com/problem/content/3598/

【题目描述】
二叉排序树,也称为二叉查找树。
可以是一颗空树,也可以是一颗具有如下特性的非空二叉树:
1.若左子树非空,则左子树上所有节点关键字值均不大于根节点的关键字值;
2.若右子树非空,则右子树上所有节点关键字值均不小于根节点的关键字值;
3.左、右子树本身也是一颗二叉排序树。
现在给你 N 个关键字值各不相同的节点。
要求你将这些节点按顺序插入一个初始为空树的二叉排序树中。
每次成功插入一个节点后,求其相应的父亲节点的关键字值,如果没有父亲节点,则输出 −1。

【输入格式】
第一行包含整数 N,表示待插入的节点数。
第二行包含 N 个互不相同的正整数,表示要顺序插入节点的关键字值。

【输出格式】
N 行。

【输入样例】
5
2 5 1 3 4

【输出样例】
-1
2
2
5
3

【数据范围】
1≤N≤100,
节点关键字值取值范围 1,10\^8

【算法分析】
● 题目中 N 的数据范围为 1≤N≤100,但若依据经验设 maxn=105,那么算法代码二运行后,必然会出现段错误(Segmentation Fault)。这是因为在极端情况下,二叉排序树会退化成单支树。此时,若使用数组表示 N 个节点的单支树时,节点最大索引可能达到 2^N-1。显然,2^100-1 超出了数组的合理范围。
● 算法代码一中的 std::unordered_map::count(k) → 1 if an element with a key equivalent to k is found, or zero otherwise.
https://cplusplus.com/reference/unordered_map/unordered_map/count/

【算法代码一】

cpp 复制代码
#include<bits/stdc++.h>
using namespace std;

unordered_map<int,int> le,ri;

int dfs(int &rt, int x) {
    if(rt==-1) {
        rt=x;
        return -1;
    }

    int fa=rt;

    if(x>fa) {
        if(!ri.count(fa)) {
            ri[fa]=x;
            return fa;
        } else return dfs(ri[fa],x);
    }

    if(x<fa) {
        if(!le.count(fa)) {
            le[fa]=x;
            return fa;
        } else return dfs(le[fa],x);
    }
}

int main() {
    int root=-1;
    int n;
    cin>>n;
    while(n--) {
        int x;
        cin>>x;
        cout<<dfs(root,x)<<endl;
    }

    return 0;
}

/*
in:
5
2 5 1 3 4

out:
-1
2
2
5
3
*/

【算法代码二】
段错误(Segmentation Fault)代码。
但在数据量小的前提下,此代码是正确的,且足以理解朴素的 BST 算法思想。

cpp 复制代码
#include<bits/stdc++.h>
using namespace std;

const int maxn=1e3+5;
int tr[maxn];

int main() {
    int n,x;
    cin>>n;
    for(int i=1; i<=n; i++) {
        cin>>x;
        if(i==1) {
            tr[1]=x;
            cout<<-1<<endl;
            continue;
        }

        int pos=1,fa=-1;
        while(1) {
            if(tr[pos]==0) {
                tr[pos]=x;
                cout<<fa<<endl;
                break;
            }

            fa=tr[pos];
            if(x>tr[pos]) pos=pos*2+1;
            else pos=pos*2;
        }
    }

    return 0;
}

/*
in:
5
2 5 1 3 4

out:
-1
2
2
5
3
*/

【参考文献】
https://blog.csdn.net/hnjzsyjyj/article/details/120397275
https://blog.csdn.net/hnjzsyjyj/article/details/140231285
https://www.acwing.com/problem/content/1630/
https://www.cnblogs.com/crazyapple/archive/2013/05/14/3077382.html
https://www.acwing.com/solution/content/219723/

相关推荐
灵枢时代3 小时前
小程序在生鲜配送行业,如何设计夜间预约和次日达的订单处理流程?
数据结构·人工智能·小程序
一条大祥脚3 小时前
ABC468 扫描线|贡献法|二阶差分|线段树优化DP
数据结构·算法
mifengxing1 天前
LeetCode 189 轮转数组|3种解法拆解,从暴力到O(1)原地最优解
数据结构·算法·leetcode
MIngYaaa5201 天前
2026暑期牛客多校3 2026-7-24
数据结构·算法·000
2501_937860941 天前
Java 集合底层深度剖析:Map 与 Set、二叉搜索树、哈希表全解
java·数据结构·散列表
Hommy881 天前
【剪映小助手】字符串列表转对象接口(Str List To Obds)
数据结构·list·剪映小助手·视频剪辑自动化·剪映api·开源剪映小助手
noipp1 天前
推荐题目:洛谷 P3726 [AHOI2017/HNOI2017] 抛硬币
c语言·数据结构·c++·算法·编程·洛谷·luogu
wabs6661 天前
关于链表【力扣19.删除链表的倒数第N个节点的思考】
数据结构·leetcode·链表
Rabitebla1 天前
C++ STL 之 set 详解:从底层红黑树到实际应用
开发语言·数据结构·c++·算法·leetcode
520拼好饭被践踏1 天前
JAVA+Agent学习day26
java·开发语言·数据结构·学习·agent