二叉树的恢复和遍历

本文介绍了二叉树的先序、中序、后序遍历方法,并通过实例详细解析了如何根据先序和中序序列恢复二叉树的过程,帮助理解二叉树遍历的基本概念。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

二叉树的遍历

  1. 先序遍历(前序遍历)
    遍历顺序
    根节点——先序遍历左子树——先序遍历右子树

  2. 中序遍历
    遍历顺序
    中序遍历左子树——根节点——中序遍历右子树

  3. 后序遍历
    遍历顺序
    后序遍历左子树——后序遍历右子数——根节点

在做二叉树的恢复时,一定要清楚的掌握二叉树的遍历的概念。任何复杂的二叉树都是有基本的二叉树构成。只要明白了二叉树三种遍历的基本概念,就可以快速并准确的写出先序,中序,后序遍历。

二叉树的恢复

根据一道期末考试的题目来分析一下二叉树的恢复
已知一课二叉树的先序序列为KEFJIHGDCAB,中序序列为JFHIGEDKABC,请画出这课二叉树,写出它的后序序列。
解析:
根据先序遍历的基本概念,由先序序列可以知道该二叉树的根节点为K.
如图
该题目左子树含有JFHIGED,右子树含有ABC
将左子树看成一个新题目就是:先序序列是EFJIHGD,中序序列为JFHIGED。
则该二叉树的根节点为E,左子树含有JFHIG,右子树含有D
将此时的左子树又看成一道新题目:先序序列是FJIHG,中序序列是JFHIG。
此二叉树根节点为F,左子树含有J,右子树含有HIG。
将此时的右子树看成一道新题目:先序序列是IHG,中序序列是HIG。
则该二叉树的根节点为I,左子树含有H,右子树含有G。
如图所示:
这里写图片描述
将右子树看成一个新题目就是:先序序列为CAB,中序序列为ABC。
则根节点为C,左子树中含有AB。
则根节点为A,没有左子树,右子树为B。
如图所示:

在C语言中,如果我们已经得到了二叉树后序遍历(Postorder)序遍历(Inorder)的结果,但不允许使用递归,可以利用线索二叉树(Threaded Binary Tree)的思想来恢复原树的结构,并进而计算出前序遍历(Preorder)。线索二叉树是一种特殊的二叉树,它的每个节点除了常规的数据指针外,还额外保存了指向其左孩子、右孩子以及父节点的线索。 首,我们知道: - 中序遍历:左->根->右 - 后序遍历:左->右->根 由于后序遍历最后一个访问的是根节点,我们可以通过这个信息找到根节点。然后,结合中序遍历,我们可以确定根节点的位置: 1. 对于后序遍历的结果,查找最后一个元素(即根节点),它会出现在中序遍历的中间位置。 2. 分别找出中序遍历中左右两部分的开始节点,它们分别是左子树右子树的结束节点。 3. 左子树的前序遍历等于左子树的后序遍历(去除根节点)的前序遍历,右子树的前序遍历则是剩余元素的前序遍历。 4. 组合这三个部分,得到整个二叉树的前序遍历结果。 以下是算法步骤的一个简单示例(假设已有的函数get_leftmost()返回中序遍历的第一个元素,get_rightmost()返回中序遍历的最后一个元素): ```c // 假设后序遍历存储在post[]数组,中序遍历存储在in[]数组 void buildPreOrder(int post[], int in[], int size) { int root = get_last_in_post(post, size); // 根节点 if (root == -1) return; // 如果没有元素,则树为空 // 左子树 int leftEnd = get_leftmost(in); int preStart = in[leftEnd]; // 左子树的前序遍历起始位置 buildPreOrder(post + 1, in + leftEnd + 1, size - (leftEnd + 1)); // 左子树的后序遍历从第一个非根节点开始 // 右子树 int rightStart = leftEnd + 1; buildPreOrder(post + size - rightStart, in + size, rightStart); // 右子树的后序遍历是从当前根节点之后开始 // 结果合并 printf("%d ", in[preStart]); // 输出根节点 for (int i = preStart + 1; i < size; ++i) { printf("%d ", in[i]); } } // 辅助函数找到后序遍历最后一个元素的对应中序位置 int get_last_in_post(int post[], int size) { // ... 实现逻辑,这里省略 } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值