您的位置:首页 > Web前端

<剑指offer>二叉树专题

2012-09-14 15:04 260 查看

【题目5】使用前序遍历和中序遍历结果构造二叉树

这个题目在<二叉树C++实现>/article/2103244.html,里面有提到,需要记住的是前序定根,中序定左右就行了,比如前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6}。先看前序的第一个元素1,代表了要构造二叉树的根,中序序列列表里面查找1,找到后,可以判断1的左边是根的左子树,右边是根的右子树,这样就将剩下的中序序列分为了{4,7,2,}和{5,3,8,6},对应的前序序列分为{2,4,7,}和{3,5,6,8};然后依次递归,沿着前序序列往后缩小,对{4,7,2,}和{2,4,7,}再进行同样的操作,递归的边界就是前序序列和中序序列只剩一个元素,并且元素相等,这样最左端左子树已经构造好了,然后最{5,3,8,6}和{3,5,6,8}进行递归,不难。代码如下。

【代码5】

#ifndef NULL
#define NULL 0
#endif
struct binary_tree_node
{
	int m_value;
	binary_tree_node* m_left;
	binary_tree_node* m_right;
};
binary_tree_node* construct_core(int* start_preorder, int* end_preorder,
								 int* start_inorder,int* end_inorder);
binary_tree_node* construct_binary_tree(int* pre_order, int* in_order, int len)
{
	if(pre_order == NULL || in_order == NULL || len <1)
		return NULL;
	return construct_core(pre_order, pre_order + len - 1, in_order, in_order + len - 1);
}
binary_tree_node* construct_core(int* start_preorder, int* end_preorder,
								 int* start_inorder,int* end_inorder)
{
	int root_value = start_preorder[0];
	binary_tree_node* node = new binary_tree_node;
	node->m_value = root_value;
	node->m_left = node->m_right = NULL;
	if(start_preorder == end_preorder && start_inorder == end_inorder
		&& *start_preorder == *start_inorder)
		return node;//递归的边界
	int* in_start = start_inorder;
	while(in_start <= end_inorder && *in_start != root_value)
		++in_start;
	if(in_start == end_inorder && *in_start != root_value)
		return NULL;//这数组不合理,前序的值在中序中没有
	int left_len = in_start - start_inorder;
	int* left_preorder_end = start_preorder + left_len;
	if (left_len > 0)
	{
		//构造左子树
		node->m_left = construct_core(start_preorder+1, left_preorder_end, start_inorder, in_start -1);
	}
	if (left_len < end_preorder - start_preorder)
	{	
		//构造右子树
		node->m_right = construct_core(left_preorder_end+1, end_preorder, in_start+1, end_inorder);
	}
	return node;
}

#include <iostream>
#include <queue>
using namespace std;
void level_visit(binary_tree_node* root)
{
	if(root == NULL)
		return;
	queue<binary_tree_node*> m_queue;
	m_queue.push(root);
	while(!m_queue.empty())
	{
		binary_tree_node* b_node = m_queue.front();
		m_queue.pop();
		cout<<b_node->m_value<<" ";
		if (b_node->m_left != NULL)
			m_queue.push(b_node->m_left);
		if(b_node->m_right != NULL)
			m_queue.push(b_node->m_right);
	}

}

【测试5】

上面最后一个函数是为了方便打印出来二叉树,用的层次遍历。
int main()
{
	int pre[] = {1,2,4,7,3,5,6,8};
	int in[] = {4,7,2,1,5,3,8,6};
	binary_tree_node* root = construct_binary_tree(pre, in, sizeof(pre)/sizeof(pre[0]));
	level_visit(root);

}

【题目18】树的子结构

【题目19】二叉树的镜像

【题目24】二插搜索树的后序遍历序列

【题目27】二插搜索树与双向链表

(待续)


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