树的双亲表示法(包含C语言实现代码)

1年前 (2024-04-28)

前面讲了二叉树的顺序存储和链式存储,本节来学习如何存储具有普通树结构的数据。


普通树存储结构

图 1 普通树存储结构


如图 1 所示,这是一棵普通的树,该如何存储呢?通常,存储具有普通树结构数据的方法有 3 种:

  1. 双亲表示法;

  2. 孩子表示法;

  3. 孩子兄弟表示法;


本节先来学习双亲表示法

双亲表示法采用顺序表(也就是数组)存储普通树,其实现的核心思想是:顺序存储各个节点的同时,给各节点附加一个记录其父节点位置的变量。

注意,根节点没有父节点(父节点又称为双亲节点),因此根节点记录父节点位置的变量通常置为 -1。

例如,采用双亲表示法存储图 1 中普通树,其存储状态如图 2 所示:


双亲表示法存储普通树示意图

图 2 双亲表示法存储普通树示意图


图 2 存储普通树的过程转化为 C 语言代码为:

#define MAX_SIZE 100//宏定义树中结点的数量

typedef char ElemType;//宏定义树结构中数据类型

typedef struct Snode{

TElemType data;//树中结点的数据类型

int parent;//结点的父结点在数组中的位置下标

}PTNode;

typedef struct {

PTNode tnode[MAX_SIZE];//存放树中所有结点

int n;//根的位置下标和结点数

}PTree;


因此,存储图 1 中普通树的 C 语言实现代码为:

#include<stdio.h>

#include<stdlib.h>

#define MAX_SIZE 20

typedef char ElemType;//宏定义树结构中数据类型

typedef struct Snode  //结点结构

{

    ElemType data;

    int parent;

}PNode;

typedef struct  //树结构

{

    PNode tnode[MAX_SIZE];

    int n;                 //结点个数

}PTree;

PTree InitPNode(PTree tree)

{

    int i, j;

    char ch;

    printf("请输出节点个数:\n");

    scanf("%d", &(tree.n));

    printf("请输入结点的值其双亲位于数组中的位置下标:\n");

    for (i = 0; i < tree.n; i++)

    {

        getchar();

        scanf("%c %d", &ch, &j);

        tree.tnode[i].data = ch;

        tree.tnode[i].parent = j;

    }

    return tree;

}

void FindParent(PTree tree)

{

    char a;

    int isfind = 0;

    printf("请输入要查询的结点值:\n");

    getchar();

    scanf("%c", &a);

    for (int i = 0; i < tree.n; i++) {

        if (tree.tnode[i].data == a) {

            isfind = 1;

            int ad = tree.tnode[i].parent;

            printf("%c的父节点为 %c,存储位置下标为 %d", a, tree.tnode[ad].data, ad);

            break;

        }

    }

    if (isfind == 0) {

        printf("树中无此节点");

    }

}

int main()

{

    PTree tree;

    for (int i = 0; i < MAX_SIZE; i++) {

        tree.tnode[i].data = " ";

        tree.tnode[i].parent = 0;

    }

   

    tree = InitPNode(tree);

    FindParent(tree);

    return 0;

}

程序运行示例:

请输出节点个数:
10
请输入结点的值其双亲位于数组中的位置下标:
R -1
A 0
B 0
C 0
D 1
E 1
F 3
G 6
H 6
K 6
请输入要查询的结点值:
C

C的父节点为 R,存储位置下标为 0