邻接表

 #返回上一级

@Author: 张海拔

@Update: 2014-01-11

@Link: http://www.cnblogs.com/zhanghaiba/p/3515294.html

 

  1 /*

  2  *Author: ZhangHaiba

  3  *Date: 2014-1-11

  4  *File: adj_list.c

  5  *

  6  *adjacency list

  7  */

  8 

  9 #include <stdio.h>

 10 #include <stdlib.h>

 11 

 12 typedef struct e_node* link;

 13 

 14 typedef struct e_node {

 15     int adjv;

 16     link next;

 17 }e_node;

 18 

 19 typedef struct v_node {

 20     char name;

 21     link next;

 22 }v_node;

 23 

 24 //public

 25 void init_adj_list(v_node*, int);

 26 void create_adj_list(v_node*, int, int);

 27 void show_adj_list(v_node*, int);

 28 void destory_adj_list(v_node*, int);

 29 //private

 30 static link head_insert_node(link, int);

 31 

 32 v_node list[512];

 33 

 34 int main(void)

 35 {

 36     int n, m;

 37 

 38     scanf("%d%d", &n, &m);

 39     init_adj_list(list, n);

 40     create_adj_list(list, n, m);

 41     show_adj_list(list, n);

 42     destory_adj_list(list, n);

 43     return 0;

 44 }

 45 

 46 void init_adj_list(v_node* a, int n)

 47 {

 48     int i;

 49 

 50     for (i = 0; i < n; ++i)

 51         a[i].next = NULL;

 52 }

 53 

 54 

 55 link head_insert_node(link h, int v)

 56 {

 57     link p = malloc(sizeof (e_node));

 58     p->adjv = v;

 59     link save = h;

 60     h = p;

 61     p->next = save;

 62     return h;

 63 }

 64 

 65 void create_adj_list(v_node* a, int n, int m)

 66 {

 67     int i;

 68 

 69     //input name

 70     for (i = 0; i < n; ++i)

 71         scanf("%s", &a[i].name);

 72 

 73     //input edge info: (x, y)

 74     int x, y;

 75 

 76     for (i = 0; i < m; ++i) {

 77         scanf("%d%d", &x, &y);

 78         a[x].next = head_insert_node(a[x].next, y);

 79         //if it is undirected graph add code as next line

 80         //a[y].next = head_insert_node(a[y].next, x);

 81     }

 82 }

 83 

 84 void show_adj_list(v_node* a, int n)

 85 {

 86     int i;

 87     link p;

 88 

 89     for (i = 0; i < n; ++i) {

 90         printf("%c: %d", a[i].name, i);

 91         for (p = a[i].next; p != NULL; p = p->next)

 92             printf("->%d", p->adjv);

 93         printf("\n");

 94     }

 95 }

 96 

 97 void destory_adj_list(v_node* a, int n)

 98 {

 99     int i;

100     link p;

101 

102     for (i = 0; i < n; ++i)

103         for (p = a[i].next; p != NULL; p = p->next)

104             free(p);

105 }

 

测试用例

输入:

5 6
A B C D E
0 4
1 2
1 0
2 3
2 0
3 4

输出:
A: 0->4
B: 1->0->2
C: 2->0->3
D: 3->4
E: 4

 

邻接表,其实就是一个由顶点节点(v_node)的数组组成,而每个数组元素会连着一个链表(包括空链表)。

即每个顶点节点需要包含边节点的指针e_node *next,且初始化为空,而边节点(e_node)除了包含next指针指向下一节点,还需包含adjv存储邻接点。

因此,先声明了边节点的指针类型、边节点类型、顶点节点类型。

其次,创建邻接表用到了创建链表中的头插法。

另外,对于无向图有两次插入。不过插入的次序可能还需要结合具体要求,否则上面的代码会出现对不同的数组元素反复进行头插,显得比较乱。

最后注意,由于动态分配使用了堆内存,必须还有destory_adj_list()函数来销毁邻接表。

 

总结:邻接表的创建核心在于头插法,节点数据结构最好区分为两个:v_node和e_node

 

  #返回上一级

你可能感兴趣的:(表)