算法设计与分析——树

分类目录:《算法设计与分析》总目录

本文中,我们专门讨论用链式数据结构表示有根树的问题。我们将首先讨论二叉树,然后给出针对结点的孩子数任意的有根树的表示方法。

树的结点用对象表示。与链表类似,假设每个结点都含有一个关键字 k e y key key。其余我们感兴趣的属性包括指向其他结点的指针,它们随树的种类不同会有所变化。

二叉树

下图展示了在二叉树 T T T中如何利用属性 p p p l e f t left left r i g h t right right存放指向父结点、左孩子和右孩子的指针。如果 x . p = N o n e x.p=None x.p=None,则 x x x是根结点。如果结点 x x x没有左孩子,则 x . l e f t = N o n e x.left=None x.left=None,右孩子的情况与此类似。属性 T . r o o t T.root T.root指向整棵树T的根结点。如果 T . r o o t = N o n e T.root=None T.root=None,则该树为空。
二叉树

分支无限制的有根树

二叉树的表示方法可以推广到每个结点的孩子数至多为常数 k k k的任意类型的树:只需要将 l e f t left left r i g h t right right属性用 c h i l d 1 , c h i l d 2 , ⋯   , c h i l d n child_1, child_2, \cdots, child_n child1,child2,,childn代替。当孩子的结点数无限制时,这种方法就失效了,因为我们不知道应当预先分配多少个属性。此外,即使孩子数 k k k限制在一个大的常数以内,但若多数结点只有少量的孩子,则会浪费大量存储空间。

所幸的是,有一个巧妙的方法可以用来表示孩子数任意的树。该方法的优势在于,对任意 n n n个结点的有根树,只需要 O ( n ) O(n) O(n)的存储空间。这种左孩子右兄弟表示法。如下图所示,和前述方法类似,每个结点都包含一个父结点指针 p p p,且 T . r o o t T.root T.root指向树 T T T的根结点。然而,每个结点中不是包含指向每个孩子的指针,而是只有两个指针:

  1. x . l e f t c h i l d x. leftchild x.leftchild指向结点 x x x最左边的孩子结点。
  2. x . r i g h t s i b l i n g x. rightsibling x.rightsibling指向 x x x右侧相邻的兄弟结点

如果结点 x x x没有孩子结点,则 x . l e f t c h i l d = N o n e x.leftchild=None x.leftchild=None;如果结点 x x x是其父结点的最右孩子,则 x . r i g h t s i b l i n g = N o n e x. rightsibling=None x.rightsibling=None
分支无限制的有根树

树的其他表示方法

我们有时也用其他方法表示有根树。例如我们对一棵完全二叉树可以使用堆来表示,堆用一个单数组加上堆的最末结点的下标表示。有的树只需向根结点方向遍历,因此只需提供父结点的指针,而没有指向孩子结点的指针。还有许多其他的表示方法。哪种方法最优取决于具体应用。

  • 4
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

von Neumann

您的赞赏是我创作最大的动力~

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值