剑指 Offer 07. 重建二叉树(C语言)
剑指 Offer 07. 重建二叉树(C语言)
1. Title
输入某二叉树的前序遍历和中序遍历的结果,请构建该二叉树并返回其根节点。
假设输入的前序遍历和中序遍历的结果中都不含重复的数字。
详情:点击这里
2. Do it
2.1. version 0.1(success)
/*!
* @file 07buildTree.c
* @date 2021-08
* @version 0.1
* @author forbit
* @brief 构建二叉树的时候采用分块的思想,拆分二叉树,更容易实现。
* @details score 24-44ms 7.2-7.6MB
*/
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* struct TreeNode *left;
* struct TreeNode *right;
* };
*/
struct TreeNode* buildTree(int* preorder, int preorderSize, int* inorder, int inorderSize){
/*!
* @brief
* @param preorder 前序遍历的数组的指针
* @param preorderSize 前序遍历的数组preorder的长度
* @param inorder 中序遍历的数组
* @param inorderSize 中序遍历的数组inorder的长度
* @return 输出结构体指针,指向已经构建好的二叉树的根节点
*/
//! 判断空
if(preorderSize==0) return NULL;
//! 初始化
struct TreeNode* tree_p = (struct TreeNode*)malloc(sizeof(struct TreeNode));
tree_p->left = NULL; tree_p->right = NULL;
tree_p->val = preorder[0];
int *p_array=inorder; //!< 用于表示暂时切割后的中序遍历的数组
int *p_array_preorder=preorder; //!< 用于表示暂时切割后的前序遍历的数组
int p_num=preorderSize; //!< 用于表示暂时切割后的数组的长度
//! 二叉树
buil_tree( tree_p,
p_array,
p_num,
p_array_preorder);
return tree_p;
}
void buil_tree( struct TreeNode* tree_p,
int *p_array,
int p_num,
int *p_array_preorder)
{
/*!
* @brief
* @param tree_p 二叉树头的指针
* @param p_array 表示暂时切割后的中序遍历的数组
* @param p_num 表示暂时切割后的数组的长度
* @param p_array_preorder 表示暂时切割后的前序遍历的数组
* @return null
*/
int root_index=0; //!< 表示暂时的root在p_array中的索引
for(int i=0; i<p_num; i++) if(p_array[i]==tree_p->val) root_index=i;
//! 判断存在左子树
if(root_index>0)
{
build_left( tree_p,
p_array,
p_num,
p_array_preorder);
}
//! 判断存在右子树
if(root_index<p_num-1)
{
build_right( tree_p,
p_array,
p_num,
p_array_preorder,
p_num);
}
}
void build_left( struct TreeNode* tree_p,
int *p_array,
int p_num,
int *p_array_preorder)
{
/*!
* @brief
* @param tree_p 二叉树头的指针
* @param p_array 表示暂时切割后的中序遍历的数组
* @param p_num 表示暂时切割后的数组的长度
* @param p_array_preorder 表示暂时切割后的前序遍历的数组
* @return null
*/
int root_index=0; //!< 表示暂时的root在p_array中的索引
for(int i=0; i<p_num; i++) if(p_array[i]==tree_p->val) root_index=i;
// 调试
printf("have a left son\n");
printf("p_array[0]:%d, p_num:%d,p_array_preorder[0]:%d,p_array_preorder:%d, tree->val(root):%d\n",p_array[0],p_num,p_array_preorder[0],p_num,tree_p->val);
//! 开辟空间
struct TreeNode* tree_left = (struct TreeNode*)malloc(sizeof(struct TreeNode));
tree_left->left=NULL; tree_left->right=NULL;
tree_p->left=&tree_left->val;
//! 给左子树赋值
tree_left->val=p_array_preorder[1];
//! 更新p_array, p_num,p_array_preorder
for(int i=0; i<p_num; i++) if(p_array[i]==tree_p->val) root_index=i;
p_array=&p_array[0];
p_num=root_index;
p_array_preorder=&p_array_preorder[1];
// 调试
printf("p_array[0]:%d, p_num:%d,p_array_preorder[0]:%d,p_array_preorder:%d, tree_left->val(root):%d\n",p_array[0],p_num,p_array_preorder[0],p_num,tree_left->val);
//! 递归
buil_tree( tree_left,
p_array,
p_num,
p_array_preorder);
}
void build_right( struct TreeNode* tree_p,
int *p_array,
int p_num,
int *p_array_preorder)
{
/*!
* @brief
* @param tree_p 二叉树头的指针
* @param p_array 表示暂时切割后的中序遍历的数组
* @param p_num 表示暂时切割后的数组的长度
* @param p_array_preorder 表示暂时切割后的前序遍历的数组
* @return null
*/
int root_index=0; //!< 表示暂时的root在p_array中的索引
for(int i=0; i<p_num; i++) if(p_array[i]==tree_p->val) root_index=i;
// 调试
printf("have a right son\n");
printf("p_array[0]:%d, p_num:%d,p_array_preorder[0]:%d,p_array_preorder:%d, tree->val(root):%d\n",p_array[0],p_num,p_array_preorder[0],p_num,tree_p->val);
//!开辟空间
struct TreeNode* tree_right = (struct TreeNode*)malloc(sizeof(struct TreeNode));
tree_right->left=NULL; tree_right->right=NULL;
tree_p->right=&tree_right->val;
//! 给右子树赋值
for(int i=0; i<p_num; i++) if(p_array[i]==tree_p->val) root_index=i;
tree_right->val=p_array_preorder[root_index+1];
//! 更新p_array, p_num,p_array_preorder
p_array=&p_array[root_index+1];
p_num=p_num-root_index-1;
p_array_preorder=&p_array_preorder[root_index+1];
//! 递归
buil_tree( tree_right,
p_array,
p_num,
p_array_preorder);
}

浙公网安备 33010602011771号