链表——树

一、链表
1.链表结构
  链表基本结构是一个data数据区加存储位置的变量。数据域即链表用来存储数据,而还需要存储链表中多个数据域之间的位置关系,可以用指针存储相关位置的地址,也可以用其它方式进行存储。这两部分组合在一起就构成了一个“node”结点,而一个一个的结点连接起来组合在一起,就构成了一个链表。为了方便找到这个链表的位置,需要定义一个单独的变量来存储链表的头一个结点,称这个变量为链表的头指针。当然,这个头指针可以仅用来指向链表的头节点,不过多数情况,为了方便对整个链表进行相关操作,可以把头指针定义为一个单独的结点,方便存储整个链表的相关信息。
2.链表和顺序表区别及优缺点
  链表相对于顺序表的优点体现在空间上的动态分配和对于内空间的利用,在元素的删除和添加上要更加方便。顺序表定义时就要限定分配存储空间,而且如果删除或者增加一个元素进去会很麻烦,尤其增加。链表因为各结点存储空间都是通过new来分配的存储空间,所以在内存利用上有优势,而且删除和添加结点时只要修改相应的指针即可实现相应结点逻辑上的位置关系修改,要方便很多。不过实际运用的话暂时做题其实用处还不大,如果需要不添加的话仅有可能删除部分信息的话完全可以用普通的线性表,然后在每个元素加一个mark变量表示是否删除即可,而题目一般不会在内存空间上卡太多的,所以基本不用担心。
3.链表分类
(1)单链表
  也即是单向链表,包含基本数据域的情况下仅记录下一个(前一个也可以,不过肯定不好用)结点位置的链表,简单易行,不过删改操作速度慢。
(2)双向链表
  同时记录前后结点位置的链表结构,优势在于加快删改操作的速度,不过消耗更多的存储空间(毕竟多了记录地址的指针)。
(3)循环链表
  前两种链表尾结点的next指针的值都是NULL,双向链表的头结点的pre指针值也是NULL。而在双向链表中的为节点的next指针会指向首个存储数据的结点地址,对于双向队列的首个存储信息的结点的pre指针则指向尾结点,如此以实现循环。即前两种链表的相似结构的特例。
4.实现链表的一些小细节
  一般链表的实现还是用结构体较方便。注意链表的结点不能再通过下标的方式访问了,所以需要定义一个或多个指来记录链表位置(就像顺序表操作时循环中定义的i,j,k类似)然后通过指针访问(->)结点信息。因为结点都是new申请的存储空间,最后要记得delete掉。
二、基本树
  单独的链表结构现阶段来说实用还不多,不过升级版的树却很常用。
1.概念(子树和度,父子祖先关系,结点层次,路径)
  一棵树也是由多个结点构成。其中有个结点没有前驱结点,仅存在后续结点(0个及以上),这样的结点称为根节点,而存在多个结点没有后续结点,称为叶子节点。一个结点的后续结点及后续结点后面的结构整体称为这个结点的子树(只有一个后续结点也称为子树),其后续结点称为这个结点的子结点,同样这个结点称为子结点的父结点,同一个父亲结点的孩子结点间互称兄弟结点。父子结点处于不同的层次,子结点的层次为父结点层次+1,根结点层次为0,一棵树最大的层次称为这棵树的深度。一个节点的子树个数称为这个结点的度(0及以上),一棵树所有结点的度中最大的度称为这棵树的度。层次比当前结点低,可以通过父子关系连结起来的所有结点称为这个结点的祖先结点。如果说可以从一个结点沿层次不减的父子关系到达另一个结点(包括这个结点在内的其它所有结点都是另一个结点的祖先),这样就说这两个结点(注意:两个!)间存在一条路径,路径长度即为路径上所有结点个数减一(构成的线段(树枝)数)。多个(0及以上)互不相交的数构成一个森林。
2.结构
  同一般的链表一样,也是由数据域和用于储存位置关系的变量(表示父子关系)构成。不过过构成树的方式有多种。
(1)父亲表示法(数组)
  定义结构体表示结点,每个结点仅存储其父亲结点的地址。记录所有结点,存在多个结点指向相同父亲结点和没有父亲结点(根结点)的情况来构成树。
(2)孩子表示法(树型单链表)
  定义结构体表示结点,其中通过结点数组形式存储该节点所有的孩子结点(或者说记录所有孩子结点的地址),会有多个孩子结点,而不存在孩子结点的某个结点即为叶子结点。这样的树型结构是由一点(根结点)扩散形成,构成树。
(3)父亲孩子表示法(树型双链表)
定义结构体,同时存储孩子结点和记录父亲结点地址,类似双向链表结构,所以在树的结点删改上方便,也是前两种树型结构表示的结合。
(4)孩子兄弟表示法(二叉树)
  定义结构体时记录一个孩子结点,但还要记录另一个(下一个)孩子结点的地址。记录的两个孩子结点为兄弟结点。具体内容后续整理。
3.简单树的遍历
(1)先序(根)遍历
  先访问根结点再访问根结点的每个子树。对于子树的遍历是先低层次再高层次,同层次(兄弟结点)按顺序访问对应子树。方法是递归定义的,所以遍历也用递归进行访问。
(2)后序(根)遍历
  先访问子树再访问根结点(或者所有子树最低层次结点共同的那个父亲结点)。所以遍历顺序是先高层次再低层次,同层次(兄弟结点)也是按顺序访问。从高层次开始但也是循着子树进行的遍历,所以方法也是递归的,用递归访问各节点。
(3)层次遍历
  前两种遍历方法即深搜法。而层次遍历即广搜法。按照层次由低到高访问,当访问到某一结点时,如果这个结点存在子结点就记录下来,当访问完同层次的其他结点(不仅包括其兄弟结点)后再按记录的顺序访问下一层次的各结点。如此,访问子结点的顺序也会和访问对应父亲结点顺序相同。所以访问时应定义一个队列记录待遍历的结点,每遍历一个结点就存入该节点的子结点地址,然后弹出该节点地址,按队列顺序遍历结点。
(4)叶节点遍历
  这种方法特殊,仅适用于特殊的树。这种树形结构仅将数据信息储存到叶子结点中,而其余子结点仅用来表示数据信息间较复杂的关系而不储存数据,所以仅对叶子结点访问即可。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值