<编程之美>3.9重建二叉树
2014-05-28 21:50
295 查看
给定一棵二叉树,前序遍历结果为:a b d c e f
中序遍历结果为:d b a e c g
二叉树为:
1. 前序遍历 ab dc e f
中序遍历 d b a e
c f
2 (左) 前序遍历 bd (右) 前序遍历 ce f
中序遍历
d b 中序遍历 e c f
3 (左) 前序遍历 d (右) 前序遍历 空 3 (左) 前序遍历 e (右)前序遍历 f
中序遍历 d 中序遍历 空 中序遍历 e 中序遍历 f
在1中,保存中间节点a,然后进入左右部分递归
在2(左)中,保存中间节点b;在2(右),保存中间节点e。然后进入各自的左右递归。
在3(左)(左)中,保存中间节点d;在3(左)(右)中,无节点,空。 在3(右)(左)中,保存中间节点e;在3(右)(右)中,保存中间节点f。
得到二叉树:
中序遍历结果为:d b a e c g
二叉树为:
</pre><pre name="code" class="cpp">#include <iostream> using namespace std; #define TREELEN 6 //定义节点 typedef struct node NODE; struct node { NODE* pLeft; NODE* pRight; char chValue; }; //根据前序遍历和中旬遍历的重建函数 void Rebuild(char *pPreOrder, char *pInOrder, int nTreeLen, NODE** pRoot) { // 防止输入的前序/中序数组为空,只要两个数组不为空,这个判断不起作用 if(pPreOrder == NULL || pInOrder == NULL) { return; } // 新建一个节点pTemp,因为前序遍历第一个值就是中间节点,所以直接赋值给pTemp,这样pTemp就存储了中间节点 NODE* pTemp = new NODE; pTemp->chValue = *pPreOrder; pTemp->pLeft = NULL; pTemp->pRight = NULL; // 将中间节点pTemp赋值给外部接口pRoot if(*pRoot == NULL) { *pRoot = pTemp; } // 递归的最终输出,当前序和中序数组长度均为1时,直接将节点输出即可 if(nTreeLen == 1) { return ; } // 准备寻找左子树的长度,预设参数 char* pOrgInOrder = pInOrder; char* pLeftEnd = pInOrder; int nTempLen = 0; // 左子树的长度 while(*pPreOrder != *pLeftEnd) { if(pPreOrder == NULL||pLeftEnd == NULL) { return; } nTempLen++; //记录临时长度,以免溢出 if( nTempLen > nTreeLen ) { break; } pLeftEnd++; } int nLeftLen = 0; nLeftLen = int(pLeftEnd - pOrgInOrder); // 右子树长度通过总长度和左子树长度求出 int nRightLen = 0; nRightLen = nTreeLen - nLeftLen - 1; //重建左子树 if( nLeftLen > 0 ) { Rebuild( pPreOrder + 1, pInOrder, nLeftLen, &((*pRoot)->pLeft) ); } //重建右子树 if( nRightLen>0 ) { Rebuild(pPreOrder + nLeftLen + 1, pInOrder + nLeftLen +1, nRightLen , &((*pRoot)->pRight) ); } } int main() { char szPreOrder[TREELEN] = {'a','b','d','c','e','f'}; char szInOrder[TREELEN] = {'d','b','a','e','c','f'}; NODE *pRoot = NULL; Rebuild(szPreOrder, szInOrder, TREELEN, &pRoot); return 0; }递归步骤分析:(红色代表左子树,蓝色代表右子树,黑色是中间节点)
1. 前序遍历 ab dc e f
中序遍历 d b a e
c f
2 (左) 前序遍历 bd (右) 前序遍历 ce f
中序遍历
d b 中序遍历 e c f
3 (左) 前序遍历 d (右) 前序遍历 空 3 (左) 前序遍历 e (右)前序遍历 f
中序遍历 d 中序遍历 空 中序遍历 e 中序遍历 f
在1中,保存中间节点a,然后进入左右部分递归
在2(左)中,保存中间节点b;在2(右),保存中间节点e。然后进入各自的左右递归。
在3(左)(左)中,保存中间节点d;在3(左)(右)中,无节点,空。 在3(右)(左)中,保存中间节点e;在3(右)(右)中,保存中间节点f。
得到二叉树:
相关文章推荐
- <二叉树 前中后 层序 非递归遍历 c语言实现>
- <编程之美> 1的数目 c代码实现
- <Android>在Activity被非正常杀死并重建时,使用savedInstanceState进行数据恢复的简单实例
- <数据结构>二叉树的递归、非递归以及层次遍历算法C语言实现
- 剑指offer--<重建二叉树>
- <剑指offer>二叉树专题
- <编程之美>给定一个十进制正整数N,写下从1开始,到N的所有整数,然后数一下其中出现的所有1的个数
- <编程之美>求一个整数的二进制表示1的个数
- <仅是自己做笔记。。。系列-1>二叉树的非递归遍历
- <编程之美>电话号码对应英文字母组合
- <编程之美>学习笔记1
- <仅是自己做笔记。。。系列-2>求二叉树中节点的最大距离
- <剑指offer>二叉树专题
- <Win32> 简单规则BMP验证码自动验证
- <li>标签之间有间距的问题
- <<Git Community Book中文版>>学习笔记
- <c:if>和关于<c:else>的补充
- <%%><%=%>
- <SVN> 代码库迁移
- <D3D> 二维火焰实现的算法