1020. Tree Traversals (25)

/*-----------------------------------------------------------------------
本题采用先根据后序和中序遍历的结果建树,然后再根据建好的树进行层序遍历的方法来完成
-------------------------------------------------------------------------*/
#include<stdio.h>
#include<stdlib.h>
typedef struct queue* q;
typedef struct Node* node;
struct Node{
	int digit;
	node left;
	node right;
};//树节点的基本结构

struct queue{
	node nodee;
	struct queue* next;
};//树的层序遍历要用到队列

q head=NULL,tail=NULL;

node build_tree(int post[],int in[],int amount);//通过后序遍历和中序遍历的结果建树
int find_root(int post[],int in[],int amount);//找到树(或子树)的根节点
void level_order(node root);//对已经建好的树进行层序遍历
void enqueue(node this_node);
node dequeue();

int main(){
	node root;
	root = (node)malloc(sizeof(struct Node));
	int i,num;
	int mid;
	int postorder[30],inorder[30];
	scanf("%d",&num);
	for(i=0;i<num;i++)
		scanf("%d",&postorder[i]);
	for(i=0;i<num;i++)
		scanf("%d",&inorder[i]);

	mid = find_root(postorder,inorder,num);
	root->digit = postorder[num-1];// or   root->digit = inorder[mid];
	root->left = build_tree(postorder,inorder,mid);
	root->right = build_tree(&postorder[mid],&inorder[mid+1],num-mid-1);
	/*--------------------------------------------------------------------------------------------------------
				后序遍历的结果为 左子树+右子树+根节点;中序遍历的结果为 左子树+根节点+右子树
			因此,树的根节点必然是后序遍历的最后一个元素。在中序遍历的结果中找到这个元素,以此为界,左右分别是根的左右子树
			采用递归的方式逐步劈分左右子树,直到树被建完
	---------------------------------------------------------------------------------------------------------*/
	level_order(root);

	return 0;
}

node build_tree(int post[],int in[],int amount){
	node root;
	int mid;
	if(amount == 0)
		return NULL;
	root = (node)malloc(sizeof(struct Node));
	mid = find_root(post,in,amount);
	root->digit = post[amount-1];
	root->left = build_tree(post,in,mid);
	root->right = build_tree(&post[mid],&in[mid+1],amount-mid-1);
	return root;
}
int find_root(int post[],int in[],int amount){
	int i;
	for(i=0;i<amount;i++)
		if(post[amount-1] == in[i])
			return i;
}

/*-----------------------------------------------------------------------
	层序遍历的基本方法(使用队列的数据结构,非递归)好像也没有递归方法=_=||
	1、根入队
	2、根的所有儿子入队
	3、进行一次出队,对出队的元素进行visit,并令出队元素为新的根
	4、从2开始重复步骤,直到队列为空
-------------------------------------------------------------------------*/
void level_order(node root){
	enqueue(root);
	while(root){
		root = dequeue();
		if(root){//not a empty queue
			enqueue(root->left);
			enqueue(root->right);
			printf("%d",root->digit);
			if(head)
				printf(" ");
		}
	}
	return ;
}

/*入队操作*/
void enqueue(node this_node){
	if(this_node==NULL)
		return ;
	if(head == NULL){
		tail =  (q)malloc(sizeof(struct queue));
		head = tail;
	}
	else{
		tail->next = (q)malloc(sizeof(struct queue));
		tail = tail->next;
	}
	tail->nodee = this_node;
	tail->next = NULL;
	return ;
}

/*出队操作*/
node dequeue(){
	if(head == NULL)
		return NULL;
	else {
		node p;
		q temp;
		p = head->nodee;
		temp = head;
		head=head->next;
		free(temp);
		return p;
	}
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值