您的位置:首页 > 编程语言

<编程之美>3.9重建二叉树

2014-05-28 21:50 295 查看
给定一棵二叉树,前序遍历结果为:a b d c e 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。

得到二叉树:

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: