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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

L2-006 树的遍历-团体程序设计天梯赛GPLT

發布時間:2025/3/20 编程问答 23 豆豆
生活随笔 收集整理的這篇文章主要介紹了 L2-006 树的遍历-团体程序设计天梯赛GPLT 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

題目來源:團體程序設計天梯賽-練習集
題目地址:L2-006 樹的遍歷

題目大意

給定一棵二叉樹的后序遍歷和中序遍歷,請你輸出其層序遍歷的序列。這里假設鍵值都是互不相等的正整數。

預備知識:
中序遍歷(Inorder Traversal):先遍歷左子樹,再訪問更節點,最后遍歷右子樹。
后續遍歷(Postorder Traversal):先遍歷左子樹,再遍歷右子樹,最后訪問根節點。
(注意:遍歷子樹的時候也要按照相應的的方式遍歷。)

我們可以通過一顆二叉樹的前序遍歷和中序遍歷或者后序遍歷和中序遍歷來確定一顆二叉樹。

題目分析

我們可以根據它給出的后序遍歷和中序遍歷,進行二叉樹的建樹,然后用bfs求出該二叉樹的層序遍歷,最后輸出就可以了。

下面就簡單講一下,怎么通過后序遍歷和中序遍歷的結果來得出二叉樹的結構。

設中序遍歷序列為 in_orderedin\_orderedin_ordered ,其范圍為 [la,ra][la, \ ra][la,?ra];后序遍歷序列為 post_orderedpost\_orderedpost_ordered ,其范圍為 [lb,rb][lb, \ rb][lb,?rb]

  • 根據后續遍歷的性質,可以知道 post_ordered[rb]post\_ordered[rb]post_ordered[rb] 為根節點。然后我們在中序遍歷序列 in_orderedin\_orderedin_ordered 中找出根節點的位置
  • 至此,我們已經可以知道 in_orderedin\_orderedin_ordered 中,左右子樹的范圍分為別為 [la,p?1][la,\ p-1][la,?p?1][p+1,ra][p+1,\ ra][p+1,?ra]。于是,我們就可以求出左子樹的節點個數
    cnt=p?lacnt=p-lacnt=p?la
  • 接著,我們就可以求出后序遍歷 post_orderedpost\_orderedpost_ordered 中左右子樹的范圍了。有了以上信息,我們就可以利用同樣的方法對求左子樹的相關信息,進行遞歸建樹,進而得到整棵二叉樹的結構。

(上述過程的圖示)

有了二叉樹結構,層序遍歷還不好求?其實沒什么好說的,就是一個很普通的bfs,這里就不展開了。

坑點:

  • 題目沒有給出樹節點鍵值的范圍,如果鍵值很大,那么用鍵值作為數組下標存儲左右節點位置的方法會導致數組越界,還好本題良心,放了我一馬。
  • 題目有明說,注意輸出格式,看題要認真。

其實這種題目很沒營養的,都是同一個套路。你第一次遇到會覺得學到東西了,覺得很開心。第二次遇到就是秒切了,第三次就會厭倦,第四次……

代碼如下

#include <bits/stdc++.h>using namespace std; const int maxn = 50; int n; /*** in_order[]表示中序遍歷序列* post_order[]表示后序遍歷序列* tree[]用于存儲樹形結構* 其中,tree[i].first表示i節點左孩子編號,tree[i].second表示i號節點右孩子編號*/ int in_order[maxn], post_order[maxn]; pair<int, int> tree[maxn]; /*** [la, ra]表示中序遍歷序列的范圍* [lb, rb]表示后序遍歷序列的范圍*/ int build(int la, int ra, int lb, int rb) {if (la > ra || lb > rb) return 0;int rt = post_order[rb];//p表示根節點在中序遍歷序列中的位置int p = la;while (in_order[p] != rt) p++;//cnt表示左子樹的節點數int cnt = p - la;//根據已知量,求左右子樹所在的遍歷序列區間tree[rt].first = build(la, p - 1 , lb, lb + cnt - 1);tree[rt].second = build(p + 1, ra, lb + cnt, rb - 1);return rt; }/*** 利用bfs層序遍歷二叉樹* @param root表示二叉樹的根節點*/ void bfs(int root) {vector<int> ans;queue<int> q;q.push(root);while (!q.empty()) {int node = q.front();q.pop();ans.push_back(node);if (tree[node].first) q.push(tree[node].first);if (tree[node].second) q.push(tree[node].second);}int len = ans.size();for (int i = 0; i < len; i++)cout << ans[i] << (i == len - 1 ? '\n' : ' '); }int main() {cin >> n;for (int i = 1; i <= n; i++)cin >> post_order[i];for (int i = 1; i <= n; i++)cin >> in_order[i];int root = build(1, n, 1, n);bfs(root);return 0; }

如果本文對你有所幫助,要記得點贊哦~

總結

以上是生活随笔為你收集整理的L2-006 树的遍历-团体程序设计天梯赛GPLT的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。