测试了30个元素的斜二叉树结果是对的,但是oj仍然有问题
希望有大佬能够解答!
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MaxSize 30
#define Null -1
/**
入栈顺序即先序遍历顺序,出栈顺序即中序遍历顺序
已知先序遍历和中序遍历求后续遍历:
1 先+中 得到树的结构
2 后续遍历树
注意,可以不用得出树的结构数组再得到后序遍历:
根据递归,每次根节点为后序遍历数组(最后)的元素
右子树根节点要比左子树根节点更靠后
先+中 得到树结构:
由 先 中 可得到 (子)树根节点 以及左右子树
接着递归左右子树的 先 中 即可
*/
typedef struct TreeNode {
int data;
int left;
int right;
} TNode;
int pre[MaxSize], in[MaxSize];
TNode T[MaxSize]; //存放树结点的结构数组
void BulidTree(int prel, int inl, int N, int Root);
void PostOrderTraversal(int Root);
int main() {
int N;
scanf("%d\n",&N);
char operation[5];
char *Push="Push";
int stack[MaxSize];
int top=-1;
int num;
int prel, inl, postl;
prel=inl=postl=0;
for(int i=0; i<2*N; i++) {
scanf("%s",operation);
if(strncmp(operation,Push,2)==0) {
scanf("%d",&num);
stack[++top]=num;
pre[prel++]=num;
} else {
num=stack[top--];
in[inl++]=num;
}
}
int Root=0;
//按照先序遍历的顺序将树的结构数组中data部分赋值,指针都初始化为Null
for(int i=0; i<N; i++) {
T[i].data=pre[i];
T[i].left=Null;
T[i].right=Null;
}
// printf("---------------------------------\n");
// for(int i=0; i<N; i++) {
// printf("%d %d %d\n",T[i].data,T[i].left,T[i].right);
// }
// printf("---------------------------------\n");
// for(int i=0; i<N; i++) {
// printf("%d\n",pre[i]);
// }
// printf("---------------------------------\n");
// for(int i=0; i<N; i++) {
// printf("%d\n",in[i]);
// }
//还原树的结构,需要递归求解
prel=inl=postl=0;
BulidTree(prel, inl, N, Root);
// printf("---------------------------------\n");
// for(int i=0; i<N; i++) {
// printf("%d %d %d\n",T[i].data,T[i].left,T[i].right);
// }
//后序遍历
PostOrderTraversal(Root);
return 0;
}
void BulidTree(int prel, int inl, int N, int Root) {
if(N==0) {
return;
}
int L=0; //分开左子树,左子树的元素个数
int R=0; //分开右子树,右子树的元素个数
int i;
for(i=inl; i<N; i++) {
if(pre[prel]==in[i]) //此时in[i]为(子)树的根节点
break;
L++; //L为左子树的元素个数
}
R=N-L-1; //R为右子树元素个数
//判断左右子树的根节点与pre[prel]的位置关系
if(L!=0) {
T[Root].left=prel+1; //先序遍历左子树部分的根节点即根的左孩子
}
if(R!=0) {
T[Root].right=prel+L+1; //先序遍历右子树部分的根节点即根的右孩子
}
/**
难点在于如何递归:
根据先序,中序能够划分左右子树,
因此,递归左子树与右子树即可
先序起始 中序起始 子树元素个数 子树根下标
左子树 pre+1(L!=0) i-L L pre+1(L!=0)
右子树 pre+L+1(R!=0) i+1 R pre+L+1(R!=0)
*/
if(L!=0)
BulidTree(prel+1, i-L, L, prel+1); //递归左子树
if(R!=0)
BulidTree(prel+L+1, i+1, R, prel+L+1); //递归右子树
return;
}
void PostOrderTraversal(int Root) {
if(Root!=Null) {
PostOrderTraversal(T[Root].left);
PostOrderTraversal(T[Root].right);
printf("%d",T[Root].data);
if(Root!=0) { //后续遍历最后一个肯定是T[0]
printf(" ");
}
}
}
)