本题要求根据给定的一棵二叉树的后序遍历和中序遍历结果,输出该树的先序遍历结果。
输入格式:
第一行给出正整数N(≤30),是树中结点的个数。随后两行,每行给出N个整数,分别对应后序遍历和中序遍历结果,数字间以空格分隔。题目保证输入正确对应一棵二叉树。
输出格式:
在一行中输出Preorder:
以及该树的先序遍历结果。数字间有1个空格,行末不得有多余空格。
输入样例:
7
2 3 1 5 7 6 4
1 2 3 4 5 6 7
输出样例:
Preorder: 4 1 3 2 6 5 7
方法一 : 是求出二叉树然后求前序遍历;
方法二 : 利用后续、中序、前序的规律直接求前序遍历。
#include<stdlib.h>
#include<stdio.h>
#include<malloc.h>
#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0
#define OVERFLOW -1
#define INFEASIBLE -2
#define NULL 0
int num, cnt = 0, cnt2 = 0;
int sub_complete[90], sub[35] = {0}, mid[35] = {0};
typedef int Status;
typedef int TElemType;
typedef struct BiTNode
{
TElemType data;
struct BiTNode *lchild, *rchild;
} BiTNode, *BiTree;
Status CreateBiTree(BiTree &T, int a[])
{
// if(cnt2 == cnt)
// return OK;
if(a[cnt2] == 0)
T = NULL;
else
{
T = (BiTree)malloc(sizeof(BiTNode));
if(!T)exit(OVERFLOW);
T->data = a[cnt2];
cnt2++;
CreateBiTree(T->rchild, a);
cnt2++;
CreateBiTree(T->lchild, a);
}
return OK;
}
void GetCompleteSub(int sub[], int mid[], int length)
{
if(num < 0)
return ;
int root = sub[num], pos, rlength, llength;
int right[30], left[30];
for(int i = 0; i < length; ++i)
if(mid[i] == root)
pos = i;
//printf("pos = %d root = %d\n",pos, root);
if(pos != 0 && pos + 1 != length)
{
rlength = length - pos - 1;
llength = pos;
for(int i = pos + 1; i < length; ++i)
right[i - pos - 1] = mid[i];
for(int i = 0; i < pos; i++)
left[i] = mid[i];
//printf("*****1***** 插入%d\n", sub[num]);
sub_complete[cnt++] = sub[num];
num -= 1;
GetCompleteSub(sub, right, rlength);
num -= 1;
GetCompleteSub(sub, left, llength);
}
else if(pos + 1 == length && pos != 0)
{
sub_complete[cnt++] = sub[num];
num -= 1;
llength = length - 1;
for(int i = 0; i < llength; ++i)
{
left[i] = mid[i];
}
sub_complete[cnt++] = 0;
GetCompleteSub(sub, left, llength);
}
else if(pos == 0 && length > 1)
{
//printf("*****2***** 插入%d\n", sub[num]);
sub_complete[cnt++] = sub[num];
num -= 1;
rlength = length - 1;
for(int i = 1; i < length; ++i)
{
right[i - 1] = mid[i];
// printf("*****2***** 插入mid %d %d\n", i - 1, right[i - 1]);
}
GetCompleteSub(sub, right, rlength);
//printf("*****2***** 插入%d\n", 0);
sub_complete[cnt++] = 0;
}
else
{
// printf("*****3***** 插入%d%d%d\n", sub[num], 0, 0);
sub_complete[cnt++] = sub[num];
sub_complete[cnt++] = 0;
sub_complete[cnt++] = 0;
//num -= 1;
}
}
Status PrintT(int e)
{
printf(" %d",e);
return OK;
}
Status PreOrderTraverse(BiTree T, Status (*visit)(int)){
if(T){
if( (*visit)(T->data) )
if( PreOrderTraverse(T->lchild,(*visit)) )
if( PreOrderTraverse(T->rchild,(*visit)) )
return OK;
return ERROR;
}
else return OK;
}
int main()
{
BiTree T;
scanf("%d", &num);
num -= 1;
for(int i = 0; i <= num; ++i)
scanf("%d", &sub[i]);
getchar();
for(int i = 0; i <= num; ++i)
scanf("%d", &mid[i]);
GetCompleteSub(sub, mid, num + 1);
// for(int i = 0; i < cnt; ++i)
// printf("%d", sub_complete[i]);
CreateBiTree(T, sub_complete);
printf("Preorder:");
PreOrderTraverse(T, PrintT);
}
方法二
------------------------------------------------------------------
#include <bits/stdc++.h>
using namespace std;
void GetPrefix(int *postfix, int *mid, int pos)
{
if(pos < 0)
return;
else
{
int i;
for(i = 0; ; i++)
{
if(mid[i] == postfix[pos])
{
break;
}
}
printf(" %d\n", mid[i]);
GetPrefix(postfix, mid, i - 1);
GetPrefix(postfix + i, mid + i + 1, pos - 1 - i);
}
}
int main()
{
int postfix[35], mid[35];
int n;
scanf("%d", &n);
for(int i = 0; i < n; ++i)
scanf("%d", &postfix[i]);
for(int i = 0; i < n; ++i)
scanf("%d", &mid[i]);
printf("Preorder:\n");
GetPrefix(postfix, mid, n - 1);
}