日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

L2-004 这是二叉搜索树吗?-团体程序设计天梯赛GPLT

發(fā)布時(shí)間:2025/3/20 编程问答 29 豆豆
生活随笔 收集整理的這篇文章主要介紹了 L2-004 这是二叉搜索树吗?-团体程序设计天梯赛GPLT 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

題目來源:團(tuán)體程序設(shè)計(jì)天梯賽-練習(xí)集
題目地址:L2-004 這是二叉搜索樹嗎?

題目大意

給定一個(gè)長度為 nnn 的序列,判斷這是否是對(duì)一棵二叉搜索樹其鏡像進(jìn)行前序遍歷的結(jié)果。如果是,則在一行中輸出 YES ,然后在下一行輸出該樹后序遍歷的結(jié)果,否者直接輸出 NO。

題目分析

1. 預(yù)備知識(shí)
前序遍歷:先訪問根節(jié)點(diǎn),再遍歷左子樹,最后遍歷右子樹。

后序遍歷:先遍歷左子樹,再遍歷右子樹,最后訪問根節(jié)點(diǎn)。
(注意:遍歷子樹的時(shí)候也要按照相應(yīng)的的方式遍歷。)

二叉搜索樹的基本性質(zhì)(如題目描述所示)

2. 結(jié)題要義
首先,我們假設(shè)輸入的序列 a[]a[\ ]a[?] 就是一棵二叉搜索樹進(jìn)行前序遍歷的結(jié)果,lllrrr 分別為序列 a[]a[\ ]a[?] 的左右邊界。

根據(jù)前序遍歷的性質(zhì),我們可以知道 a[l]a[l]a[l] 即為這棵樹的根節(jié)點(diǎn)、 l+1l+1l+1 為左子樹的左邊界, rrr 為右子樹的右邊界。然后我們定義兩個(gè)指針 tltltltrtrtr 分別表示右子樹的左邊界、左子樹的右邊界。(注意哪個(gè)對(duì)應(yīng)哪個(gè)

初始化 tl=l+1tl = l+1tl=l+1tr=rtr=rtr=r,接著根據(jù)二叉樹搜索樹的性質(zhì) ,tltltl 往右移動(dòng),找到第一個(gè)大于或等于根節(jié)點(diǎn) a[l]a[l]a[l] 的節(jié)點(diǎn)、trtrtr往右移動(dòng),找到第一個(gè)小于根節(jié)點(diǎn) a[l]a[l]a[l] 的節(jié)點(diǎn)。過程如下圖所示,

這樣就確定了序列中根節(jié)點(diǎn)、左子樹和右子樹的位置,我們遞歸進(jìn)行這個(gè)這個(gè)過程,就可以得到整棵樹的結(jié)構(gòu),過程如下圖所示:

為了簡便,我們可以省去建樹的過程,在確定了序列中根節(jié)點(diǎn)、左子樹和右子樹的位置后,就直接進(jìn)行后序遍歷。由確定子樹范圍的過程可得,若這是一顆二叉搜索樹,則必有 tl?tr=1tl-tr=1tl?tr=1 ,要是不滿足這個(gè)條件,我們就直接停止遍歷。

訪問根節(jié)點(diǎn)時(shí),我們可以將根節(jié)點(diǎn)放入 vectorvectorvector 中(vectorvectorvector即為后序遍歷序列)。最后我們通過判斷 vectorvectorvector 中的元素個(gè)數(shù)是否等于 nnn 來判斷這是否為二叉搜索樹

如果等于 nnn ,就可以輸出 vectorvectorvector ;否則就判斷是否為鏡像。至于求判斷鏡像的過程也基本和上訴無異,區(qū)別在于確定子樹范圍的條件而已。

代碼如下

#include <bits/stdc++.h>using namespace std; const int maxn = 1e3 + 10; int n, flag; /*** a[]用于存儲(chǔ)輸入的前序遍歷序列* ans用于存儲(chǔ)后序遍歷的結(jié)果*/ int a[maxn]; vector<int> ans;/*** 后序遍歷這顆二叉樹**/ void dfs(int l, int r) {if (l > r) return ;//tl表示右子樹的左邊界,tr表示左子樹的右邊界int tl = l + 1, tr = r;if (flag) {//判斷二叉搜索樹的“鏡像”while (tl <= r && a[tl] >= a[l]) tl++;while (tr > l && a[tr] < a[l]) tr--;} else {//判斷二叉搜索樹while (tl <= r && a[tl] < a[l]) tl++;while (tr > l && a[tr] >= a[l]) tr--;}//不滿足二叉搜索樹的條件if (tl - tr != 1) return ;//訪問左子樹dfs(l + 1, tr);//訪問右子樹dfs(tl, r);//訪問根節(jié)點(diǎn)ans.push_back(a[l]); }int main() {cin >> n;for (int i = 1; i <= n; i++) cin >> a[i];//先檢查是不是二叉搜索樹的“鏡像”dfs(1, n);//如果不滿足,則再檢查是不是二叉搜索樹if (ans.size() != n) {flag = 1;ans.clear();dfs(1, n);}if (ans.size() != n) {cout << "NO" << endl;} else {cout << "YES" << endl;for (int i = 0; i < n; i++) {cout << ans[i] << (i == n -1 ? '\n' : ' ');}}return 0; }

如果本文對(duì)你有所幫助,記得點(diǎn)個(gè)贊哦~

總結(jié)

以上是生活随笔為你收集整理的L2-004 这是二叉搜索树吗?-团体程序设计天梯赛GPLT的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。