数据结构理论基础——树

      版权声明:本文为博主原创文章,未经博主允许不得转载。          https://blog.csdn.net/u011815404/article/details/80656655        </div>
        <link rel="stylesheet" href="https://csdnimg.cn/release/phoenix/template/css/ck_htmledit_views-f57960eb32.css">
                          <link rel="stylesheet" href="https://csdnimg.cn/release/phoenix/template/css/ck_htmledit_views-f57960eb32.css">
      <div class="htmledit_views" id="content_views">
        <h1><a name="t0"></a>【树的定义】</h1>

树是递归定义的,一颗树是由n(n>0)个元素组成的有限集合,其中:

  1. 每个元素称为结点(node)
  2. 至少存在一个结点,它没有前驱(其余的结点都有唯一的一个前驱结点,每个结点可以有0或多个后继结点),这个结点称为根节点(root)
  3. 除根节点外,其余结点能分成m(m>=0)个互不相交的有限集合T0,T1,T2,……,Tm-1,其中每个子集又是一颗树,这些集合称为这棵树的子树

【树的基本概念】

  1. 树是一种非线性的有序数据结构,能很好地描述有分支和层次特性的数据集合。
  2. 一个结点的子树个数,称为结点的度(degree),树中各节点的度的最大值称为这棵树的。度为0的结点称为叶结点,度不为0的结点称为分支结点,根以外的分支结点称为内部结点
  3. 在图形表示的树型结构中,对两个用线段(树枝)连接的相关联的结点,称上端结点为下端结点的父节点,称下端结点为上端结点的子结点。对同一个父结点的多个子结点互称兄弟结点,对从根结点到某个子结点所经过的所有结点称为这个子结点的祖先,对以某个结点为根的子树中的任一结点都是该结点的子孙
  4. 定义一棵树的根结点的层次(level)为0,其它结点的层次等于它的父结点层次加1,则一棵树中所有的结点的层次的最大值称为树的深度(depth)
  5. 对于树中任意两个不同的结点,如果从一个结点出发,自上而下沿着树中连着结点的线段能到达另一结点,则称它们之间存在着一条路径。可用路径所经过的结点序列表示路径,其长度等于路径上的结点个数减1。从根节点出发,到树中的其余结点一定存在着一条路径,不同子树上的结点之间不存在路径。
  6. 森林(forest)是m(m>=0)棵互不相交的树的集合。
  7. 树形结构中二叉树是最常用的结构,其分支个数确定,又可以为空,具有良好的递归特性,因此常常将一般树转换为二叉树进行处理。

以下图为例:

    

 

  1. 根节点:1,叶结点有:3、5、6、8、9,分支结点有:1、2、4、7,内部结点有:2、4、7,这棵树的度为:3
  2. 对于根结点1来说,它是2、3、4的父节点,同时2、3、4是结点1的子节点,它们又是兄弟结点。
  3. 对于结点8来说,1、4、7是它的祖先;对于4来说,7、8、9是它的子孙。
  4. 根节点的层次为0,结点2、3、4的层次为1,结点5、6、7的层次为2,结点8、9的层次为3,这棵树的深度为3。
  5. 对于结点1与结点8自己存在的路径,可用1、4、7、8来表示该路径,该路径的长度为3。

【树的存储结构】

1.父亲表示法

使用数组存储,每个结点包括一个数据域和一个指针域(指向其父结点)。

假设树的度为10,树的结点仅存放字符,则这棵树的数据结构定义如下:


 
 
  1. const int m= 10; //树的结点数
  2. struct node
  3. {
  4. char data; //数据域
  5. int parent; //指针域
  6. };
  7. node tree[m];

优缺点:利用了树中除根结点外每个结点都有唯一的父结点这个性质,很容易找到树根,但找孩子时需要遍历整个线性表。

2.孩子表示法

树型单链表结构,每个结点包括一个数据域和一个指针域(指向若干子结点)。

假设树的度为10,树的结点仅存放字符,则这棵树的数据结构定义如下:


 
 
  1. const int m= 10; //树的度
  2. typedef struct node;
  3. typedef node *tree; //声明tree是指向node的指针类型
  4. struct node
  5. {
  6. char data; //数据域
  7. tree child[m]; //指针域,指向若干孩子结点
  8. };
  9. tree t;

缺陷:只能从根(父)结点遍历到子结点,不能从某个子结点返回到它的父结点。

3.父亲孩子表示法

树型双链表结构,每个结点包括一个数据域和二个指针域(一个指向若干子结点,一个指向父结点)。

假设树的度为10,树的结点仅存放字符,则这棵树的数据结构定义如下:


 
 
  1. const int m= 10; //树的度
  2. typedef struct node;
  3. typedef node *tree; //声明tree是指向node的指针类型
  4. struct node
  5. {
  6. char data; //数据域
  7. tree child[m]; //指针域,指向若干孩子结点
  8. tree father; //指针域,指向父亲结点
  9. };
  10. tree t;

4.孩子兄弟表示法

二叉树型表示法,是一种双链表结构,但每个结点包括一个数据域和二个指针域(一个指向该结点的第一个孩子结点,一个指向该结点的下一个兄弟结点)。


 
 
  1. typedef struct node;
  2. typedef node *tree; //声明tree是指向node的指针类型  
  3. struct node
  4. {
  5. char data; //数据域
  6. tree firstchild, next; //指针域,分别指向第一个孩子结点和下一个兄弟结点
  7. };
  8. tree t;

【树的遍历】

1.先序(根)遍历:先访问根结点,再从左到右按照先序思想遍历各棵子树。(实质上是深度优先遍历)

2.后序(根)遍历:先从左到右遍历各棵子树,再访问根结点。(实质上是深度优先遍历)

3.层次遍历:按层次从小到大逐个访问,同一层次按照从左到右的次序。(实质上是广度优先遍历)

4.叶结点遍历:但将所有数据信息存放在叶结点中,其余结点都是用来表示数据之间的某种分支或层次关系时,从左到右顺序访问叶结点。

以下图为例

先序遍历的结果:125634789

后序遍历的结果:562389741

层次遍历的结果:123456789

叶结点的结果:56389

【例题】

1.树的存储结构:点击这里

2.树的遍历:点击这里

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值