剑指offer06题二叉树的重建(c语言)

本文介绍了一种根据给定的前序和中序遍历结果重建二叉树的方法,并提供了一个完整的C语言实现示例。通过递归地确定根节点及左右子树的位置,最终构建出完整的二叉树结构。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目:输入二叉树的前序和中序遍历结果,请重建出二叉树。假如输入的前序遍历和中序遍历结果中不含重复数字(关键,如果重复了,该程序就不适用用了)。如输入的前序遍历是{1,2,4,7,3,5,6,8,}和中序遍历{4,7,2,1,5,3,8,6},请重建出它的二叉树。

二叉树的结构


分析图

如图中所示,

1:前序遍历第1个结点是根结点,对应了中序遍历的root的位置,就可以根据中序遍历序列得出1前面是该二叉树的左子树,后面是该二叉树的右子树。

2:根据前序遍历根节点得出下一个节点是左子树的根节点。

3:根据中序遍历得出根节点1的位置,然后和前序遍历的root结点位置相加再加1,就得到了右子树的根节点是3

4:依次类推,利用递归直到查完整个序列。

代码:

/*************************************************************************
    > File Name: 06.c
    > Author: ma6174
    > Mail: ma6174@163.com 
    > Created Time: Mon 03 Mar 2014 08:01:53 PM PST
 ************************************************************************/

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

typedef struct BTree						/*ding yi er cha shu*/
{
	int data;
	struct BTree *left;
	struct BTree *right;
}btree,*BTREE;
BTREE ConstructCode(int *ptree_start,int *ptree_end,int *itree_start,int *itree_end);/*主递归函数*/
BTREE Construct(int *ptree,int *itree,int length);			/*调用递归函数重建二叉树,返回根节点位置*/
void P_BTree(BTREE btree);									/*先序遍历二叉树函数*/
void I_BTree(BTREE btree);									/*中序遍历二叉树函数*/
void A_BTree(BTREE btree);									/*后序遍历二叉树函数*/

void P_BTree(BTREE btree)									/*先序遍历二叉树函数*/
{
	if(btree==NULL)
		return;
	printf("%d ",btree->data);
	if(btree->left!=NULL)
	{
		P_BTree(btree->left);
	}
	if(btree->right!=NULL)
	{
		P_BTree(btree->right);
	}
}
void I_BTree(BTREE btree)									/*中序遍历二叉树函数*/
{
	if(btree==NULL)
		return;
	if(btree->left!=NULL)
	{
		I_BTree(btree->left);
	}
	printf("%d ",btree->data);
	if(btree->right!=NULL)
	{
		I_BTree(btree->right);
	}
}
void A_BTree(BTREE btree)									/*后序遍历二叉树函数*/
{
	if(btree==NULL)
		return;
	if(btree->left!=NULL)
	{
		A_BTree(btree->left);
	}
	if(btree->right!=NULL)
	{
		A_BTree(btree->right);
	}
	printf("%d ",btree->data);
	free(btree);											/*利用后续遍历释放申请的空间*/
}
BTREE Construct(int *ptree,int *itree,int length)
{
	if(ptree==NULL || itree==NULL || length<=0)
		return NULL;
	return ConstructCode(ptree,ptree+length-1,itree,itree+length-1);
}
/****************************************************************
*args:
*	ptree_start:先序遍历开始位置指针
*	ptree_end:先序遍历结束位置指针
*	itree_start:中序遍历开始位置指针
*	itree_end:中序遍历结束位置指针
****************************************************************/
BTREE ConstructCode(int *ptree_start,int *ptree_end,int *itree_start,int *itree_end)
{
	BTREE root_node;
	root_node=(BTREE)malloc(sizeof(btree));
	root_node->data=ptree_start[0];							/*根节点*/
	root_node->left=NULL;
	root_node->right=NULL;
	if(ptree_start==ptree_end)								/*该节点是子树最后一个节点*/
	{
		if(itree_start==itree_end && *ptree_start==*ptree_end)
		{
			return root_node;
		}else
		{
			printf("ConstructCode is error!\n");
			exit(1);
		}
	}
	int *tmp_itree=itree_start;
	int left_length=0;
	while((*itree_start!=root_node->data) && (itree_start<itree_end))/*在中序遍历中寻找跟节点的指针*/
	{
		itree_start++;
	}
	left_length=itree_start-tmp_itree;						/*根节点在中序遍历中的位置,用于求在先序遍历中右子树的开始位置*/
	if(left_length>0)										/*左子树递归*/
	{
		root_node->left=ConstructCode(ptree_start+1,ptree_start+left_length,tmp_itree,itree_start-1);
	}
	if(left_length<(ptree_end-ptree_start))					/*右子树递归,pend-pstart>left_length说明遍历序列比左子树长,右子树有节点*/
	{
		root_node->right=ConstructCode(ptree_start+left_length+1,ptree_end,itree_start+1,itree_end);
	}
	return root_node;	
}
int main()
{
	int ptree[8]={1,2,4,7,3,5,6,8};
	int itree[8]={4,7,2,1,5,3,8,6};
	int *p;													/*测试为空的情况*/
	int *i;
	BTREE root;
	root=Construct(ptree,itree,8);
	if(root==NULL)
	{
		printf("the tree is NULL\n");
		return 1;
	}
	printf("先序:");
	P_BTree(root);
	printf("\n");
	printf("中序:");
	I_BTree(root);
	printf("\n");
	printf("后序:");
	A_BTree(root);
	printf("\n");
	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值