编程之美:第三章 结构之法 3.9重建二叉树

来源:互联网 发布:腾讯手游助手mac版 编辑:程序博客网 时间:2024/05/20 07:37
/*重建二叉树:给定一颗二叉树,假设每个节点都用唯一的字符来表示假设已经有了前序和中序遍历结果,希望通过一个算法来重建这课树给定函数如下void Rebuild(char* pPreOrder,char* pInOrder,int iTreeLen,Node** pRoot)iTreeLen:树的长度,pRoot返回Node** 类型,根据前序和中序遍历结果重新构建树的根节点                     ab          cd           e      f输入:abdcef(前序)dbaecf(中序)输出:dbefca*//*关键:1 这道题目与王道解法不同之处在与,没有使用下限与上限,而是直接使用了树的长度,并且通过直接对字符串的指针进行加,来达到去除上下限参数的方法2 检查边界,获得前序遍历第一个节点,设置左右孩子为空。如果根节点为空,把当前节点复制到根节点;如果当前树长度为1,那么已经是最后一个节点,直接返回,寻找子树长度,找打左子树的结尾。计算左子树长度和右子树长度,左子树长度>0,重建左子树,右子树长度>0,重建右子树3 if(!(*pRoot))//如果根节点为空,就将当前节点复制到根节点{*pRoot = pTemp;}4 if(iTreeLen == 1)//递归出口,如果当前树的长度为1,表示已经是最后一个节点,后面的左右子树寻找就不需要做了{return;}5 int iRightLen = iTreeLen - iLeftLen - 1;//注意这里的-1代表根节点,要去除6 if(iLen > iTreeLen)//如果超出长度,直接退出{break;}7if(iLeftLen > 0)//左子树不空,建立左子树{Rebuild(pPreOrder+1,pInOrder,iLeftLen,&((*pRoot)->_pLeft));}8 Rebuild(pPreOrder + iLeftLen + 1,pInOrder + iLeftLen + 1,iRightLen,&((*pRoot)->_pRight));//注意这里要pInOder+iLeftLen+1因为要跳过根节点*/#include <stdio.h>#include <string.h>#include <iostream>using namespace std;const int MAXSIZE = 10000;const int TREELEN  = 6;typedef struct Node{char _chVal;Node* _pLeft;Node* _pRight;}Node;Node g_nodeArr[MAXSIZE];int g_iIndex;Node* createNode(){++g_iIndex;g_nodeArr[g_iIndex]._pLeft = g_nodeArr[g_iIndex]._pRight = NULL;return &g_nodeArr[g_iIndex];}/*重建思路:检查边界,获得前序遍历第一个节点,设置左右孩子为空。如果根节点为空,把当前节点复制到根节点;如果当前树长度为1,那么已经是最后一个节点,直接返回,寻找子树长度,找打左子树的结尾。计算左子树长度和右子树长度,左子树长度>0,重建左子树,右子树长度>0,重建右子树*/void Rebuild(char* pPreOrder,char* pInOrder,int iTreeLen,Node** pRoot){if(!pPreOrder || !pInOrder){return;}Node* pTemp = createNode();//获得前序遍历的第一个节点pTemp->_chVal = *pPreOrder;if(!(*pRoot))//如果根节点为空,就将当前节点复制到根节点{*pRoot = pTemp;}if(iTreeLen == 1)//递归出口,如果当前树的长度为1,表示已经是最后一个节点,后面的左右子树寻找就不需要做了{return;}char* pOrgInOrder = pInOrder;//计算左右子树的长度char* pLeft = pInOrder;int iLen = 0;while(*pPreOrder != *pLeft){if(!pPreOrder || !pLeft){return;}iLen++;if(iLen > iTreeLen)//如果超出长度,直接退出{break;}pLeft++;}int iLeftLen = (int)(pLeft - pOrgInOrder);int iRightLen = iTreeLen - iLeftLen - 1;//注意这里的-1代表根节点,要去除if(iLeftLen > 0)//左子树不空,建立左子树{Rebuild(pPreOrder+1,pInOrder,iLeftLen,&((*pRoot)->_pLeft));}if(iRightLen > 0)//右子树不空,建立右子树{Rebuild(pPreOrder + iLeftLen + 1,pInOrder + iLeftLen + 1,iRightLen,&((*pRoot)->_pRight));//注意这里要pInOder+iLeftLen+1因为要跳过根节点}}void backVisit(Node* pRoot){if(!pRoot){return;}backVisit(pRoot->_pLeft);backVisit(pRoot->_pRight);printf("%c",pRoot->_chVal);}void process(){char strPreOrder[MAXSIZE],strInOrder[MAXSIZE];while(EOF != scanf("%s %s",strPreOrder,strInOrder)){Node* pRoot = NULL;Rebuild(strPreOrder,strInOrder,strlen(strPreOrder),&pRoot);backVisit(pRoot);printf("\n");}}int main(int argc,char* argv[]){process();getchar();return 0;}

0 1
原创粉丝点击