【2017/2/26 | 一次性完成,好有成就感!坚持总有回报!】
题目:http://ac.jobdu.com/problem.php?pid=1078
题意:给出二叉树的前序和中序遍历结果,输出后序遍历结果
注意点:在新建二叉树结点时,一定要申请空间,一开始忘了,苦恼了好一会!
#include<cstdio>
#include<cstring>
#include<algorithm>
#define maxSize 30
using namespace std;
struct Btree {//二叉树
int id;
Btree * left;
Btree * right;
int left_flag, right_flag;//记录是否有左右子树
};
//构造二叉树
void rebuild(char * str_1, char * str_2, Btree *pre) {
if (strlen(str_1) <= 1) {//达到叶节点
pre->left_flag = 0;
pre->right_flag = 0;
return;
}
char start = str_1[0];
int start_id = strchr(str_2, start)-str_2;//中序遍历中找到根节点
char newStr_1[30], newStr_2[30], newStr_3[30], newStr_4[30];
//分割 前序遍历结果
strncpy(newStr_3, str_1 + 1, start_id); //左子树
strncpy(newStr_4, str_1 + start_id + 1, strlen(str_1) - start_id - 1);//右子树
//分割 中序遍历结果
strncpy(newStr_1, str_2, start_id); //左子树
strncpy(newStr_2, str_2 + start_id + 1, strlen(str_2) - start_id - 1);//右子树
newStr_1[start_id] = 0; //加空字符,保证字符串结束
newStr_2[strlen(str_2) - start_id - 1] = 0;
newStr_3[start_id] = 0;
newStr_4[strlen(str_2) - start_id - 1] = 0;
//为左右子树申请空间、递归分解
if (strlen(newStr_1) != 0) {//非空
pre->left_flag = 1;
Btree* leftChild = (Btree *)malloc(sizeof(Btree));
leftChild->id = newStr_3[0] - 'A';
pre->left = leftChild;
rebuild(newStr_3, newStr_1, leftChild);
}
if (strlen(newStr_2) != 0) {
pre->right_flag = 1;
Btree* rightChild = (Btree *)malloc(sizeof(Btree));
rightChild->id = newStr_4[0] - 'A';
pre->right = rightChild;
rebuild(newStr_4, newStr_2, rightChild);
}
}
//以后序遍历输出
void myPrint(Btree* t) {
if(1 == t->left_flag)
myPrint(t->left);
if(1 == t->right_flag)
myPrint(t->right);
char temp = t->id + 'A';
printf("%c", temp);
return;
}
int main() {
char str_1[maxSize];//前序遍历结果
char str_2[maxSize]; //中序
while (scanf("%s", str_1) != EOF) {
scanf("%s", str_2);
Btree *pre;
pre = (Btree *)malloc(sizeof(Btree));//一定记得申请空间
int temp = str_1[0] - 'A';//前序遍历结果的首结点即为根节点
pre->id = temp;
rebuild(str_1, str_2, pre);//重构二叉树
myPrint(pre); //按后序遍历输出
printf("\n");
}
return 0;
}