[C、C++]数据结构:树の存储结构和遍历

一、树の存储结构

1.树の三种表示法

双亲表示法(顺序存储):更像是单亲。

孩子表示法(顺序+链式存储):用一个顺序空间(数组)存储各个结点的数据。

2.树、二叉树、森林の转换

树转二叉树:对每个结点,左孩子还是左孩子,把兄弟结点变成右孩子。

二叉树转树:左孩子还是孩子,右孩子变右兄弟。

森林转二叉树(用二叉链表存储森林):

把互不相见的树依次转化成二叉树,把它们的根节点看成兄弟结点,用右指针连起来。

二叉树转森林(孩子兄弟表示法存储森林):对每个结点来说,左边连的是自己的孩子,右边连的是兄弟(自己父节点的下一个孩子)

二、遍历

总览:

树的先根遍历序列与其对应的二叉树的先序遍历序列相同。

根结点的右孩子变成了左孩子的右孩子。

树的后跟遍历序列和其对应的二叉树的中序遍历序列相同。

这是因为在将树转化为二叉树的过程中,每个节点的右子树都是空的。因此,在进行后根遍历时,会首先遍历所有的子树,然后再访问根节点。这就意味着在二叉树中,我们会首先访问所有的左子节点(也就是原始树中的子树),然后再访问根节点。这正是二叉树中序遍历的定义。

左孩子->右孩子->根——>左孩子->左孩子的兄弟->根==二叉树的中序遍历

左孩子->根->右孩子——>左孩子->根->左孩子的爹的兄弟==树的后根遍历
所以,一棵树的后根遍历序列等于它对应的二叉树的中序遍历序列。这种关系在将森林转化为二叉树时也同样适用。具体来说,森林的第一棵树的子树森林会转换成左子树,剩余的树构成的森林会转换成右子树。因此,森林的先序和中序遍历对应于二叉树的先序和中序遍历。

树的层次(广度优先)遍历:用一个辅助队列实现,让根节点入队,让根节点出队,如果有子结点,所有子结点依次入队,重复该过程。

森林的先序遍历:

方法1:效果等同于依次对各个子树先根遍历

考试手算时,很不推荐钻到两层递归嵌套里,直接对各个子树进行先根遍历即可。

方法2:转化成二叉树再先序遍历。

森林的中序遍历:

方法1:对各个子树进行后跟遍历。

方法2:转化成二叉树进行中序遍历

值得注意的是,森林的中序遍历与二叉树的中序遍历方法的定义不同。在二叉树的中序遍历中,我们按照左-根-右的顺序进行遍历。而在森林的中序遍历中,我们首先中序遍历第一棵树的所有子树,然后访问这棵树的根节点(可以理解为:对于森林来说,根据左孩子右兄弟原则,中序遍历的左-根-右其实就是左孩子-根-右兄弟)。对于这棵树来说,根节点的访问次序其实是整棵树遍历的最后(类似于二叉树的后序),这里经常与二叉树的中序遍历混淆。

此外,有些人可能会对为什么称之为“中序”遍历感到困惑。实际上,这是因为这种遍历等同于将森林转换为二叉树之后,对二叉树进行的中序遍历。因此,尽管在处理每个单独的树时,它更像是后序遍历,但由于它等同于整个森林转换为二叉树后的中序遍历,所以被称为“中序”遍历。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值