【树】Tree Traversals Again

【树】Tree Traversals Again

题目要求:

An inorder binary tree traversal can be implemented in a non-recursive way with a stack. For example,suppose that when a 6-node binary tree (with the keys numbered from 1 to 6) is traversed, the stack operations are: push(1); push(2); push(3); pop(); pop(); push(4); pop(); pop(); push(5); push(6); pop(); pop(). Then a unique binary tree (shown in Figure 1) can be generated from this sequence of operations. Your task is to give the postorder traversal sequence of this tree.在这里插入图片描述

输入格式:

Each input file contains one test case. For each case, the first line contains a positive integer N (≤30) which is the total number of nodes in a tree (and hence the nodes are numbered from 1 to N). Then 2N lines follow, each describes a stack operation in the format: “Push X” where X is the index of the node being pushed onto the stack; or “Pop” meaning to pop one node from the stack.

输出格式:

For each test case, print the postorder traversal sequence of the corresponding tree in one line. A solution is guaranteed to exist. All the numbers must be separated by exactly one space, and there must be no extra space at the end of the line.

输入样例:

6
Push 1
Push 2
Push 3
Pop
Pop
Push 4
Pop
Pop
Push 5
Push 6
Pop
Pop

输出样例:

3 4 2 6 5 1

解题思路:
  1. 入栈的顺序为树的先序遍历,出栈的顺序为树的中序遍历,相当于已知先序遍历和中序遍历求后序遍历序列。
  2. 思路1:直接利用递归求解后序遍历序列;思路2:先建树,再后序遍历。

本程序采用思路1。

注意:

IsFull 函数和 IsEmpty 函数中需要传参,小心遗漏。

完整程序:
/*
【解题思路】
1.入栈的顺序为树的先序遍历,出栈的顺序为树的中序遍历,相当于已知先序遍历和中序遍历求后序遍历序列
2.思路1:直接利用递归求解后序遍历序列;思路2:先建树,再后序遍历

本程序采用思路1
*/ 

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MaxSize 30
#define true 1
#define false 0

typedef struct SNode {
	int *data;  
	int top; // 栈顶指针,空栈为-1 
	int maxSize; 
} *Stack;

int pre[MaxSize],in[MaxSize],post[MaxSize]; // 分别存放先序、中序序列和后序序列 

Stack CreateStack(); // 创建栈 
void Push(Stack S,int ele); // 入栈
int Pop(Stack S); // 出栈
int IsFull(Stack S); // 判断栈满
int IsEmpty(Stack S); // 判断栈空
void PostOrder(int preL,int inL,int postL,int n); // 由先序遍历和中序遍历序列得到后序遍历序列
 
int main()
{
	Stack S;
	int i,N; // N为结点个数,因为每个结点被push一次pop一次,所以之后会有2 * N行输入 
	int pj = 0,ij = 0; // pj为pre数组的下标,ij为in数组的下标 
	char str[10]; // 临时存放"Push"或"Pop"的字符数组 
	int e; // 结点元素 
	S = CreateStack();
	scanf("%d",&N);
	getchar(); // 读取缓存区的回车符
	for(i = 0;i < 2 * N;i ++) {
		scanf("%s",str); // 输入空白字符结束 
		if(strcmp(str,"Push") == 0) {
			scanf("%d",&e);
			getchar();
			pre[pj ++] = e; 
			Push(S,e);
		}
		else {
			in[ij ++] = Pop(S);
		}
	} 
	PostOrder(0,0,0,N);
	for(i = 0;i < N -1;i ++) {
		printf("%d ",post[i]);
	}
	printf("%d",post[i]);
	
	return 0; 
}

Stack CreateStack()
{
	Stack S = (Stack)malloc(sizeof(struct SNode));
	S -> data = (int *)malloc(MaxSize * sizeof(int));
	S -> top = -1;
	S -> maxSize = MaxSize;
	return S;
}

int IsFull(Stack S)
{
	if(S -> top == S -> maxSize -1)
		return true; // 栈满 
	else 
		return false; 
}

int IsEmpty(Stack S)
{
	if(S -> top == -1)
		return true;
	else 
		return false;	
}
 
void Push(Stack S,int ele)
{
	if(!IsFull(S)) // 注意别忘记参数 
		S -> data[++ (S -> top)] = ele;
	else 
		return;
}

int Pop(Stack S)
{
	if(!IsEmpty(S)) // 注意别忘记参数 
		return (S -> data[(S -> top) --]);	
	else 
		return false;
}

void PostOrder(int preL,int inL,int postL,int n) // preL:pre数组的最左项;inL:in数组的最左项;postL:post数组的最左项;n:结点数 
{
	int i,L,R;
	int root; // 树根结点 
	if(n == 0) return;
	if(n == 1) {
		post[postL] = pre[preL];
		return;
	}
	root = pre[preL]; // pre数组的最左项就是树根结点 
	post[postL + n - 1] = root; 
	for(i = 0;i < n;i ++) 
		if(in[inL + i] == root)	break;
	L = i; // 左子树结点数 
	R = n - L - 1;  // 右子树结点数
	PostOrder(preL + 1,inL,postL,L); // 左子树递归
	PostOrder(preL + L + 1,inL + L + 1,postL + L,R); // 右子树递归 
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

百栗.

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值