关闭

图---邻接表(建立,深度遍历,广度遍历)

标签: struct测试null算法list
38745人阅读 评论(32) 收藏 举报
分类:

     图的邻接表表示法类似于树的孩子链表表示法。对于图G中的每个顶点vi,该方法把所有邻接于vi的顶点vj链成一个带头结点的单链表,这个单链表就称为顶点vi的邻接表(Adjacency List)。

以下代码测试过,为图的邻接表表示方式。

 C++ Code 
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
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
/************************************************************************/
/* 图的邻接表存储结构                                                    */
/************************************************************************/
#ifdef _MSC_VER
#define _CRTDBG_MAP_ALLOC
#include <stdlib.h>
#include <crtdbg.h>
#ifdef _DEBUG
#define new new(_NORMAL_BLOCK, __FILE__, __LINE__) 
#endif
#endif

#include <stdio.h>
#define MaxVertexNum 100
#define QueueSize 30 
typedef enum{ FALSE, TRUE }Boolean;
Boolean visited[MaxVertexNum];
typedef char VertexType;
typedef int EdgeType;
typedef struct node     //边表结点
{
    int adjvex;         //邻接点域
    struct node *next;  //域链
    //若是要表示边上的权,则应增加一个数据域
}EdgeNode;
typedef struct vnode    //顶点边结点
{
    VertexType vertex;  //顶点域
    EdgeNode *firstedge;//边表头指针
}VertexNode;
typedef VertexNode AdjList[MaxVertexNum];   //AdjList是邻接表类型
typedef struct
{
    AdjList adjlist;    //邻接表
    int n, e;           //图中当前顶点数和边数
}ALGraph;               //对于简单的应用,无须定义此类型,可直接使用AdjList类型
/************************************************************************/

/* 建立无向图的邻接表算法                                               */
/************************************************************************/
void CreateGraphAL(ALGraph *G)
{
    int i, j, k;
    EdgeNode * s;
    printf("请输入顶点数和边数(输入格式为:顶点数,边数):\n");
    scanf("%d,%d", &(G->n), &(G->e));       // 读入顶点数和边数   
    printf("请输入顶点信息(输入格式为:顶点号<CR>)每个顶点以回车作为结束:\n");
    for (i = 0; i < G->n; i++)              // 立有n个顶点的顶点表   
    {
        scanf("\n%c", &(G->adjlist[i].vertex)); // 读入顶点信息   
        G->adjlist[i].firstedge = NULL;            // 点的边表头指针设为空   
    }
    printf("请输入边的信息(输入格式为:i,j):\n");
    for (k = 0; k < G->e; k++)      // 建立边表   
    {
        scanf("\n%d,%d", &i, &j); // 读入边<Vi,Vj>的顶点对应序号   
        s = new EdgeNode;         // 生成新边表结点s   
        s->adjvex = j;         // 邻接点序号为j   
        s->next = G->adjlist[i].firstedge; // 将新边表结点s插入到顶点Vi的边表头部   
        G->adjlist[i].firstedge = s;
        s = new EdgeNode;
        s->adjvex = i;
        s->next = G->adjlist[j].firstedge;
        G->adjlist[j].firstedge = s;
    }
}
/************************************************************************/
/* 深度优先遍历                                                         */
/************************************************************************/
void DFS(ALGraph *G, int i)
{
    //以vi为出发点对邻接表表示的图G进行深度优先搜索
    EdgeNode *p;
    printf("visit vertex:%c\n", G->adjlist[i].vertex);  // 访问顶点vi
    visited[i] = TRUE;              //标记vi已访问
    p = G->adjlist[i].firstedge;        //取vi边表的头指针
    while (p)
    {                               //依次搜索vi的邻接点vj,这里j=p->adjvex
        if (!visited[p->adjvex])    //若vi尚未被访问
            DFS(G, p->adjvex);      //则以Vj为出发点向纵深搜索
        p = p->next;                     //找vi的下一邻接点
    }
}
void DFSTraverseM(ALGraph *G)
{
    int i;
    for (i = 0; i < G->n; i++)
        visited[i] = FALSE;
    for (i = 0; i < G->n; i++)
        if (!visited[i])
            DFS(G, i);
}
/************************************************************************/
/* 广度优先遍历                                                         */
/************************************************************************/
typedef struct
{
    int front;
    int rear;
    int count;
    int data[QueueSize];
}CirQueue;
void InitQueue(CirQueue *Q)
{
    Q->front = Q->rear = 0;
    Q->count = 0;
}
int QueueEmpty(CirQueue *Q)
{
    return Q->count == 0;
}
int QueueFull(CirQueue *Q)
{
    return Q->count == QueueSize;
}
void EnQueue(CirQueue *Q, int x)
{
    if (QueueFull(Q))
        printf("Queue overflow");
    else
    {
        Q->count++;
        Q->data[Q->rear] = x;
        Q->rear = (Q->rear + 1) % QueueSize;
    }
}
int DeQueue(CirQueue *Q)
{
    int temp;
    if (QueueEmpty(Q))
    {
        printf("Queue underflow");
        return NULL;
    }
    else
    {
        temp = Q->data[Q->front];
        Q->count--;
        Q->front = (Q->front + 1) % QueueSize;
        return temp;
    }
}
void BFS(ALGraph*G, int k)
{   // 以vk为源点对用邻接表表示的图G进行广度优先搜索
    int i;
    CirQueue Q;             //须将队列定义中DataType改为int
    EdgeNode *p;
    InitQueue(&Q);          //队列初始化
    printf("visit vertex:%c\n", G->adjlist[k].vertex);      //访问源点vk
    visited[k] = TRUE;
    EnQueue(&Q, k);         //vk已访问,将其人队。(实际上是将其序号人队)
    while (!QueueEmpty(&Q))
    {                                   //队非空则执行
        i = DeQueue(&Q);                    //相当于vi出队
        p = G->adjlist[i].firstedge;        //取vi的边表头指针
        while (p)
        {                               //依次搜索vi的邻接点vj(令p->adjvex=j)
            if (!visited[p->adjvex])
            {                           //若vj未访问过
                printf("visit vertex:%c\n", G->adjlist[p->adjvex].vertex);      //访问vj
                visited[p->adjvex] = TRUE;
                EnQueue(&Q, p->adjvex); //访问过的vj人队
            }
            p = p->next;                    //找vi的下一邻接点
        }
    }
}
void BFSTraverseM(ALGraph *G)
{
    int i;
    for (i = 0; i < G->n; i++)
        visited[i] = FALSE;
    for (i = 0; i < G->n; i++)
        if (!visited[i])
            BFS(G, i);
}
/************************************************************************/
/* 打印邻接表                                                     */
/************************************************************************/
void PrintfGraphAL(ALGraph *G)
{
    for (int i = 0; i < G->n; i++)
    {
        printf("vertex:%c", G->adjlist[i].vertex);
        EdgeNode *p = G->adjlist[i].firstedge;
        while (p)
        {
            printf("→:%d", p->adjvex);
            p = p->next;
        }
        printf("\n");
    }
}
/************************************************************************/
/* 删除邻接表                                                     */
/************************************************************************/
void DeleteGraphAL(ALGraph *G)
{
    for (int i = 0; i < G->n; i++)
    {
        EdgeNode *q;
        EdgeNode *p = G->adjlist[i].firstedge;
        while (p)
        {
            q = p;
            p = p->next;
            delete q;
        }
        G->adjlist[i].firstedge = NULL;
    }
}
/************************************************************************/
/* 主函数调用                                                           */
/************************************************************************/
int main()
{
#ifdef _MSC_VER
    _CrtSetDbgFlag(_CRTDBG_LEAK_CHECK_DF | _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG));
    _CrtDumpMemoryLeaks();
#endif

    ALGraph G;
    CreateGraphAL(&G);
    printf("深度优先遍历:\n");
    DFSTraverseM(&G);
    printf("广度优先遍历:\n");
    BFSTraverseM(&G);
    printf("邻接表:\n");
    PrintfGraphAL(&G);
    DeleteGraphAL(&G);

    return 0;
}

