树和森林存储


树的存储方式
想象一下,树就像一个家庭,每个家庭成员(结点)都有一个爸爸(双亲),但是可能有多个孩子。在计算机里,我们有几种不同的方法来存储这样的家庭结构:
双亲表示法:就像每个孩子都有一个名牌,上面写着他们爸爸的名字和位置。这样,我们很快就能找到孩子的爸爸,但是要找孩子的兄弟姐妹,就得一个个问过去。
孩子表示法:每个孩子都有一个名单,上面写着他们所有的兄弟姐妹。这样,我们很容易就知道谁是兄弟姐妹,但是要找到孩子的爸爸,就得看遍所有名单。
孩子兄弟表示法:这是一种更灵活的方法,每个孩子都知道自己的第一个兄弟姐妹和下一个兄弟姐妹是谁。这种方法方便我们快速找到孩子的兄弟姐妹,但是要找到爸爸,就得费点劲。
树和森林的变形
有时候,我们需要把一棵树变成另一种形状,就像把一张纸折成不同的形状一样。我们可以把一棵树变成一棵二叉树,也可以把一片森林(很多棵树)变成一棵二叉树。反过来,我们也可以把一棵二叉树变回一棵树或者一片森林。
树和森林的访问方法
访问树和森林就像参观一个景点,有不同的路线可以走:
先根遍历:就像先去景点的大门,然后再一个个参观里面的小景点。
后根遍历:就像先逛完所有的小景点,最后再回到大门。
先序遍历森林:就像先去森林里的第一棵树,然后是它的小树,再去下一棵树。
中序遍历森林:就像先去森林里的第一棵树的小树,然后是第一棵树,再去下一棵树。
树在并查集中的应用
并查集就像一个大型的家族聚会,我们需要知道谁和谁是一家人。我们可以用树来表示这些家族关系:
Union操作:就是把两个家族合并成一个大家族。
Find操作:就是找出一个人属于哪个家族。
Initial操作:就是最开始的时候,每个人都是自己的家族。
我们用树来存储这些家族关系,每个家族的族长(根结点)告诉我们这个家族的成员都有谁。
 

知识点链接
树的存储结构
双亲表示法:
概念:使用数组存储结点,每个结点增加一个指针指向其双亲结点在数组中的位置。根结点的下标为0,其双亲指针为-1。
优点:快速访问每个结点的双亲。
缺点:需要遍历整个结构来查找结点的孩子。
孩子表示法:
概念:使用单链表将每个结点的孩子结点链接起来。
优点:直接访问孩子结点。
缺点:需要遍历所有孩子链表来查找双亲。
孩子兄弟表示法:
概念:使用二叉链表存储,每个结点包含指向第一个孩子和下一个兄弟的指针。
优点:灵活,易于实现树到二叉树的转换。
缺点:查找双亲结点较为复杂,但可以通过增加parent域简化。
树、森林与二叉树的转换
树转换为二叉树:将树的每个结点的左指针指向第一个孩子,右指针指向右兄弟。通过特定的画法转换,包括在兄弟结点间加连线,保留与第一个孩子的连线,其他连线抹去,并进行45度旋转。
森林转换为二叉树:先转换每棵树为二叉树,然后在树根之间加连线,进行45度旋转。
二叉树转换为森林:断开根的右链,将右子树视为森林转换后的二叉树,重复此过程直到只剩一棵没有右子树的二叉树,再转换为树。
树和森林的遍历
先根遍历:先访问根结点,再遍历子树,与二叉树的先序遍历相同。
后根遍历:先遍历子树,再访问根结点,与二叉树的中序遍历相同。
先序遍历森林:先访问第一棵树的根,再遍历其子树森林,然后遍历剩余森林。
中序遍历森林:先遍历第一棵树的子树森林,访问根结点,再遍历剩余森林。
树的应用——并查集
支持操作:
 Union(S, Root1, Root2) :合并两个不相交的子集合。
 Find(S, x) :查找元素x所在的子集合。
 Initial(S) :初始化集合,每个元素为一个单元素集合。
具体实现:使用双亲表示法存储并查集,每个子集合为一棵树,所有树构成森林。
 

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值