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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > c/c++ >内容正文

c/c++

PAT甲级1020 Tree Traversals:[C++题解]树的遍历、由中序序列和后序序列递归建树

發布時間:2025/4/5 c/c++ 18 豆豆
生活随笔 收集整理的這篇文章主要介紹了 PAT甲级1020 Tree Traversals:[C++题解]树的遍历、由中序序列和后序序列递归建树 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

文章目錄

    • 題目分析
    • 題目鏈接

題目分析


題意重述:給定一棵二叉樹的后序遍歷序列和中序遍歷序列,讓求層次遍歷的序列。

分析:

后序遍歷:先 左子樹、右子樹 ,最后再遍歷根結點。

中序遍歷:先左子樹,再根結點,然后是右子樹。

給定中序序列和后續序列,便可以唯一確定這棵二叉樹的形狀。

由于后序遍歷最后遍歷根結點,所以最后一個就是根結點。 找到根結點的值,我們就可以在中序序列中找到根結點,從而把中序序列分成左子樹、根結點、右子樹三部分。 這三部分也可以在后序序列中找到對應的部分。

然后對于后序序列的各個部分,遞歸上面這個過程,先找到這個部分的根結點,再對應到中序序列,把中序序列的這一部分再分成左子樹、根結點、右子樹三部分……

這里需要用到hash表l和r,分別用來存一個結點的左兒子 和右兒子。這樣查找某結點是否存在兒子,就方便很多。
ac代碼

#include<bits/stdc++.h> using namespace std;const int N =40;int n; int postOrder[N], inOrder[N];unordered_map<int,int> l,r,pos; //l和r存左右兒子,pos存中序遍歷每個值的下標 int q[N];/*build函數:根據中序序列和后序序列建樹,返回樹根il:中序序列左端點;ir:中序序列右端點pl:后序序列左端點;pr:后序序列右端點 */ int build(int il, int ir, int pl ,int pr){int root = postOrder[pr]; //在后序序列中找到根結點的值,存在root中int k =pos[root];// 根結點在中序序列中的位置//看中序序列//中序序列中存在左子樹if(il < k){//左子樹的樹根 就是 root的左兒子l[root] = build(il,k-1, pl,pl+(k-1-il));}//中序序列中存在右子樹if(k<ir){//右子樹的樹根就是root的右兒子r[root] = build(k+1,ir,pl+(k-1-il)+1,pr-1);}return root; //返回樹根 } /* bfs:層次遍歷 手寫隊列*/ void bfs(int root){int hh =0 ,tt =0;q[0] =root; //q[0]為根結點while(hh<=tt){ //隊列不空int t =q[hh++]; //取隊首元素//左子樹存在,左子樹的樹根加入隊列if(l.count(t)) q[++tt] =l[t]; //左兒子存在加入隊列//右子樹存在,右子樹的樹根加入隊列if(r.count(t)) q[++tt] =r[t]; //右兒子存在加入隊列}cout<<q[0];for(int i=1;i<n;i++) cout<<" "<<q[i]; }int main(){cin>> n;for(int i=0; i<n;i++) cin>> postOrder[i];for(int i=0;i<n;i++){cin>>inOrder[i];pos[inOrder[i]] =i; //記錄每個值在中序序列中的位置}int root = build(0,n-1,0,n-1);bfs(root);}

題目鏈接

PAT甲級1020 Tree Traversals

總結

以上是生活随笔為你收集整理的PAT甲级1020 Tree Traversals:[C++题解]树的遍历、由中序序列和后序序列递归建树的全部內容,希望文章能夠幫你解決所遇到的問題。

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