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.

Input Specification:

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.

Output Specification:

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.

Sample Input:

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

Sample Output:

3 4 2 6 5 1

我的代码:C++(g++ 6.5.0)

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<stdbool.h>
#define MaxSize 30

typedef struct Stack *PtrToStack;
struct Stack {
	int top;
	char stack[MaxSize];
};

char preOrder[MaxSize + 1]; //位置0不存节点
char inOrder[MaxSize + 1]; 
char postOrder[MaxSize + 1]; 

void BuildTree(PtrToStack S, char preOrder[], char inOrder[], char postOrder[], int N) {
	char oprtn[5];
	int i;
	int j = 1;
	int k = 1;
	int node;
	for (i = 1; i <= 2*N; i++) {
		scanf("%s", oprtn);
		if (strcmp(oprtn, "push") == 0) { //push
			scanf("%d", &node);
			preOrder[j++] = node;
			S->stack[S->top++] = node;

		}else { //pop
			char temp = S->stack[--S->top];
			inOrder[k++] = temp;
		}
	}
}

void Solve(char preOrder[], char inOrder[], char postOrder[], int Num, int preL, int inL, int postL) {
	/*Num遍历时的节点总数 不是总的节点数, first先序遍历起始点, left与right是后序数组的区间*/
	int i,index,lNum,rNum;
	if (Num == 0) return;
	if (Num==1) { 
		postOrder[postL] = preOrder[preL];
		return;
	}
	postOrder[postL+Num-1] = preOrder[preL]; //先序遍历第一个节点为根节点,放在后序遍历区间最后一个位置
	for (i = 0; i <= MaxSize; i++) { //找到根节点在中序遍历中的位置
		if (inOrder[i] == preOrder[preL]) {
			index = i;
			break;
		}
	}
	lNum = index - inL;  //左子树节点个数
	rNum = inL + Num - index - 1;   //inL用于计算左右子树的节点数的
	Solve(preOrder, inOrder, postOrder, lNum, preL+1, inL, postL);
	Solve(preOrder, inOrder, postOrder, rNum, preL+lNum+1, index+1, postL + lNum);
}

int main()
{
	int N;
	bool first = true; //输出是否为第一个元素的标记
	PtrToStack S = (PtrToStack)malloc(sizeof(struct Stack));  //记得free
	S->top = 0;
	scanf("%d", &N);
	BuildTree(S, preOrder, inOrder, postOrder,N);
	Solve(preOrder, inOrder, postOrder, N, 1, 1, 1);
	for (int i = 1; i <= N;i++) {
		if (first) {
			printf("%d", postOrder[i]);
			first = false;
		}else {
			printf(" %d", postOrder[i]);
		}
	}
	return 0;
}
posted @ 2020-09-06 23:18  敵人杰  阅读(158)  评论(0编辑  收藏  举报