树6——由中序和后序序列构造二叉树

二叉树

这是西北大学考研试题。我们知道,由先序序列和中序序列可以唯一地确定一棵二叉树,同样,由中序序列和后序序列也可以唯一地确定一棵二叉树。先来分析中序序列和后序序列有什么特点。根据二叉树遍历的递归定义,二叉树的后序遍历是先后序遍历左子树,然后后序遍历右子树,最后访问根结点。因此,在后序遍历的过程中,根结点位于后序序列的最后。在二叉树的中序遍历过程中,先中序遍历左子树,然后是根结点,左后遍历右子树。因此,在二叉树的中序序列中,根结点将中序序列分割为左子树序列和右子树序列两个部分。由中序序列的左子树结点个数,通过扫描后序序列,可以将后序序列分为左子树和右子树序列。以此类推,即可构造出二叉树。例如给定结点的中序序列(D,B,G,E,A,C,F)和后序序列(D,G,E,B,F,C,A),则可以唯一确定一颗二叉树,如下图所示。

由后序序列,A是二叉树的根结点,再根据中序序列得知,A的左子树中序序列为(D,B,G,E),右子树中序序列为(C,F)。然后在后序序列中,可以确定A的左子树后序序列为(D,G,E,B),右子树后续序列为(F,C)。进一步,由A的左子树后续序列得知,B是子树(D,G,E)的根结点,由中序序列(D,B,G,E)知道,B的左子树是D,右子树中序序列是(G,E),而后序序列是(G,E)。子树(G,E)的根结点为E,从而左子树为G。因此,确定了A的左子树,同理,可以确定A的右子树。

code:

#include <stdio.h>
#include <stdlib.h>
#include <string>
#include <iostream>

using namespace std;
#define MAXSIZE 100
typedef struct Node
{
	char data;
	struct Node *lchild, *rchild;
}BitNode, *BiTree;
void CreateBiTree(BiTree *T, char *in, char *post, int len);
void PrintLevel(BiTree T);
void PreTraverse(BiTree T);
void PrintLevel(BiTree T)
{
	BiTree Queue[MAXSIZE];
	int front, rear;
	if (T==NULL)
	{
		return;
	}
	front = -1;
	rear = 0;
	Queue[rear] = T;
	while (front!=rear)
	{
		front++;
		printf("%4c",Queue[front]->data);
		if (Queue[front]->lchild!=NULL)
		{
			rear++;
			Queue[rear] = Queue[front]->lchild;
		}
		if (Queue[front]->rchild!=NULL)
		{
			rear++;
			Queue[rear] = Queue[front]->rchild;

		}

	}

}
void PreTraverse(BiTree T)
{
	if (T!=NULL)
	{
		printf("%4c", T->data);
		PreTraverse(T->lchild);
		PreTraverse(T->rchild);
	}
}

void CreateBiTree(BiTree *T, char *in, char *post, int len)
{
	int k;
	char *temp;
	if (len<=0)
	{
		*T = NULL;
		return;
	}
	for (temp = in; temp < in + len;temp++)
	{
		if (*(post+len-1)==*temp)
		{
			k = temp - in;
			(*T) = (BitNode *)malloc(sizeof(BitNode));
			(*T)->data = *temp;
			break;
		}
	}
	CreateBiTree(&((*T)->lchild), in, post, k);
	CreateBiTree(&((*T)->rchild), in + k + 1, post + k, len - k - 1);
}

void TreePrint(BiTree T, int level)
{
	int i;
	if (T==NULL)
	{
		return;
	}
	TreePrint(T->rchild, level + 1);
	for (i = 0; i < level;i++)
	{
		printf("    ");
	}
	printf("%c\n", T->data);
	TreePrint(T->lchild, level + 1);

}



void main()
{
	BiTree T;
	int len;
	char in[MAXSIZE], post[MAXSIZE];
	printf("由中序序列和后序序列构造二叉树: \n");
	printf("请输入中序的字符串序列:");//DBGEACF
	gets_s(in);
	printf("请输入后序的字符串序列:");//DGEBFCA
	gets_s(post);
	len = strlen(post);
	CreateBiTree(&T, in, post, len);
	TreePrint(T, 1);
	printf("\n你建立的二叉树先序遍历结果是: \n");
	PreTraverse(T);
	printf("\n你建立的二叉树层序遍历结果是: \n");
	PrintLevel(T);
	printf("\n");
	system("pause");

}

结果:

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值