测试结果如下:

 NormalText Code 
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
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
请输入顶点数和边数(输入格式为:顶点数,边数):
8,9
请输入顶点信息(输入格式为:顶点号<CR>)每个顶点以回车作为结束:
A
B
C
D
E
F
G
H
请输入边的信息(输入格式为:i,j):
0,1
0,2
1,3
1,4
2,5
2,6
3,7
4,7
5,6
深度优先遍历:
visit vertex:A
visit vertex:C
visit vertex:G
visit vertex:F
visit vertex:B
visit vertex:E
visit vertex:H
visit vertex:D
广度优先遍历:
visit vertex:A
visit vertex:C
visit vertex:B
visit vertex:G
visit vertex:F
visit vertex:E
visit vertex:D
visit vertex:H
邻接表:
vertex:A→:2→:1
vertex:B→:4→:3→:0
vertex:C→:6→:5→:0
vertex:D→:7→:1
vertex:E→:7→:1
vertex:F→:6→:2
vertex:G→:5→:2
vertex:H→:4→:3
请按任意键继续. . .


 

如果测试有误,若是代码有错,请指出,共同学习。

5
0
查看评论

【数据结构】图的构建(邻接表法)

最近整理电脑,发现了以前写的数据结构的代码,由于时间久了,好多代码都找不到了,现在扒出来复习一下。 如果看不懂下面关于图的术语或者压根就不知道图。建议看一下严蔚敏版的《数据结构》中对图的介绍 图的构建方法有好几种,如邻接矩阵法,邻接表法,十字链表法,邻接多重表。今天介绍邻接表法。 邻接...
  • sundong_d
  • sundong_d
  • 2015-04-10 19:12
  • 9551

【数据结构】邻接表创建_CreateALGraph

#include "stdio.h" #include "stdlib.h" #include "io.h" #include "math.h" #include "time.h"...
  • manoel
  • manoel
  • 2013-11-14 17:15
  • 13706

图的存储结构——邻接表的建立

邻接表(无向图)
  • u012257743
  • u012257743
  • 2014-07-06 15:05
  • 5016

邻接表的建立-两种方式(模板)

/* * 构建邻接表模板 * */ #include #include int head[100100];//表头,head[i]代表起点是i的边的编号 int cnt;//代表边的编号 struct s { int u;//记录边的起点 int v;//记录边的终点 in...
  • haut_ykc
  • haut_ykc
  • 2016-08-10 23:10
  • 755

邻接表的创建与输出(C语言)

邻接表是图的常用储存结构之一,它很好的解决了邻接矩阵占用空间较大的问题。 邻接表用到了两个结构体,一个是顶点表,包括点的序号和连接此起点的第一条边。一个是边表,包括连接此边的终点和对应之前起点的下一条边。 初始化邻接表时,先将定点表赋值,并把指针指向NULL。再将输入的数据插入,插入到起点所对应的边...
  • sinat_33844073
  • sinat_33844073
  • 2017-03-09 16:20
  • 1059

数据结构上机实验--有向图邻接表的建立,深度广度搜索及拓扑排序

1、以邻接表存储方式创建一个有向图,并对图进行深度遍历和广度遍历。 2、编写程序实现图的拓扑排序。
  • qq_29600137
  • qq_29600137
  • 2015-11-22 20:06
  • 1319

数组建立邻接表的方法

具体的思路是,在建立邻接表时
  • ZouCharming
  • ZouCharming
  • 2014-11-21 16:58
  • 1530

数据结构:图的存储结构之邻接表

对于图来说,邻接矩阵是不错的一种图存储结构,但是我们也发现,对于边数相对顶点较少的图,这种结构是存在对存储空间的极大浪费的。因此我们考虑另外一种存储结构方式:邻接表(Adjacency List),即数组与链表相结合的存储方法。 邻接表的处理方法是这样的。 1、图中顶点用一个一维数组存储,另外,...
  • Simba888888
  • Simba888888
  • 2013-04-30 00:05
  • 48973

关于邻接表和其深度优先遍历、广度优先遍历的问题

如果有一个邻接表存储的图,以
  • u012989088
  • u012989088
  • 2014-09-09 10:16
  • 6347

图的深度优先搜索(邻接表)

图的遍历(Traversing Graph)是指从图中某一顶点出发访问图中其余顶点,且使每个顶点仅被访问一次。 深度优先搜索(Depth First Search)         深度优先搜索假设初始状态下图中所有顶点都未被访问,尝试优先搜索从图...
  • furney
  • furney
  • 2012-02-11 11:29
  • 4037
    个人资料
    • 访问:3549252次
    • 积分:36049
    • 等级:
    • 排名:第137名
    • 原创:402篇
    • 转载:88篇
    • 译文:5篇
    • 评论:3424条
    个人说明
    联系方式:
    文章存档
    最新评论