1. 程式人生 > >二叉樹遍歷(王道)

二叉樹遍歷(王道)

中序 數組 har 不為 位置 mem 一行 遍歷 uil

題目描述:

二叉樹的前序、中序、後序遍歷的定義:
前序遍歷:對任一子樹,先訪問跟,然後遍歷其左子樹,最後遍歷其右子樹;
中序遍歷:對任一子樹,先遍歷其左子樹,然後訪問根,最後遍歷其右子樹;
後序遍歷:對任一子樹,先遍歷其左子樹,然後遍歷其右子樹,最後訪問根。
給定一棵二叉樹的前序遍歷和中序遍歷,求其後序遍歷(提示:給定前序遍歷與中序遍歷能夠唯一確定後序遍歷)。

輸入:

兩個字符串,其長度n均小於等於26。
第一行為前序遍歷,第二行為中序遍歷。
二叉樹中的結點名稱以大寫字母表示:A,B,C....最多26個結點。

輸出:

輸入樣例可能有多組,對於每組測試樣例,
輸出一行,為後序遍歷的字符串。

樣例輸入:
ABC
BAC
FDXEAG
XDEFAG
樣例輸出:
BCA
XEDGAF
#include <iostream>
#include<cstdio>
#include<string.h>
using namespace std;

struct Node{
    Node *lchild;
    Node *rchild;
    char c;
};
struct Node Tree[50];
char str1[30],str2[30];//放前序和中序
int loc;//靜態數組中已分配的節點個數
Node *create(){//申請一個結點空間,返回指向其的指針
Tree[loc].lchild = Tree[loc].rchild = NULL;//初始化左右兒子為空 return &Tree[loc++];//返回指針,且loc累加 } void postOrder(Node *T){//後序遍歷 if(T->lchild != NULL) postOrder(T->lchild);//遞歸遍歷左子樹 if(T->rchild != NULL) postOrder(T->rchild);//遞歸遍歷右子樹 printf("%c",T->c);//遍歷該節點,輸出字符
} Node *build(int s1,int e1,int s2,int e2){ //由字符串的前序遍和中序遍歷還原樹,並返回其根節點 //s1和e1分別為前序遍歷結果的頭和尾下標,s2和e2分別為中序遍歷結果的頭和尾下標 Node* ret = create();//為根節點申請空間 ret->c = str1[s1];//該節點字符為前序遍歷中第一個字符 int rootIdex; for(int i=s2;i<=e2;i++){//尋找根節點在中序遍歷中的位置 if(str2[i] == str1[s1]){ rootIdex = i; break; } } if(rootIdex != s2)//左子樹不為空 ret->lchild = build(s1+1,s1+rootIdex-s2,s2,rootIdex-1);//遞歸還原左子樹 if(rootIdex != e2)//右子樹不為空 ret->rchild = build(s1+rootIdex-s2+1,e1,rootIdex+1,e2);//遞歸還原右子樹 return ret;//返回根節點指針 } int main() { int n; cin >> n; while(n--){
loc = 0; memset(str1,
0,sizeof(str1)); memset(str2,0,sizeof(str2)); scanf("%s",str1); scanf("%s",str2); int len1 = strlen(str1); int len2 = strlen(str2); Node* T = build(0,len1-1,0,len2-1);//還原樹 postOrder(T);//後序遍歷 cout << endl; cout << endl; } return 0; }
順便說一下,C和C++裏面只有NULL沒有null!!!
 

二叉樹遍歷(王道)