【题目5】使用前序遍历和中序遍历结果构造二叉树
这个题目在<二叉树C++实现>
http://blog.csdn.net/luno1/article/details/7951993,里面有提到,需要记住的是前序定根,中序定左右就行了,比如前序遍历序列{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】二插搜索树与双向链表
(待续)