根据前序和中序遍历结果重建二叉树

解决思想:根据前序遍历的结果得到树根(包括子树)将中序遍历的结果划分成左右子树,来进行递归
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

typedef struct Node
{
char chValue;
struct Node *lChild;
struct Node *rChild;
}Node;


//重建二叉树
void Rebuild(char*pPreOrder , char*pInOrder , Node **pRoot , int nTreeLen)
{
int nLeftLen , nRightLen;  //左右子树长度
char* pLeftEnd;  //查找左子树的结束位置,以便确定左子树长度
Node *p;

//边界条件检查
if(!pPreOrder ||!pInOrder ||!pRoot) return;

if(!(p = (Node *)malloc(sizeof(Node)))) return;
p->chValue =*pPreOrder;   //p为前序遍历的第一个节点
p->lChild = p->rChild = NULL;
if(*pRoot==NULL)     //若根节点为空,则把当前第一个节点赋值给根节点
    *pRoot = p;

if(nTreeLen ==1) return;   //树长度为一,已经到结尾,直接返回

//划分左右子数
pLeftEnd = pInOrder;
while(*pLeftEnd !=*pPreOrder) pLeftEnd++;
nLeftLen = (int)(pLeftEnd - pInOrder);
nRightLen = nTreeLen - nLeftLen -1;

if(nLeftLen) Rebuild(pPreOrder +1 , pInOrder , &((*p)->lChild) , nLeftLen); //递归重建左子树
if(nRightLen) Rebuild(pPreOrder + nLeftLen +1, pInOrder + nLeftLen +1 , &((*p)->rChild) , nRightLen);//递归重建右子树
}

//后序遍历
void PostOrder(Node *p)
{
if(p)
{
PostOrder(p->lChild);
PostOrder(p->rChild);
printf("%c",p->chValue);
}
}

int main(void)
{
char PreOrder[32] , InOrder[32];
Node *pTree;

//输入先序和中序序列
while(scanf("%s%s", PreOrder , InOrder) != EOF)
{
Rebuild(PreOrder , InOrder , &pTree , strlen(PreOrder));
PostOrder(pTree);
printf("\n");
}
return0;
}

posted on 2012-05-08 10:03  温柔的暴力  阅读(583)  评论(0编辑  收藏  举报

导航