数据结构(9)——树

来源:互联网 发布:python笔试选择题 编辑:程序博客网 时间:2024/04/29 14:31
树的定义:
树是n个结点的有限集。n=0时称为空树。在任意一棵非空树中:
1.有且仅有一个特定的称为根结点

2.n > 1时,其余结点可分为m个互不相交的有限集T1、T2、......Tm,其中每个集合本身有时一棵树,并且称为根的子树。如下图:


子树T1,T2是上面的子树


关于树的定义要注意以下两点:
1.n>0时根结点是唯一的。
2.m>0时,子树的个数没有限制,但它们一定是互不相交的


结点拥有的子树称为结点的度。度为0的结点称为叶结点或者终端结点;度不为0的结点称为非终端结点或分支结点。除根结点外,分支结点也称为内部结点。树的度是树内各结点的度的最大值。

结点的子树的根称为该结点的孩子,相应的,该结点称为孩子的双亲。同一个双亲的孩子之间互称兄弟。结点的祖先是从根到该结点所经分支上的所有结点。

以某结点为根的子树中的任一结点都称为该结点的子孙。


树的其他相关概念:
结点的层次从根开始定义起,根为第一层,根的孩子为第二层。树中结点的最大层次称为树的深度或高度。上面示意图树的深度是4。

如果将树中结点的各子树看成从左至右是有次序的,不能互换的,则称为该树是有序树,否则称为无序树。
森林是m棵互不相交的树的集合。


线性结构与树结构的不同:

线性结构:
第一个数据元素没有前驱,最后一个数据元素没有后继,中间元素一个前驱一个后继
树结构:
根结点无双亲,唯一;叶结点无孩子,可以多个;中间结点:一个双亲多个孩子


树的存储结构:
1.双亲表示法:
在每个结点中,设一个指示器指示其双亲结点到链表中的位置。如下图:


data是数据域,parent是指针域。

[cpp] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. <span style="font-size:18px;">/*结点定义*/  
  2. #define MAX_TREE_SIZE 100  
  3. typedef struct PTNode  
  4. {  
  5.     int data;   //结点数据,类型根据实际情况而定  
  6.     int parent;  //双亲位置  
  7. }PTNode;  
  8. typedef struct    //树结构  
  9. {  
  10.     PTNode nodes[MAX_TREE_SIZE];   //结点数组  
  11.     int r,n;    //根的位置和结点数  
  12. }PTree;</span>  

下标dataparent0A-11B02C03D14E25F26G37H38I39J4当parent为-1时,表示找到了树的根结点


2.孩子表示法:

每个结点有多个指针域,其中每个指针指向一棵子树的根结点,这种方法叫做多重链表表示法。有两种方案来解决孩子个数不同的问题。


方案一:一种是指针域的个数等于树的度
显然这种方法浪费空间


方案二:一种是指针域的个数等于树的度,专门取一个位置来存储结点指针域的个数

这种方法克服了浪费空间的缺点,空间利用率提高了,但是在时间上的损耗变多了。


以上两种方法都有一定的缺点,而孩子表示法则没有上述两种方法的缺点。孩子表示法是指把每个结点的孩子结点排列起来,以单链表作存储结构,则n个结点有n个孩子链表,如果是叶子结点则此单链表为空。然后n个头指针又组成一个线性表,采用顺序存储结构,存放进一个一维数组中。如下图:


孩子法的结构定义代码:

[cpp] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. <span style="font-size:18px;">#define MAX_TREE_SIZE 100  
  2. typedef struct CTNode  
  3. {  
  4.     int child;  
  5.     struct CTNode *next;  
  6. }ChildPtr;  
  7. int struct  //表头结构  
  8. {  
  9.     int data;  
  10.     ChildPtr firstchild;  
  11. }CTBox;  
  12. typedef struct  
  13. {  
  14.     CTBox nodes[MAX_TREE_SIZE];  
  15.     int r,n;  
  16. }CTree;</span>  

3.孩子兄弟表示法:

任意一棵树,它的结点的第一个孩子如果存在唯一的,它的有兄弟如果存在也是唯一的。因此我们设置两个指针,分别指向该结点的 第一个孩子和此结点的右兄弟。结点结构如下表:

datafirstchildrightsib结构定义代码如下:
[cpp] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. typedef struct CSNode  
  2. {  
  3.     int data;  
  4.     struct CSNode 8firstchild,*rightsib;  
  5. }CSNode,*CSTree;  
示意图如下:


0 0
原创粉丝点击