邻接矩阵法
用一个一维数组存储图的顶点信息,用一个二维数组存储图的边信息。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| #define MAX_LENGTH 100
typedef char VertexType;
typedef int EdgeType;
typedef struct Graph { VertexType vertices[MAX_LENGTH]; EdgeType edges[MAX_LENGTH][MAX_LENGTH]; int vernum, arcnum; } Graph;
|
广度优先搜索
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
| typedef struct Queue { int front = 0, rear = 0; int queue[MAX_LENGTH]; } Queue;
void BFSTraverse(Graph graph) { bool isVisited[graph.vernum]; for (int i = 0; i < graph.vernum; ++i) isVisited[i] = false;
Queue Q = {.front = 0, .rear = 0};
for (int i = 0; i < graph.vernum; ++i) if (!isVisited[i]) BFS(graph, i, &Q, isVisited); }
void BFS(Graph graph, int init_ver, Queue *Q, bool isVisited[]) { printf("访问顶点: %d\n", init_ver); isVisited[init_ver] = true;
Q->queue[Q->rear++] = init_ver;
while (Q->front != Q->rear) { int visited_ver = Q->queue[Q->front++]; for (int w = 0; w < graph.vernum; w++) { if (graph.edges[visited_ver][w] != 0 && !isVisited[w]) { printf("访问顶点: %d\n", w); isVisited[w] = true; Q->queue[Q->rear++] = 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
|
void DFSTraverse(Graph graph) { bool isVisited[graph.vernum]; for (int i = 0; i < graph.vernum; ++i) isVisited[i] = false;
for (int i = 0; i < graph.vernum; ++i) if (!isVisited[i]) DFS(graph, i, isVisited); }
void DFS(Graph graph, int init_ver, bool isVisited[]) { printf("访问顶点: %d\n", init_ver); isVisited[init_ver] = true;
for (int w = 0; w < graph.vernum; w++) { if (graph.edges[init_ver][w] != 0 && !isVisited[w]) DFS(graph, w, isVisited); } }
|
邻接表法
可以简单理解为,用一个一维数组存储图的所有顶点信息(顶点表),每个顶点结点中包含一个链式结构的边表,边表由依附于该顶点的所有边的边结点组成。
顶点结点中包含了顶点的信息和指向第一条边的指针。边结点中包含了边的信息(边的权值)、边指向的顶点,和依附于同一个结点的下一条边的指针。
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
| #define MAX_LENGTH 100
typedef char VertexType;
typedef int EdgeType;
typedef struct EdgeNode { EdgeType edge_data; int vertex_index; struct EdgeNode *next_edge_node; } EdgeNode;
typedef struct VertexNode { VertexType vertex_data; EdgeNode *first_edge_node; } VertexNode, VertexTable[MAX_LENGTH];
typedef struct Graph { VertexTable table; int vernum, arcnum; } Graph;
|
广度优先搜索
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
| typedef struct Queue { int front = 0, rear = 0; int queue[MAX_LENGTH]; } Queue;
void BFSTraverse(Graph graph) { bool isVisited[graph.vernum]; for (int i = 0; i < graph.vernum; ++i) isVisited[i] = false;
Queue Q = {.front = 0, .rear = 0};
for (int i = 0; i < graph.vernum; ++i) if (!isVisited[i]) BFS(graph, i, &Q, isVisited); }
void BFS(Graph graph, int init_ver, Queue *Q, bool isVisited[]) { printf("访问顶点%d\n", init_ver); isVisited[init_ver] = true;
Q->queue[Q->rear++] = init_ver;
while (Q->front != Q->rear) { int visited_ver = Q->queue[Q->front++];
EdgeNode *edge_node = NULL; for (edge_node = graph.table[visited_ver].first_edge_node; edge_node != NULL; edge_node = edge_node->next_edge_node) { int w = edge_node->vertex_index; if (!isVisited[w]) { printf("访问顶点%d\n", w); isVisited[w] = true; Q->queue[Q->rear++] = 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 37 38 39
|
void DFSTraverse(Graph graph) { bool isVisited[graph.vernum]; for (int i = 0; i < graph.vernum; ++i) isVisited[i] = false;
for (int i = 0; i < graph.vernum; ++i) if (!isVisited[i]) DFS(graph, i, isVisited); }
void DFS(Graph graph, int init_ver, bool isVisited[]) { printf("访问顶点%d\n", init_ver); isVisited[init_ver] = true;
EdgeNode *edge_node = NULL; for (edge_node = graph.table[init_ver].first_edge_node; edge_node != NULL; edge_node = edge_node->next_edge_node) { int w = edge_node->vertex_index; if (!isVisited[w]) DFS(graph, w, isVisited); } }
|
十字链表法
十字链表仅可存储有向图,用一个一维数组存储图的所有顶点信息(顶点表),每个顶点结点中包含两个链式结构的弧表(出弧和入弧),出弧由弧尾相同的弧结点组成,入弧由弧头相同的弧结点组成。
顶点结点中包含了顶点的信息、第一条入弧的指针和第一条出弧的指针。弧结点中包含了弧的信息(弧的权值)、弧尾依附的顶点、弧头指向的顶点,和弧尾弧头相同的下一条弧的指针。
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
| #define MAX_LENGTH 100
typedef char VertexType;
typedef int EdgeType;
typedef struct EdgeNode { EdgeType edge_data; int tail_vertex_index; int head_vertex_index; struct EdgeNode *tail_edge_node; struct EdgeNode *head_edge_node; } EdgeNode;
typedef struct VertexNode { VertexType vertex_data; EdgeNode *firstIn; EdgeNode *firstOut; } VertexNode, VertexTable[MAX_LENGTH];
typedef struct Graph { VertexTable table; int vernum, arcnum; } Graph;
|
邻接多重表
十字链表仅可存储无向图,用一个一维数组存储图的所有顶点信息(顶点表),每个顶点结点中包含一个链式结构的边表,边表中边表结点的成分复杂,每个边结点中包含两个指针,指向两个顶点。
顶点结点中包含了顶点的信息和指向第一条边的指针。边结点中包含了边的信息、边依附的第一个顶点、同样依附的第一个顶点的下一条边指针、边依附的第二个顶点,同样依附的第而个顶点的下一条边指针。
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
| #define MAX_LENGTH 100
typedef char VertexType;
typedef int EdgeType;
typedef struct EdgeNode { EdgeType edge_data; int i_vertex_index; struct EdgeNode *i_edge_node; int j_vertex_index; struct EdgeNode *j_edge_node; } EdgeNode;
typedef struct VertexNode { VertexType vertex_data; EdgeNode *first_edge_node; } VertexNode, VertexTable[MAX_LENGTH];
typedef struct Graph { VertexTable table; int vernum, arcnum; } Graph;
|