关闭

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

标签: struct测试null算法list
34195人阅读 评论(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
请按任意键继续. . .


 

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

4
0

猜你在找
【视频】C语言及程序设计(讲师:贺利坚)
【视频】Python爬虫工程师培养课程全套(讲师:韦玮)
【视频】Python全栈开发入门与实战(讲师:李杰)
【视频】2017软考网络规划设计师套餐(讲师:任铄)
【视频】2017软考软件设计师套餐(讲师:任铄)
【视频】2017软考信息系统项目管理师套餐(讲师:任铄)
【视频】软考(高级)项目经理实战营(讲师:张传波)
【视频】微信公众平台开发套餐(讲师:刘运强)
深度学习原理+实战+算法+主流框架套餐(讲师:唐宇迪)
2017系统集成项目管理工程师通关套餐(讲师:徐朋)
查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:3269349次
    • 积分:33728
    • 等级:
    • 排名:第135名
    • 原创:393篇
    • 转载:88篇
    • 译文:5篇
    • 评论:3370条
    个人说明
    联系方式:
    最新评论