利用前序、中序遍历或者后序、中序遍历建立二叉树(c)

        二叉树中,可以根据前序遍历或者后序遍历配合中序遍历对二叉树进行还原,不使用中序不能唯一确定一棵二叉树。

一、二叉树前中后遍历总结

前、中、后都是针对头节点来说的。

1.前序遍历:先遍历头节点。头->左->右

下图前序遍历结果:f->b->a->d->c->e->g->i->h

2.中序遍历:左->头->右

下图中序遍历结果:a b c d e f g h i

3.后序遍历:左->右->头

下图后序遍历结果:a c e d b h i g f

       

二、上面相信大家应该都可以遍历出来,那我们应该怎样将其还原出这颗唯一的二叉树呢?

1.前序+中序

思路:前序遍历的第一个节点一定是整棵树的头节点。同样,在中序中找到这个节点位置可以知道根节点左边的数组就是其左子树右边就是右子树。前序左子树为对应根节点后面的和中序左子树长度相同数据右子树在左子树后面

       带入例子中序中,实际就是前序第一个节点为f,是整棵树的头节点。f前面有五个数,是整棵树的左子树(abcde),f后面三个数为右子树(ghi)。前序中对应左子树为f后五个(badce),右子树为剩下三个(gih)。

实现代码:

#include <stdio.h>
//类型定义
struct TreeNode
{
	int val;
	struct TreeNode* left;
	struct TreeNode* right;
};
struct TreeNode* RebuildTree(int* preorder, int perSize, int* inorder, int inSize)
{
	if (preorder == NULL || perSize == 0 || inorder == NULL || inSize == NULL)
		return NULL;
	struct TreeNode* root = malloc(sizeof(struct TreeNode));
	root->val = preorder[0];  //前序第一个为头节点
	int i = 0;
	for (; i < inSize; i++)   //找出头节点位于中序位置
	{
		if (inorder[i] == preorder[0])
			break;
	}
	//递归重建
	root->left = RebuildTree(&preorder[1],i,&inorder[0],i);
	root->right = RebuildTree(&preorder[i+1],perSize-i-1,&inorder[i+1],inSize-i-1);
	return root;
}
int main()
{
	int preorder[5] = { 3,9,20,15,7 };  //先序
	int inorder[5] = { 9,3,15,20,7 };  //中序
	RebuildTree(preorder, 5, inorder, 5);
	return 0;
}

上面的传参方法我觉得很妙,之前都没试过。果然还得是指针。

2.后序+中序

思路:类似前一种,实际后序遍历头节点是从最后开始的,中序同样分割,各位可以仔细思考一下。这里直接给出代码:

#include <stdio.h>
struct TreeNode
{
    int val;
    struct TreeNode* left, * right;
};
struct TreeNode* buildTree(int* inorder, int inorderSize, int* postorder, int postorderSize) {
    if (inorder == NULL || postorder == NULL || inorderSize == 0 || postorderSize == 0)
        return NULL;
    struct TreeNode* root = malloc(sizeof(struct TreeNode));
    root->val = postorder[postorderSize - 1];
    printf("%d ", root->val);
    int i = 0;
    for (; i < inorderSize; i++)
    {
        if (inorder[i] ==root->val)
            break;
    }
    //递归重建
    root->left = buildTree(&inorder[0], i, &postorder[0], i);
    root->right = buildTree(&inorder[i+1],inorderSize-i-1,&postorder[i],postorderSize-i-1);
    return root;
}
int main()
{
    int inorder[] = { 2,1,3 };  //中序
    int postorder[] = { 2,3,1 };//后序
    buildTree(inorder,3, postorder, 3);
	return 0;
}

总结:其实二叉树的遍历都是有迹可循的,各种遍历差别不大。其次,指针和递归是在树这个知识点中最常用的知识点,需要有一定的基础。

  • 5
    点赞
  • 50
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值