03-树3 Tree Traversals Again

03-树3 Tree Traversals Again

本题目来源于PTA上的《中国大学MOOC-陈越、何钦铭-数据结构-2019春》题目集。
下面是题目:
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.
03-树3 Tree Traversals Again_第1张图片

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

受到 https://www.cnblogs.com/ch122633/p/8758346.html 的启发,程序思路:直接从输入的Push和Pop入手,第一个Push的一定是根节点,每Push一下就可以为树增加一个节点,BT指针始终指向Push进去的新节点,或者是Pop出来的节点,判断新Push进来的是当前节点(BT指向的节点)左孩子还是右孩子,就看上一次的操作是Push,还是Pop,Push:左孩子,Pop:右孩子

c语言实现代码:

#include "stdio.h"
#include "string.h"
#include "stdlib.h"
#include "stdbool.h"
#define NMAX 30
typedef int ElementType;

typedef struct TNode *Position;
typedef Position BinTree; /* 二叉树类型 */
struct TNode{ /* 树结点定义 */
	ElementType Data; /* 结点数据 */
	BinTree Left;     /* 指向左子树 */
	BinTree Right;    /* 指向右子树 */
};

typedef struct SNode *PtrToSNode;
typedef PtrToSNode Stack;
struct SNode{
	BinTree Data;
	PtrToSNode Next;
};
Stack CreateStack(){
	/* 构建一个堆栈的头结点,返回该结点指针 */
	Stack S;
	S = (Stack)malloc(sizeof(struct SNode));
	S->Next = NULL;

	return S;
}

bool IsEmpty(Stack S)
{ /* 判断堆栈S是否为空,若是返回true;否则返回false */
	return (S->Next == NULL);
}

bool Push(Stack S, BinTree X)
{ /* 将元素X压入堆栈S */
	PtrToSNode TmpCell;

	TmpCell = (PtrToSNode)malloc(sizeof(struct SNode));
	TmpCell->Data = X;
	TmpCell->Next = S->Next;
	S->Next = TmpCell;
	return true;
}

BinTree Pop(Stack S)
{ /* 删除并返回堆栈S的栈顶元素 */
	PtrToSNode FirstCell;
	BinTree TopElem;

	if (IsEmpty(S)) {
		printf("堆栈空");
		return NULL;
	}
	else {
		FirstCell = S->Next;
		TopElem = FirstCell->Data;
		S->Next = FirstCell->Next;
		free(FirstCell);
		return TopElem;
	}
}

void Read_input();
BinTree build_Tree();
void PostorderTraversal(BinTree BT);

int N;
char push_pop[2 * NMAX][10];
int inorder[NMAX], preorder[NMAX];

int main()
{
	int i, j = 0, num;
	BinTree BT;
	
	Read_input();
	for (i = 0; i < 2 * N; i++){
		if (strlen(push_pop[i]) > 4){ //Push操作
			num = push_pop[i][5] - '0';
			preorder[j] = num;
			j++;
		}
	}
	BT = build_Tree();
	PostorderTraversal(BT);
	
	return 0;
}

void Read_input(){
	int i,j = 0;	
	
	scanf_s("%d", &N);
	getchar(); //读取缓存区的回车符
	for (i = 0; i < 2 * N; i++){
		gets_s(push_pop[i], 10);
	}
}

BinTree build_Tree(){
	BinTree BT, Root, newTree;
	int i, last_is_push, num,ge,shi;
	Stack S;

	S = CreateStack();

	BT = (BinTree)malloc(sizeof(struct TNode));
	BT->Data = preorder[0];
	BT->Left = NULL;
	BT->Right = NULL;
	Push(S, BT);
	Root = BT;
	last_is_push = 1;
	for (i = 1; i < 2 * N; i++){
		if (strlen(push_pop[i]) > 4){	
			if (strlen(push_pop[i]) ==6)
				num = push_pop[i][5] - '0';
			else{
				ge = push_pop[i][6] - '0';
				shi = push_pop[i][5] - '0';
				num = shi * 10 + ge;
			}
			
			newTree = (BinTree)malloc(sizeof(struct TNode));
			newTree->Data = num;
			newTree->Left = NULL;
			newTree->Right = NULL;
			Push(S, newTree);
			if (last_is_push){	//如果上一次是Push操作,则这次Push的为当前节点的左孩子
				BT->Left = newTree;
			}
			else{	//如果上一次是Pop操作,则这次Push的为当前节点的右孩子
				BT->Right = newTree;
			}
			BT = newTree;
			last_is_push = 1;
		}
		else{
			BT = Pop(S);
			last_is_push = 0;
		}
	}

	return Root;
}
int flag = 0;
void PostorderTraversal(BinTree BT){
	if (BT){
		PostorderTraversal(BT->Left);
		PostorderTraversal(BT->Right);
		if (flag == 0){
			flag = 1;
		}
		else{
			printf(" ");
		}
		printf("%d", BT->Data);
	}
}

你可能感兴趣的:(数据结构)