-
树的基本术语
- 结点: 结点不仅包含数据元素,而且包含指向子树的分支。
- 结点的度: 结点拥有的子树的个数或者分支的个数。
- 树的度: 树中各结点度的最大值。
- 叶子结点: 又叫终端结点,指度为0的结点。
- 非终端结点: 又叫分支结点,指度不为0的点。
- 子结点: 指结点的子树的根。
- 双亲结点: 与孩子结点的定义对应。
- 兄弟结点: 同一个双亲的孩子结点之间互为兄弟结点。
- 祖先、子孙: 从根到某结点的路径上的结点都是它的祖先,而以某结点为根的子树中的所有节点都是它的子孙。
- 树的高度(深度): 树中结点的最大层次
- 结点的深度和高度: 结点的深度从根节点算起,根节点的深度为1;而结点的高度是从最底层的叶子结点算起的,叶子结点高度为1.
- 有序树: 树中结点的子树从左到右是有次序的,不能交换的,这样的树叫做有序树。
- 无序树: 树中结点的子树是无序的,可以任意交换。
- 丰满树: 即理想平衡树,要求除最底层外其他层都是满的。
- 森林: 若干棵不相交的树的集合。
好了,概念说完了,接下来就是树这种数据结构是在内存中怎么存储的。存储结构无非两种:顺序存储,比如用数组实现的顺序表;链式存储,如链表。
说到这插一个题外话,也是刚刚查资料的时候意识到的一个问题,什么是数据结构?
百度百科上有这么一句话:
数据结构具体指同一类数据元素中,各元素之间的相互关系,包括三个组成成分,数据的逻辑结构,数据的存储结构和数据运算结构。
也就是说数据结构包括了同一类数据之间的逻辑关系、物理存储以及运算结构。而我们讨论的线性表(包括顺序表、链表、栈和队列)、树、图等数据结构指的是数据之间的逻辑结构:一个元素只有一个前驱和一个后继(线性表),一个元素只一个前驱但可以有多个后继(树),一个元素可以有多个前驱多个后继(图)。而这些逻辑关系在计算机中的物理存储方式就是其物理结构了。下边是借来的对顺序表、线性表和数组的区别的总结:
1) 数组就是相同数据类型的元素按一定顺序排列的集合。
一句话:就是物理上存储在一组联系的地址上。也称为数据结构中的物理结构。
2)线性表中数据元素之间的关系是一对一的关系,即除了第一个和最后一个数据元素之外,其它数据元素都是首尾相接的。
一句话:线性表是数据结构中的逻辑结构。可以存储在数组上,也可以存储在链表上。
3)线性表的结点按逻辑次序依次存放在一组地址连续的存储单元里的方法。用顺序存储方法存储的线性表简称为顺序表。
一句话:用数组来存储的线性表就是顺序表。
总结:你被这几个概念混淆,是因为你没搞懂数据结构里的逻辑结构和物理存储结构。回到正题
-
树的存储结构
树有三种表示方法:双亲表示法、孩子表示法以及孩子兄弟表示法。
其中双亲表示法是可以通过顺序存储实现的,
假设使用一组连续的空间来存储树的结点,同时在每个结点中存储它的双亲在数组中的位置
。剩下的两种表示法都要用到链式存储了。- 双亲表示法
/*树的双亲表示法结点结构定义 */ #define MAXSIZE 100 typedef int ElemType; //树结点的数据类型,暂定为整形 typedef struct PTNode //结点结构 { ElemType data; //结点数据 int parent; //双亲位置 }PTNode; typedef struct { PTNode nodes[MAXSIZE]; //结点数组 int r,n; //根的位置和结点数 }PTree;
- 孩子表示法
/*树的孩子表示法结点结构定义 */ #define MAXSIZE 100 typedef int ElemType; //树结点的数据类型,暂定为整形 typedef struct CTNode //孩子结点 { int child; struct CTNode *next; }*ChildPtr; typedef struct //表头结构 { ElemType data; ChildPtr firstchild; }CTBox; typedef struct //树结构 { CTBox nodes[MAXSIZE]; //结点数组 int r,n; //根结点的位置和结点数 }CTree;
- 孩子兄弟表示法
/*树的孩子兄弟表示法结构定义 */ typedef struct CSNode { ElemType data; struct CSNode *firstchild, *rightsib; }CSNode, *CSTree;
以上,参考这位大神的数据结构之树的三种存储结构 。