树-基本知识

一.定义:

1. 树是 n(n>=0) 个节点的有限集。n=0 时成为空树。在任意一棵非空树中:有且只有一个特定的成为根节点。其余m(m>0)个互不相交的有限集 T1,T2……Tm,其中每一个集合本身又是一棵树,并且成为根的子树。并且子树是不相交的。

2. 度:节点拥有的子树的个数,度为 0 的节点为叶节点,度不为 0 的节点成为非终端节点或分支节点 。

3. 树的度是树内各节点度的最大值。

4. 节点的子树的根称为该节点的孩子,该节点称为孩子的双亲

5. 同一个双亲的孩子之间互称为兄弟。
节点的祖先是从根到该节点所经分支上的所有节点

6 节点的层次从根开始定起,根为第一层,其双亲在同一层的节点互为堂兄弟。

7. 树中结点的最大层次称为树的深度。

8. 有序树:树中节点的各子树看成从左到右是有次序的,不能互换

9. 森林:m(m>=0) 棵互不相交的树的集合。

二.树的存储结构
1. 双亲表示法:以一组连续空间存储数的节点,同时每个节点中,附设一个指示器指示其双亲节点在数组中的位置。

//结构定义
typedef int TElemType;

typedef Struct PTNode{

        TElemType data;  // 存储的数据

        int patent;      // 存储的双亲的位置

} PTNode;

typedef struct{         // 树结构

    PTNode nodes[MAX_TREE_SIZE];

    int r,n;       
         // 根的位置和节点数

}

找到双亲节点的时间复杂度:O(1)
找到节点的孩子的时间复杂度:O(n)

改进一:增加长子域(该节点的最左边孩子的域)

改进二:增加右兄弟域

2.孩子表示法:
每个节点有多个指针域,其中每个指针指向一棵子树的根节点,称为多重链表表示法。


方案一:
根据树的度来确定每个节点指针域的个数。如图中树的度为 4 ,则每个节点都有 4 个孩子域

缺点:当树中各节点的度相差很大时,浪费空间,因为很多节点的指针域是空的。

方案二:
每个节点指针域的个数等于该节点的度,专门取一个节点的位置来存储节点指针域的个数。如根结点有两个孩子,则有两个孩子领域,一个数字域。

缺点:克服了空间上的浪费,但由于每个节点的链表是不相同的结构,还要维护 节点的度的数值,在时间会有损耗。

引入即减少空指针的浪费又能使节点的结构相同

孩子表示法:把每个节点的孩子结点排列起来,用单链表作为存储结构,n 个节点 n 个链表,如果为叶子节点,该单链表为空。再将 n 个头指针组成一个线性表,采用顺序存储结构,存放到一维数组中。


 //树的孩子节点表示法结构定义
 #define MAX_TREE_SIZE 100

 typedef struct CTNode //孩子节点
{
    int child ;

    struct CTNode *next;

}*ChildPtr;

typedef struct{ //表头结构

    TlemType data;

    ChildPtr firstChild;

}CTBox;

typedef struct{ //树的结构

    CTBox nodes[MAX_TREE_SIZE];

    int r,n;//根的位置和节点数。

}Ctree;
问题:对于查找每个节点的孩子和其孩子节点的兄弟,只需查找这个节点的孩子的单链表就可以了,但想要知道每个节点的双亲是谁需要遍历整棵树。 进而有了:孩子双亲表示法。


 //树的孩子节点表示法结构定义
 #define MAX_TREE_SIZE 100

 typedef struct CTNode //孩子节点
{
    int child ;

    struct CTNode *next;

}*ChildPtr;

typedef struct{ //表头结构

    int parentIndex;

    TlemType data;

    ChildPtr firstChild;

}CTBox;

typedef struct{ //树的结构

    CTBox nodes[MAX_TREE_SIZE];

    int r,n;//根的位置和节点数。

}Ctree;

孩子兄弟表示法:任意一棵树,它的节点的第一个孩子如果存在就是唯一的,它的右兄弟也是唯一的。因此设置两个指针,分别指向该节点的第一个孩子和此节点的右兄弟。
typedef struct CSNode{

    TElemType data;

     struct CSNode * first child, *rightsib;

}CSNode, *CSTree;

好处:查找某个节点的孩子带来了方便,并把一个复杂的树变成了一棵二叉树。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值