剑指offer-7 根据中序遍历、前序遍历重建二叉树

解本题首先要明确中序遍历和前序遍历的定义,我们可以先根据前序遍历在中序遍历中找到根节点,然后位于中序遍历中根节点左边的就是此根节点对应的左子树,位于中序遍历中根节点右边的就是此根节点对应的右子树,由此产生递归的思路,每次先在前序遍历中找到根节点,然后在中序遍历中确定左子树和右子树,接着递归生成根节点的左子树和右子树即可:
#include <iostream>  
struct BTN //二叉树结点结构  
{
	int value;
	BTN* pleft;
 	BTN* pright;
};

int find_pos(int value, int * mid, int mid_head, int mid_tail){//前序遍历的值value(即根结点)在中序遍历中的位置,用以划分左右子树,mid_head、mid_tail指示当前中序遍历数组范围
	int count = 0;
	for (int i = mid_head ; i <= mid_tail ; i++,count++)
	{
		if (mid[i] == value)  
			break;
	}    
	return count;
}

void build_tree(BTN** root , int* pre , int pre_head , int pre_tail , int* mid , int mid_head , int mid_tail)//根据前序遍历pre[pre_head:pre_tail]和中序遍历mid[mid_head:mid_tail]递归生成左右子树
{
	if (pre_head <= pre_tail&& mid_head<=mid_tail) //边界条件
	{
		*root = new BTN();
		(*root)->pleft = nullptr;
		(*root)->pright = nullptr;
		(*root)->value = pre[pre_head];
		int pos = find_pos(pre[pre_head], mid, mid_head, mid_tail);   		
		build_tree(&((*root)->pleft), pre, pre_head + 1, pre_head +pos,mid,mid_head, mid_head + pos - 1);//左子树的前、中遍历数组
		build_tree(&((*root)->pright), pre,pre_head + pos + 1, pre_tail, mid, mid_head + pos+1, mid_tail);    //右子树的前、中遍历数组
	}
}

BTN* rebuild_BT(int* pre, int * mid, int len)//重建二叉树
{
	if (len <= 0)        
		return nullptr;
	BTN* phead = nullptr; //头节点指针 
	build_tree(&phead, pre, 0, len - 1, mid, 0, len - 1);//因为要改变头节点指针,因此需要传一个二级指针,
	return phead;
}

void print_bt(BTN* root)//递归前序打印树
{    
	if (root!=nullptr)   
 	{       
		std::cout << root->value << " ";  
		print_bt(root->pleft);   
		print_bt(root->pright);   
	 }
}

int main()
{    
	int pre[] = { 1, 2, 4, 7, 3, 5, 6, 8 };
	int mid[] = { 4,7,2,1,5,3,8,6 };
	BTN* phead = rebuild_BT(pre, mid, 8);   
	print_bt(phead);  
	system("pause");
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值