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

来源:互联网 发布:知图科技 编辑:程序博客网 时间:2024/06/06 07:12

题目:输入二叉树的前序和中序遍历结果,请重建出二叉树。假如输入的前序遍历和中序遍历结果中不含重复数字(关键,如果重复了,该程序就不适用用了)。如输入的前序遍历是{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;}


0 0
原创粉丝点击