PTA Tree Traversals Again 思路分析及程式碼解析
阿新 • • 發佈:2021-01-04
PTA Tree Traversals Again 思路分析及程式碼解析 v0.9.1
一、前導
1. 需要掌握的知識
- 二叉樹及其非遞迴遍歷
- 堆疊
2. 題目資訊
- 題目來源:PTA / 拼題A
- 題目地址: Tree Traversals Again
二、解題思路分析
1. 題意理解
- An inorder binary tree traversal can be implemented in a non-recursive way with a stack.
Then a unique binary tree can be generated from this sequence of operations. - 輸入資料
6 //樹的結點數
Push 1 //向堆疊中push一個元素
Push 2
Push 3
Pop //從棧頂彈出一個元素
Pop
Push 4
Pop
Pop
Push 5
Push 6
Pop
Pop
- 輸出資料:列印樹的後序遍歷
3 4 2 6 5 1
- 題意
堆疊的操作順序,可唯一確定一棵二叉樹,請輸出此樹的後序遍歷
2. 思路分析(重點)
- 根據應用堆疊進行樹的遍歷的內容:堆疊的入棧順序就是樹的先序遍歷,出棧順序就是樹的中序遍歷
- 本題就是已知先序遍歷和中序遍歷,得到後序遍歷
三、具體實現
1. 彎路和bug
- 由於使用遞迴,判定條件是inorder[InL+record],而不是inorder[record]
for(record=0;record<Nodes;record++)
if(inorder[InL+record]==root) //** bug: if(inorder[record]==root)
break;
2. 程式碼框架(重點)
2.1 採用的資料結構
陣列
#define max 30
int preorder[max], inorder[max],postorder[max];
2.2 程式主體框架
程式偽碼描述
int main()
{
題意:堆疊的push是先序遍歷,pop是中序遍歷,要獲取後序遍歷
1.通過輸入資料得到先序和中序
2.通過先序和中序直接得到後續
}
2.3 各分支函式
- GetPreAndIn( ) 通過輸入資料,獲取二叉樹的先序遍歷和中序遍歷
#define size 10
char Operation[size];
void GetPreAndIn(int Nodes) //Nodes 樹的結點數
{
int data,top,pre=0,in=0;
stack<int> s;
for(int i=0;i<Nodes*2;i++)
{
cin>>Operation;
if(!strcmp(Operation,"Push"))
{
cin>>data;
preorder[pre]=data; pre++; //入棧順序就是樹的先序遍歷
s.push(data);
}
else if(!strcmp(Operation,"Pop"))
{
top=s.top();
s.pop();
inorder[in]=top; in++; //出棧順序就是樹的中序遍歷
}
}
}
- GetPostOrder( ) 核心函式,根據先序和中序,不建樹的情況下直接得到後序。具體思路是:
(1)先序遍歷的首元素就是root,root是後序的最後一個元素
(2)已知root和中序遍歷,可以得到二叉樹左右子樹的結點個數
(3)遞迴左子樹和右子樹
(4)需要考慮遞迴的兩種特殊情況:樹結點為空時和樹結點為1時
void GetPostOrder(int PreL,int InL,int PostL,int Nodes) //PreL InL PostL 表示前序 中序 後序 最左邊的元素編號,也就是0
{
int root,leftTreeNumber,rightTreeNumber, record=0;
if(!Nodes) return;
if(Nodes==1)
{
postorder[PostL]=preorder[PreL];
return;
}
root=preorder[PreL]; //對於先序,最左邊的元素就是根元素
postorder[PostL+Nodes-1]=root;
for(record=0;record<Nodes;record++)
if(inorder[InL+record]==root) //** bug: if(inorder[record]==root) 注意起始位置
break;
leftTreeNumber=record; rightTreeNumber=Nodes-leftTreeNumber-1;
GetPostOrder(PreL+1,InL,PostL,leftTreeNumber); //左子樹及其最左邊的元素
GetPostOrder(PreL+record+1,InL+record+1,PostL+record,rightTreeNumber);
}
3. 完整編碼
- 如果本文幫到了您,請點贊鼓勵,您的鼓勵是作者持續原創的動力,謝謝
- 如有疑問或建議,歡迎留言