本文深入探讨了树的基本概念,包括结点、度、层次和深度等,详细介绍了树的多种存储结构,如顺序存储、孩子表示法、孩子兄弟表示法及二叉链表。同时,对二叉树的定义、特性、特殊类型及其存储结构进行了全面讲解,最后阐述了二叉树的四种遍历方法:先序、中序、后序和层序遍历。
摘要由CSDN通过智能技术生成

一、基本概念

1、结点:数据元素+若干指向子树的分支

2、结点的度:分支的个数

3、树的度:树中所有结点的度的最大值

4、叶子结点:度为零的结点

5、孩子结点:一个结点的直接后继

6、双亲结点:一个结点的直接前驱

7、兄弟结点:同一双亲结点的孩子结点之间互称

8、结点的层次:根结点的层次为1,第i层的结点的 子树的根结点的层次为i+1

9、树的深度:树中结点的层次的最大值

二、树的存储结构

1、顺序存储——双亲表示法

原理:除了根节点外,其余每个节点,不一定有孩子,但一定有且仅有一个双亲。

data(数据域,存储结点的数据信息)parent(指针域,存储双亲的下标)
#define MAX_TREE_SIZE 100
typedef int TElemType;
typedef struct PTnode /*结点的结构*/
{
    TElemType data;  //结点的数据域名
    int parent;      //结点的指针域——双亲的位置
}
typedef struct
{    
    PTnode nodes[MAX_TREE_SIZE]; //结点数组
    int r,n;   //根的位置和节点数
}PTree;

约定根节点的指针域为-1

2、孩子表示法

原理:每个结点下面很有可能有多个子树,用一个指针域指向一个子树,那么结构中就需要多个指针域。指针域的个数就是树的度。

          树的度:树各个节点度的最大值

data(存储一个结点中的数据域)指针域1指针域2指针域3

 

优缺点: 如果树中各个节点的度相差很大,那么将会十分浪费空间

               如果树中各个节点的度相差很小,充分利用了空间。

 

改进:让每个节点指针域的个数等于该节点的度数。

datadegree(存储该节点的度数)指针域1指针域2指针域3

优缺点: 空间利用率提高

                由于各个节点的度有差异,运算困难。

 

改进

  原理:n个节点存储于n维数组中

            每个节点的孩子结点用单链表排列起来

child(存储某结点在表头数组中的下标)next(指向下一个孩子结点的指针)
data(某结点的数据信息)firstchild(头指针域,存储孩子链表的头指针)

#define MAX_TREE_SIZE 100
typedef struct CTNode   /*孩子结点的数据结构*/
{
    int child; //该孩子结点的下标
    struct CTNode *next; //指向下一个孩子结点的指针
}*ChildPtr;


typedef struct /*表头结构*/
{
    TElemType data; //各个节点的数据
    ChildPtr firstchild; //指向第一个孩子结点的指针
}CTBox;

typedef struct /*树结构*/
{
    CTBox nodes[MAX_TREE_SIZE];/*节点数组*/
    int r,n;   
}CTree;

实际问题:  遍历整个树      查找某个结点的某个孩子    找到某个结点的兄弟结点 

3、孩子兄弟表示法——二叉树

特殊:每个节点有且仅有一个左孩子和右孩子

data(数据域)leftchildrightchild

 

typedef struct CSNode
{
    TElemType data;
    struct CSNode *firstchild,*rightsib;
}CSNode , *CSTree;

三、二叉树

1、定义:n个结点的有限集合

                可以为空集(空二叉树)

                由一个根结点和两颗互不相交的、分别称为根结点的左子树和右子树的二叉树组成。

2、特点:每个节点最多有两颗子树,每个结点度<=2

                 区分左右子树

                 问题:三个节点的二叉树有几种形态?

3、特殊二叉树

      A:斜树

      B:满二叉树 :所有的分支结点都存在左右子树,并且所有的叶子节点都在同一层。

      C:完全二叉树:对一棵具有n个结点的二叉树按层序编号,如果编号为i(1<=i<=n)的结点与同样深度的满二叉树编号为i的结点位置完全相同,则这就是完全二叉树

         在满二叉树的基础上,我在最底层从右往左删去若干节点,得到的都是完全二叉树。如果编号出现空档,那就说明不是完全二叉树

         所以说,满二叉树一定是完全二叉树,但是完全二叉树不一定是满二叉树。

四、二叉树的存储结构

1、顺序存储结构

     A:完全二叉树的顺序存储——理想状态

 

下标12345678910
数据ABCDEFGHI

J

     B:普通二叉树——空间利用率低

下标1234567
数据ABC

2、二叉链表

节点结构

Lchild(指向左孩子的指针)data(结点数据)Rchild(指向右孩子的指针)

 

typedef struct BiTNode
{
    TElemType data;
    struct BiTNode *Lchild,*Rchild;
}BiTNode , *BiTree;

五、二叉树的遍历

1、先序遍历——根左右

     若二叉树为空树,则空操作;

    否则(1)访问根结点

           (2)先序遍历左子树

           (3)先序遍历右子树。

           访问:根据实际的需要来确定做什么。比如对每个结点进行计算,输出打印。

void  PreOrder(BiTree root) /* root是指向根结点的指针 */
{	
        if (root!=NULL)
        {
             Visit(root ->data);   /*访问根结点*/
	  PreOrder(root ->LChild);    /*先序遍历左子树*/
	  PreOrder(root ->RChild);    /*先序遍历右子树*/
	}
 } 

2、中序遍历(左 根 右)

若二叉树为空树,则空操作;

否则 (1)中序遍历左子树;

         (2)访问根结点;

          (3)中序遍历右子树。

void  InOrder(BiTree root) 
{	
        if (root!=NULL)
        {
	  InOrder(root ->LChild);  /*中序遍历左子树*/
             Visit(root ->data);  /*访问根结点*/
	  InOrder(root ->RChild);  /*中序遍历右子树*/
	}
 } 

3、后序遍历(左 右 根)

      若二叉树为空树,则空操作;

      否则    (1)后序遍历左子树

                  (2)后序遍历右子树 

                  (3)访问根结点。

void  PostOrder(BiTree root) 
{	
        if (root!=NULL)
        {
	  PostOrder(root ->LChild);  /*后序遍历左子树*/
	  PostOrder(root ->RChild);  /*后序遍历右子树*/
             Visit(root ->data);  /*访问根结点*/
          }
 } 

4、层序遍历

      若二叉树为空树,则空操作;

      否则从树的根结点开始访问,从上而下逐层遍历,在同一层中,按从左到右的顺序对结点逐个访问。

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值