数据结构 - 树 - 一般树和森林的基本介绍

树的存储结构

双亲表示法

通过保存树中每个结点的双亲结点的位置,来表示树中结点之间的结构关系。

#define MAX_TREE_SIZE  100
typedef struct PTNode
{
    ElemType data;
    int parent;    // 双亲位置(双亲的下标)
} PTNode;
typedef struct
{
    PTNode nodes[MAX_TREE_SIZE];
    int r, n;      // r为根的位置,n为结点数
} Ptree;

孩子表示法

通过保存树中每个结点的孩子结点的位置,表示树中结点之间的结构关系。

方法一:多重链表

类似于二叉链表,我们可以用多叉链表。具体实现有两种方式:定长结点不定长结点

  • 定长结点:优点是结点结构一致,便于实现树的操作,缺点是浪费一些内存空间。

  • 不定长结点:优点是节省内存空间,缺点是不定长的结点会使一些操作实现变复杂。

方法二:孩子链表

将树中的每个结点的孩子排列起来,看成一个线性表,采用线性链表进行存储。

树的孩子链表的类型定义如下:

typedef struct CTNode  // 孩子结点
{
    int child;
    struct CTNode* next;
} *ChildPtr;
typedef struct
{
    ElemType data;
    ChildPtr firstchild; // 孩子链表头指针
} CTBox;
typedef struct
{
    CTBox nodes[MAX_TREE_SIZE];
    int n, r;   // 结点数和根的位置
} CTree;

孩子兄弟表示法

我们也可以仍用二叉链表作为树的存储结构。

树的孩子兄弟表示法的类型定义如下:

typedef struct CSNode
{
    ElemType data;
    struct CSNode
        * firstchild,  //指向第一个孩子
        * nextsibling; //指向下一个兄弟
} CSNode, * CSTree;

树与二叉树

树与二叉树的转换

二叉树和树都可以用二叉链表存储,我们可以以二叉链表为中介,实现树与二叉树之间的转换。其转换的方法图示如下:

森林与二叉树的转换

森林:树的集合。

将森林中的树的根结点看作兄弟,用树与二叉树的转换方法,进行森林与二叉树的转换。

树的遍历

遍历:按一定规律走遍树的各个顶点,且使每一顶点仅被访问一次,即找一个完整而有规律的走法,以得到树中所有结点的一个线性序列。

常用方法如下:

  • 先根(序)遍历:先访问树的根结点,然后依次先根遍历根的每棵子树。

  • 后根(序)遍历:先依次后根遍历每棵子树,然后访问根结点。

  • 层次遍历:先访问第一层上的结点,然后依次遍历第二层,一直到最后一层的结点。

广义表建树

posted on 2022-05-17 12:21  Black_x  阅读(97)  评论(0编辑  收藏  举报