图
:::danger 注意 ⚠
仅此文件从上到下复制成一个文件即可使用哦 ~
包括DFS与BFS
BY Lucifer LGX
:::
命令行
前提是windows有MinGW环境
1 2 3 4 5 6 7 8
| gcc xxx.c
g++ xxx.cpp
|
结构体定义
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
| #include <stdio.h> #include <stdlib.h>
#define MAX_VERTEX_NUM 20 #define VRType int #define InfoType char #define VertexType int
typedef enum{DG, DN, UDG, UDN} GraphKind; typedef enum{FALSE, TRUE} bools; bools visited[MAX_VERTEX_NUM];
typedef struct Queue{ VertexType data; struct Queue * next; }Queue;
typedef struct { VRType adj; InfoType * info; }ArcCell, AdjMatrix[MAX_VERTEX_NUM][MAX_VERTEX_NUM];
typedef struct { VertexType vexs[MAX_VERTEX_NUM]; AdjMatrix arcs; int vexnum, arcnum; GraphKind kind; }MGraph;
|
定位
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| int LocateVex(MGraph * G, VertexType v){ int i = 0; for (; i < G->vexnum; i++) { if (G->vexs[i] == v) { break; } } if (i > G->vexnum) { printf("没有这个顶点! \n"); return -1; } return i; }
|
第一个顶点
1 2 3 4 5 6 7 8 9
| int FirstAdjVex(MGraph G,int v){ for(int i = 0; i < G.vexnum; i++){ if( G.arcs[v][i].adj ){ return i; } } return -1; }
|
下一个顶点
1 2 3 4 5 6 7 8 9
| int NextAdjVex(MGraph G,int v,int w){ for(int i = w + 1; i < G.vexnum; i++){ if( G.arcs[v][i].adj ){ return i; } } return -1; }
|
输出
1 2 3
| void visitVex(MGraph G, int v){ printf("%d ", G.vexs[v]); }
|
DFS
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
| void DFS(MGraph G,int v){ visited[v] = TRUE; visitVex(G, v); for(int w = FirstAdjVex(G,v); w >= 0; w = NextAdjVex(G, v, w)){ if(!visited[w]){ printf("-> "); DFS(G, w); } } }
void DFSTraverse(MGraph G){ int v; for( v = 0; v < G.vexnum; ++v){ visited[v] = FALSE; } for( v = 0; v < G.vexnum; v++){ if(!visited[v]){ DFS(G, v); } } }
|
队列操作
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
| void InitQueue(Queue ** Q){ (*Q) = (Queue*) malloc (sizeof(Queue)); (*Q)->next = NULL; }
void EnQueue(Queue **Q, VertexType v){ Queue * element = (Queue*) malloc (sizeof(Queue)); element->data = v; element->next = NULL; Queue * temp = (*Q); while (temp->next != NULL) { temp = temp->next; } temp->next = element; }
void DeQueue(Queue **Q, int *u){ (*u) = (*Q)->next->data; (*Q)->next = (*Q)->next->next; }
bool QueueEmpty(Queue *Q){ if (Q->next == NULL) { return true; } return false; }
|
BFS
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
| void BFSTraverse(MGraph G){ int v; for( v = 0; v < G.vexnum; ++v){ visited[v] = FALSE; } Queue * Q; InitQueue(&Q); for( v = 0; v < G.vexnum; v++){ if(!visited[v]){ visited[v] = TRUE; visitVex(G, v); EnQueue(&Q, G.vexs[v]); while (!QueueEmpty(Q)) { int u; DeQueue(&Q, &u); u = LocateVex(&G, u); for (int w = FirstAdjVex(G, u); w >= 0; w = NextAdjVex(G, u, w)) { if (!visited[w]) { printf("-> "); visited[w] = TRUE; visitVex(G, w); EnQueue(&Q, G.vexs[w]); } } } } } }
|
构造有向图
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
| void CreateDG(MGraph *G){ printf("请输入有向图的顶点数和弧数(以','隔开): \n"); scanf("%d,%d", &(G->vexnum), &(G->arcnum)); int num = 1; for (int i = 0; i < G->vexnum; i++) { printf("请输入第%d个顶点名称: \n", num); scanf("%d", &(G->vexs[i])); num++; } for (int i = 0; i < G->vexnum; i++) { for (int j = 0; j<G->vexnum; j++) { G->arcs[i][j].adj = 0; G->arcs[i][j].info = NULL; } } for (int i = 0; i < G->arcnum; i++) { int v1,v2; printf("请输入弧头和弧尾(以','隔开): \n"); scanf("%d,%d", &v1, &v2); int n = LocateVex(G, v1); int m = LocateVex(G, v2); if (m == -1 || n == -1) { printf("没有这个顶点! \n"); return; } G->arcs[n][m].adj = 1; } }
|
构造无向图
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
| void CreateDN(MGraph *G){ printf("请输入无向图的顶点数和弧数(以','隔开): \n"); scanf("%d,%d", &(G->vexnum), &(G->arcnum)); int num = 1; for (int i = 0 ; i < G->vexnum; i++) { printf("请输入第%d个顶点名称: \n", num); scanf("%d", &(G->vexs[i])); num++; } for (int i = 0; i < G->vexnum; i++) { for (int j = 0; j < G->vexnum; j++) { G->arcs[i][j].adj = 0; G->arcs[i][j].info = NULL; } } for (int i = 0; i < G->arcnum; i++) { int v1, v2; printf("请输入弧头和弧尾(以','隔开): \n"); scanf("%d,%d", &v1, &v2); int n = LocateVex(G, v1); int m = LocateVex(G, v2); if (m == -1 || n == -1) { printf("没有这个顶点!\n"); return; } G->arcs[n][m].adj = 1; G->arcs[m][n].adj = 1; } }
|
构造有向网
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
| void CreateUDG(MGraph *G){ printf("请输入有向网的顶点数和弧数(以','隔开): \n"); scanf("%d,%d", &(G->vexnum), &(G->arcnum)); int num = 1; for (int i = 0; i < G->vexnum; i++) { printf("请输入第%d个顶点名称: \n", num); scanf("%d", &(G->vexs[i])); num++; } for (int i = 0; i < G->vexnum; i++) { for (int j = 0; j < G->vexnum; j++) { G->arcs[i][j].adj = 0; G->arcs[i][j].info = NULL; } } for (int i = 0; i < G->arcnum; i++) { int v1, v2, w; printf("请输入弧头、弧尾和权值(以','隔开): \n"); scanf("%d,%d,%d", &v1, &v2, &w); int n = LocateVex(G, v1); int m = LocateVex(G, v2); if (m ==-1 || n == -1) { printf("没有这个顶点! \n"); return; } G->arcs[n][m].adj = w; } }
|
构造无向网
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
| void CreateUDN(MGraph* G){ printf("请输入无向网的顶点数和弧数: \n"); scanf("%d,%d", &(G->vexnum), &(G->arcnum)); int num = 1; for (int i = 0; i < G->vexnum; i++) { printf("请输入第%d个顶点名称: \n", num); scanf("%d", &(G->vexs[i])); num++; } for (int i = 0; i < G->vexnum; i++) { for (int j = 0; j < G->vexnum; j++) { G->arcs[i][j].adj = 0; G->arcs[i][j].info = NULL; } } for (int i = 0; i < G->arcnum; i++) { int v1, v2, w; printf("请输入弧头、弧尾和权值(以','隔开): \n"); scanf("%d,%d,%d", &v1, &v2, &w); int m = LocateVex(G, v1); int n = LocateVex(G, v2); if (m ==-1 || n == -1) { printf("没有这个顶点! \n"); return; } G->arcs[n][m].adj = w; G->arcs[m][n].adj = w; } }
|
构造图
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
| void CreateGraph(MGraph *G){ printf("请选择构造图的类型: \n"); printf("0: 有向图 \n"); printf("1: 无向图 \n"); printf("2: 有向网 \n"); printf("3: 无向网 \n"); printf("您的选择是: \n"); scanf("%d", &(G->kind)); switch (G->kind) { case DG: return CreateDG(G); break; case DN: return CreateDN(G); break; case UDG: return CreateUDG(G); break; case UDN: return CreateUDN(G); break; default: break; } }
|
遍历
1 2 3 4 5 6 7 8
| void PrintGrapth(MGraph G){ for (int i = 0; i < G.vexnum; i++){ for (int j = 0; j < G.vexnum; j++){ printf("%d ", G.arcs[i][j].adj); } printf("\n"); } }
|
主函数
1 2 3 4 5 6 7 8 9 10
| int main() { MGraph G; CreateGraph(&G); PrintGrapth(G); printf("\n DFS遍历: \n"); DFSTraverse(G); printf("\n BFS遍历: \n"); BFSTraverse(G); return 0; }
|