树的存储方式:顺序存储结构,链式存储结构

双亲表示法:

#define MaxSize 100//树中最多结点数
typedef struct {//树的结点定义
    ElemType data;//数据元素
    int parent;//双亲位置域
}PTNode;
typedef struct {//树的类型定义
    PTNode nodes[MaxSize];//双亲表示
    int n;//结点数
}PTree;

该存储结构利用了每个结点(根结点除外)只有唯一双亲的性质,可以很快得到每个结点的双亲结点,但求结点的孩子时需要遍历整个结构。

孩子表示法:

typedef struct CTNode {//孩子链表结点的定义
    int child;//该孩子结点在线性表中的位置
    struct CTNode *next;//指向下一个孩子结点的指针
};
typedef struct {//顺序表结点的结构定义
    ElemType data;//结点的信息
    struct CTNode* firstchild;//指向孩子链表的头指针
}CTBox;
typedef struct {//树的定义
    CTBox nodes[MaxSize];//顺序表
    int root;//该树的根结点在线性表中的位置
    int num;//该树的结点个数
}CTree;

寻找子女非常简单,寻找双亲的操作需要遍历n个结点中孩子链表指针域所指向的n个孩子链表

孩子兄弟表示法: 

typedef struct CSNode {
    ElemType data;//数据域
    struct CSNode* firstchild, *nextchild;//第一个孩子和右兄弟指针
}CSNode,*CSTree;

树、二叉树、森林的转换

树转化为二叉树:(1)在兄弟结点之间加一条线;(2)每个结点只保留它与第一个孩子结点的连线(3)以树根为轴心,顺时针旋转45。(左孩子右兄弟)

森林转化为二叉树:(1)森林中的每棵树转化为二叉树(2)每棵树的根之间加一条连线(3)以第一棵树的根为轴心顺时针旋转45

二叉树转化为森林:(1)若二叉树非空,断开根结点的右链(2)二叉树根的右子树又可以视为一个由除第一棵树外的森林转化的二叉树,应用同样的方法,直到最后只剩一棵没有右子树的二叉树为止,最后将每棵二叉树依次转化为树,就得到了原始森林。二叉树转化为树或森林是唯一的。

1.以孩子兄弟表示法存储的森林的叶子结点数:当森林(树)以孩子兄弟表示法存储时,若结点没有孩子(fch==null),则它必是叶子,总的叶子结点个数是孩子子树(fch)上的叶子数和兄弟子树(nsib)上的叶结点个数之和。

typedef struct node{
    ElemType data;//数据域
    struct node* fch, * nsib;//孩子与兄弟域
}*Tree;
int leaves(Tree t) {
    if (t == NULL)
        return 0;//树空返回0
    if (t->fch == NULL)//若结点无孩子,则该结点必是叶子
        return 1 + leaves(t->nsib);//返回叶子结点和其兄弟子树中的叶子结点数
    else//孩子子树和兄弟子树中叶子数之和
        return leaves(t->fch) + leaves(t->nsib);
}

2.以孩子兄弟链表为存储结构,设计递归算法求树的深度

 当森林(树)以孩子兄弟表示法存储时,若结点没有孩子(fch==null),则它必是叶子,总的叶子结点个数是孩子子树上的叶子数和兄弟子树上的叶结点个数之和。

typedef struct node{
    ElemType data;//数据域
    struct node* fch, * nsib;//孩子与兄弟域
}*Tree;
int leaves(Tree t) {
    if (t == NULL)
        return 0;//树空返回0
    if (t->fch == NULL)//若结点无孩子,则该结点必是叶子
        return 1 + leaves(t->nsib);//返回叶子结点和其兄弟子树中的叶子结点数
    else//孩子子树和兄弟子树中叶子数之和
        return leaves(t->fch) + leaves(t->nsib);
}

3.孩子兄弟链表为存储结构,设计递归算法求树的深度

采用递归算法,若树为空,高度为零,否则,高度为第一子女树高度加1和兄弟子树高度的大者,其递归算法使用队列,逐层遍历树,获得树的高度。

int Height(CSTree bt) {
    //递归求以孩子链表表示树的深度
    int hc, hs;
    if (bt = NULL)
        return 0;
    else//否则,高度取子女高度+1和兄弟子树高度的大者
    {
        hc = Height(bt->firstchild);//第一子女树高
        hs = Height(bt->nextchild);//兄弟树高
        if (hc + 1 > hs)
            return hc + 1;
        else
            return hs;
    }
}
int height(CSTree bt) {
    //递归求以孩子链表表示树的深度
    int hc, hs;
    if (bt = NULL)
        return 0;
    else//否则,高度取子女高度+1和兄弟子树高度的大者
    {
        hc = height(bt->firstchild);//第一子女树高
        hs = height(bt->nextsibling);//兄弟树高
        if (hc + 1 > hs)
            return hc + 1;
        else
            return hs;
    }
}

 

posted @ 2021-10-13 22:19  #Lorraine#  阅读(87)  评论(0)    收藏  举报