剑指offer06题二叉树的重建(c语言)
题目:输入二叉树的前序和中序遍历结果,请重建出二叉树。假如输入的前序遍历和中序遍历结果中不含重复数字(关键,如果重复了,该程序就不适用用了)。如输入的前序遍历是{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! "); 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 "); return 1; } printf("先序:"); P_BTree(root); printf(" "); printf("中序:"); I_BTree(root); printf(" "); printf("后序:"); A_BTree(root); printf(" "); return 0; }
声明:该文观点仅代表作者本人,牛骨文系教育信息发布平台,牛骨文仅提供信息存储空间服务。
- 上一篇: 搭建WebSocket服务器与客户端
- 下一篇: 20070929迅雷面试部分题