• 《大话数据结构》笔记(6-1)--树:树


    代码实现:
     
     

    第六章    树

    树的定义
     树的结点包含一个数据元素及若干指向其子树的分支。
    结点拥有的子树数称为结点的度(degree)
    度为0的结点称为叶结点(Leaf)或终端结点;度不为0的结点称为非终端结点或分支结点。
    除根结点之外,分支结点也称为内部结点。
    树的度是树内各结点的度的最大值。
    结点的子树的根称为该节点的孩子(Child),相应的,该结点称为孩子的Parent
    同一个Parent的孩子之间互称兄弟(Sibling)。
    结点的祖先是从根到该结点所经分支上的所有结点。以某结点为根的子树中的任一结点都称为该结点的子孙。
     
    结点的层次(Level)从根开始定义起。其Parent在同一层的结点互为堂兄弟。
    树中结点的最大层数称为树的深度(Depth)或高度
    如果将树中结点的各子树看成从左至右是有次序的,不能互换的,则称改树为有序树,否则称为无序树。
     
    森林(Forest)是m(m>=0)棵互不相交的树的集合。对树中每个结点而言,其子树的集合即为森林。
    树的抽象数据类型
     
    树的存储结构
    双亲表示法
    假设以一组连续空间存储树的结点,同时在每个结点中,附设一个指示器指示其双亲结点到链表中的位置。
    结点结构定义代码:
     
     约定根结点的位置域设置为-1
     根据结点的parent指针很容易找到它的双亲结点,所用的时间复杂度为O(1);如果想要知道结点的孩子是什么,则需要遍历整个结构才行。
     
    改进:
    可以把此结构扩展为双亲域、长子域、右兄弟域等。
    存储结构的设计是一个非常灵活的过程,一个存储结构设计的是否合理,取决于基于该存储结构的运算是否适合、是否方便、时间复杂度好不好等。
     
     
    孩子表示法
    每个结点有多个指针域,其中每个指针指向一棵子树的根结点,我们把这个方法叫做多重链表表示法。
     
    由于树的每个结点的度不相同,所以有两种方案来解决。
    方案一
    指针域的个数等于树的度。
     
    这种方法对于树中各节点的度相差很大时,显然是浪费空间的。不过如果树的各结点度相差很小时,就意味着开辟的空间被充分利用了,这时存储结构的缺点反而变成了优点。
     
    方案二
    每个结点指针域的个数等于该结点的度。
     
    这种方法克服了浪费空间的缺点,对空间利用率是提高了,但是由于各个结点的链表是不相同的结构,加上要维护结点的度的数值,在运算上就会带来时间上的损耗。
     
    有没有什么方法,既可以减少空指针的浪费又能使结点各结构相同?
    孩子表示法
    把每个结点的孩子结点排列起来,以单链表作为存储结构,则n个结点有n个孩子链表,如果是叶子结点则此单链表为空。然后n个头指针又组成一个线性表,采用顺序存储结构,存放进一个一维数组中。
    为此,需要设计两种结点结构,一个是孩子链表的孩子结点另一个是表头数组的表头结点
     
    孩子表示法的结构定义代码:
     这里存在的问题是需要遍历整棵树才知道某个结点的双亲。
     
    改进
    双亲孩子表示法
     
    孩子兄弟表示法
    任意一棵树,它的结点的第一个孩子如果存在就是唯一的,它的右兄弟如果存在也是唯一的。因此,我们设置两个指针,分别指向该结点的第一个孩子和此结点的有兄弟。
     
     所有有必要知道父结点,完全可以再增加一个parent指针域来解决快速查找双亲的问题。
     
    其实这个表示法的最大好处是它把一棵复杂的树变成了一棵二叉树。
     
  • 相关阅读:
    人月神话阅读笔记
    12周总结
    IOS成长之路-用NSXMLParser实现XML解析
    沟通能力的表达
    IOS中UIScrollView的contentSize、contentOffset和contentInset属性
    Block 的使用时机
    drawAdapter
    drawpoly()函数的用法
    @synchronized(self)
    Swift2
  • 原文地址:https://www.cnblogs.com/lyu0709/p/6881510.html
Copyright © 2020-2023  润新知