树的存储结构

一、父亲表示法

原理:利用一维数组来表示树,一维数组的每个元素表示树的结点,其中包括结点的数据和该结点 的双亲在数组中的下标;数组中的第一个元 素表示根结点,该结点无双亲,因此parent域用-1表示,其他结点按照层序存储.如结点B、 C、D 的双亲结点是下标为0的根结点,其parent域用0表示。
优缺点:利用了树中除根结点外每个结点都有唯一的父结点这个性质。很容易找到树根,但找孩子时需要遍历整个线性表。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#include <iostream>
using namespace std;

struct Node{
    char data;
    int parent;
};

int main(){
    int n;
    cin>>n;
    Node tree[n];

    for(int i=0;i<n;i++){
        cin>>tree[i].data;
        cin>>tree[i].parent;
    }

    for(int i=0;i<n;i++){
        cout<<tree[i].data;
        cout<<' ';
        cout<<tree[i].parent;
        cout<<endl;
    }
}


二、孩子表示法

孩子表示法存储普通树采用的是 “顺序表+链表/数组” 的组合结构,其存储过程是:从树的根节点开始,使用顺序表依次存储树中各个节点,需要注意的是,与双亲表示法不同,孩子表示法会给各个节点配备一个链表或指针数组,用于存储各节点的孩子节点位于顺序表中的位置。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
#include<iostream>
using namespace std;
const int m = 10;           //树的度

struct node
{
    char data;             //数据域
    node* child[m];          //指针域,指向若干孩子结点
};

int main(){
    int n;
    cin>>n;
    node tree[n];
    tree[0].data='A';
    tree[0].child[0]=&tree[1];
    tree[1].data='B';
    cout<<tree[0].child[0]<<endl;
    cout<<&tree[1];
    return 0;
}


三、父亲孩子表示法

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include<iostream>
using namespace std;
const int m = 10;           //树的度

struct node
{
    char data;             //数据域
    node *child[m];       //指针域,指向若干孩子结点
    node  *father;
};

int main(){
    int n;
    cin>>n;
    node tree[n];
    tree[0].data='A';
    tree[0].child[0]=&tree[1];
    tree[1].data='B';
    tree[1].father=&tree[0];
    cout<<tree[1].father<<endl;
    cout<<&tree[0];
    return 0;
}


四、孩子兄弟表示法

树结构中,位于同一层的节点之间互为兄弟节点。例如,图 1 的普通树中,节点 A、B 和 C 互为兄弟节点,而节点  D、E 和 F 也互为兄弟节点。
孩子兄弟表示法,采用的是链式存储结构,其存储树的实现思想是:从树的根节点开始,依次用链表存储各个节点的孩子节点和兄弟节点。

因此,该链表中的节点应包含以下 3 部分内容(如图 2 所示):
1、节点的值;
2、指向第一个孩子节点的指针;
3、指向相邻右兄弟节点的指针;

struct Node{ 
       char  data; 
       Node * firstchild,*nextsibling; 
};


习题:

找树根和孩子
【问题描述】  给定一棵树,输出树的根root,孩子最多的结点max以及他的孩子
【输入格式】  第一行:n(结点数<=100),m(边数<=200)。 以下m行;每行两个结点x和y,    表示y是x的孩子(x,y<=1000)。
【输出格式】 第一行:树根:root。     第二行:孩子最多的结点max。        第三行:max的孩子。

【输入样例】
8 7
4 1
4 2
1 3
1 5
2 6
2 7
2 8

输出样例
4
2
6 7 8

Scroll to Top