0.?必要的说明
- 由于是用C语言编写并且图这一章中代码复用性很强,所以在写的时候都是建立工程分文件来写的,考虑一部分同学的特殊需要,笔者重新组织了所有的源文件(xxx.c)和头文件(xxx.h),并成为一个源文件,方便大家利用。最后考虑到在进行编译源文件和链接到相关的函数、变量以及声明时的顺序被无意打乱,程序可能跑不过,这种情况按下面红字操作。
- 有需要查看工程文件的伙伴可以点击这里进入代码仓库下载。
- 如果你的编译器是VS2019或者以往版本,那么你只需要复制一份代码到你的VS2019上再按下Fn + F5即可;如果你的编译器是CodeBlocks或者Dev C++等等其他的,那么你需要将每一个程序的第一行代码
#define _CRT_SECURE_NO_WARNINGS 1 删除后再将代码复制到你的编译器上运行。 - 你的支持和鼓励是我创作的最大动力😉!
1.?图的实现
?1.1?图的邻接矩阵实现
#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include <stdlib.h>
typedef char VertexDataType;
typedef int EdgeWeightDataType;
typedef struct {
VertexDataType* setsOfVertex;
EdgeWeightDataType** AdjacencyMatrix;
int numsOfVertex;
int numsOfEdge;
int MaxSizeCnt;
}MatrixGraph;
void InitGraph(MatrixGraph* Graph, int n);
void InsertVertex(MatrixGraph* Graph, VertexDataType vertex);
void InsertEdge(MatrixGraph* Graph, int v1, int v2, EdgeWeightDataType weight);
void ShowMatrix(MatrixGraph* Graph);
int main() {
MatrixGraph graph;
InitGraph(&graph, 5);
InsertVertex(&graph, 'A');
InsertVertex(&graph, 'B');
InsertVertex(&graph, 'C');
InsertVertex(&graph, 'D');
InsertVertex(&graph, 'E');
InsertEdge(&graph, 0, 1, 1);
InsertEdge(&graph, 0, 3, 1);
InsertEdge(&graph, 1, 2, 1);
InsertEdge(&graph, 1, 4, 1);
InsertEdge(&graph, 2, 3, 1);
InsertEdge(&graph, 2, 4, 1);
ShowMatrix(&graph);
return 0;
}
void InitGraph(MatrixGraph* Graph, int n) {
Graph->setsOfVertex = (VertexDataType*)malloc(sizeof(VertexDataType) * n);
Graph->AdjacencyMatrix = (EdgeWeightDataType**)malloc(sizeof(int*) * n);
for (int i = 0; i < n; i++) {
Graph->AdjacencyMatrix[i] = (EdgeWeightDataType*)malloc(sizeof(EdgeWeightDataType) * n);
}
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
Graph->AdjacencyMatrix[i][j] = 0;
}
}
Graph->numsOfEdge = 0;
Graph->numsOfVertex = 0;
Graph->MaxSizeCnt = n;
}
void InsertVertex(MatrixGraph* Graph, VertexDataType vertex) {
if (Graph->numsOfVertex <= Graph->MaxSizeCnt) {
Graph->setsOfVertex[Graph->numsOfEdge] = vertex;
Graph->numsOfVertex++;
}
}
void InsertEdge(MatrixGraph* Graph, int v1, int v2, EdgeWeightDataType weight) {
Graph->AdjacencyMatrix[v1][v2] = weight;
Graph->AdjacencyMatrix[v2][v1] = weight;
Graph->numsOfEdge++;
}
void ShowMatrix(MatrixGraph* Graph) {
printf("\n\n\n");
for (int i = 0; i < Graph->numsOfVertex; i++) {
printf(" [ ");
for (int j = 0; j < Graph->numsOfVertex; j++) {
if (j != Graph->numsOfVertex - 1) {
printf("%d ", Graph->AdjacencyMatrix[i][j]);
}
else {
printf("%d ", Graph->AdjacencyMatrix[i][j]);
}
}
printf("]");
printf("\n");
}
}
?1.2?图的邻接表实现
#define _CRT_SECURE_NO_WARNINGS 1
#define MAX_VERTEXNUMS 70
#include <stdio.h>
#include <stdlib.h>
typedef char VertexDataType;
typedef int EdgeWeightDataType;
typedef struct GraphEdgeNode {
int adjVertexIndex;
struct GraphEdgeNode* p_nextEdge;
EdgeWeightDataType infoOfEdge;
}EdgeNode;
typedef struct GraphVertexNode {
VertexDataType val;
EdgeNode* p_firstAdjEdge;
}VertexNode;
typedef struct {
VertexNode* setsOfVertex;
int vertexNums;
int edgeNums;
}ALGraph;
void BuildALGraph(ALGraph* graph);
int SearchVertexRetIndex(ALGraph* graph, VertexDataType val);
void showALGraph(ALGraph* graph);
#define _CRT_SECURE_NO_WARNINGS 1
#include "GraphOperationsStatement.h"
int main() {
ALGraph graph;
BuildALGraph(&graph);
showALGraph(&graph);
return 0;
}
void BuildALGraph(ALGraph* graph) {
graph->setsOfVertex = (VertexNode*)malloc(sizeof(VertexNode) * MAX_VERTEXNUMS);
int vertexNums = 0;
int edgeNums = 0;
printf("分别输入顶点和边的个数(num1 num2):\n");
scanf("%d %d", &vertexNums, &edgeNums);
getchar();
graph->vertexNums = vertexNums;
graph->edgeNums = edgeNums;
for (int i = 0; i < graph->vertexNums; i++) {
printf("输入第%d个顶点的信息:\n", i + 1);
scanf("%c", &(graph->setsOfVertex[i].val));
getchar();
graph->setsOfVertex[i].p_firstAdjEdge = NULL;
}
VertexDataType v1 = 0;
VertexDataType v2 = 0;
int v1Index = 0;
int v2Index = 0;
for (int i = 0; i < graph->edgeNums; i++) {
printf("输入第%d条边所依附的两个结点:\n", i + 1);
scanf("%c", &v1);
getchar();
scanf("%c", &v2);
getchar();
v1Index = SearchVertexRetIndex(graph, v1);
v2Index = SearchVertexRetIndex(graph, v2);
EdgeNode* newEdgeNode0 = (EdgeNode*)malloc(sizeof(EdgeNode));
newEdgeNode0->adjVertexIndex = v2Index;
newEdgeNode0->p_nextEdge = graph->setsOfVertex[v1Index].p_firstAdjEdge;
graph->setsOfVertex[v1Index].p_firstAdjEdge = newEdgeNode0;
EdgeNode* newEdgeNode1 = (EdgeNode*)malloc(sizeof(EdgeNode));
newEdgeNode1->adjVertexIndex = v1Index;
newEdgeNode1->p_nextEdge = graph->setsOfVertex[v2Index].p_firstAdjEdge;
graph->setsOfVertex[v2Index].p_firstAdjEdge = newEdgeNode1;
}
}
int SearchVertexRetIndex(ALGraph* graph, VertexDataType val) {
for (int i = 0; i < graph->vertexNums; i++) {
if (graph->setsOfVertex[i].val == val) {
return i;
}
}
return -1;
}
void showALGraph(ALGraph* graph) {
EdgeNode* cur = NULL;
printf("\n");
for (int i = 0; i < graph->vertexNums; i++) {
printf("%c->", graph->setsOfVertex[i].val);
cur = graph->setsOfVertex[i].p_firstAdjEdge;
while (cur != NULL) {
printf("%d->", cur->adjVertexIndex);
cur = cur->p_nextEdge;
}
printf("NULL\n");
}
}
2.?图的基础算法
?2.1?图的深度优先遍历
#define _CRT_SECURE_NO_WARNINGS 1
#define MAX_SIZEOFVERTEX 70
#include <stdio.h>
#include <stdlib.h>
typedef int VertexDataType;
typedef int EdgeWeightDataType;
typedef struct GraphEdgeNode {
int adjVertexIndex;
struct GraphEdgeNode* p_nextEdge;
EdgeWeightDataType infoOfEdge;
}EdgeNode;
typedef struct GraphVertexNode {
VertexDataType val;
EdgeNode* p_firstAdjEdge;
}VertexNode;
typedef struct {
VertexNode* setsOfVertex;
int vertexNums;
int edgeNums;
int* visited;
}ALGraph;
void InitALGraph(ALGraph* graph);
void InsertVertex(ALGraph* graph, VertexDataType val);
void InsertEdge(ALGraph* graph, VertexDataType val_1, VertexDataType val_2);
int SearchVertexRetIndex(ALGraph* graph, VertexDataType val);
void showALGraph(ALGraph* graph);
void DFS_AL(ALGraph* graph, int StartVertexIndex);
int main() {
ALGraph graph;
InitALGraph(&graph);
InsertVertex(&graph, 1);
InsertVertex(&graph, 2);
InsertVertex(&graph, 3);
InsertVertex(&graph, 4);
InsertVertex(&graph, 5);
InsertVertex(&graph, 6);
InsertVertex(&graph, 7);
InsertEdge(&graph, 1, 3);
InsertEdge(&graph, 1, 2);
InsertEdge(&graph, 3, 2);
InsertEdge(&graph, 2, 5);
InsertEdge(&graph, 2, 4);
InsertEdge(&graph, 5, 7);
InsertEdge(&graph, 5, 6);
showALGraph(&graph);
printf("无向连通图的优先深度遍历结果:\n");
DFS_AL(&graph, 0);
return 0;
}
void InitALGraph(ALGraph* graph) {
graph->setsOfVertex = (VertexNode*)malloc(sizeof(VertexNode) * MAX_SIZEOFVERTEX );
graph->edgeNums = 0;
graph->vertexNums = 0;
graph->visited = (int*)malloc(sizeof(int) * MAX_SIZEOFVERTEX );
}
void InsertVertex(ALGraph* graph, VertexDataType val) {
graph->setsOfVertex[graph->vertexNums].val = val;
graph->setsOfVertex[graph->vertexNums].p_firstAdjEdge = NULL;
graph->visited[graph->vertexNums] = 0;
graph->vertexNums++;
}
void InsertEdge(ALGraph* graph, VertexDataType val_1, VertexDataType val_2) {
int v1Index = 0;
int v2Index = 0;
v1Index = SearchVertexRetIndex(graph, val_1);
v2Index = SearchVertexRetIndex(graph, val_2);
EdgeNode* newEdgeNode0 = (EdgeNode*)malloc(sizeof(EdgeNode));
if (newEdgeNode0 == NULL) {
exit(0);
}
newEdgeNode0->adjVertexIndex = v2Index;
newEdgeNode0->p_nextEdge = graph->setsOfVertex[v1Index].p_firstAdjEdge;
graph->setsOfVertex[v1Index].p_firstAdjEdge = newEdgeNode0;
EdgeNode* newEdgeNode1 = (EdgeNode*)malloc(sizeof(EdgeNode));
if (newEdgeNode1 == NULL) {
exit(0);
}
newEdgeNode1->adjVertexIndex = v1Index;
newEdgeNode1->p_nextEdge = graph->setsOfVertex[v2Index].p_firstAdjEdge;
graph->setsOfVertex[v2Index].p_firstAdjEdge = newEdgeNode1;
graph->edgeNums++;
}
int SearchVertexRetIndex(ALGraph* graph, VertexDataType val) {
for (int i = 0; i < graph->vertexNums; i++) {
if (graph->setsOfVertex[i].val == val) {
return i;
}
}
return -1;
}
void showALGraph(ALGraph* graph) {
EdgeNode* cur = NULL;
printf("当前图的邻接表的状态:\n");
for (int i = 0; i < graph->vertexNums; i++) {
printf("Adjacency List[%d]: %d => ", i, graph->setsOfVertex[i].val);
cur = graph->setsOfVertex[i].p_firstAdjEdge;
while (cur != NULL) {
printf("%d->", graph->setsOfVertex[cur->adjVertexIndex].val);
cur = cur->p_nextEdge;
}
printf("NULL\n");
}
}
void DFS_AL(ALGraph* graph, int startVertexIndex) {
printf("%d ", graph->setsOfVertex[startVertexIndex].val);
graph->visited[startVertexIndex] = 1;
EdgeNode* cur = graph->setsOfVertex[startVertexIndex].p_firstAdjEdge;
while (cur) {
int adjVertexIndex = cur->adjVertexIndex;
if (graph->visited[adjVertexIndex] == 0) {
DFS_AL(graph, adjVertexIndex);
}
cur = cur->p_nextEdge;
}
}
?2.2?图的广度优先遍历
#define _CRT_SECURE_NO_WARNINGS 1
#define MAX_VERTEXNUMS 70
#include <stdio.h>
#include <stdlib.h>
typedef int VertexDataType;
typedef int EdgeWeightDataType;
typedef struct GraphEdgeNode {
int adjVertexIndex;
struct GraphEdgeNode* p_nextEdge;
EdgeWeightDataType infoOfEdge;
}EdgeNode;
typedef struct GraphVertexNode {
VertexDataType val;
EdgeNode* p_firstAdjEdge;
}VertexNode;
typedef struct {
VertexNode* setsOfVertex;
int vertexNums;
int edgeNums;
int* visited;
}ALGraph;
typedef struct LQueueNode {
VertexNode* val;
struct LQueueNode* next;
}LQueueNode;
typedef struct {
LQueueNode* head;
LQueueNode* tail;
}LQueue;
void InitALGraph(ALGraph* graph);
void InsertVertex(ALGraph* graph, VertexDataType val);
void InsertEdge(ALGraph* graph, VertexDataType val_1, VertexDataType val_2);
int SearchVertexRetIndex(ALGraph* graph, VertexDataType val);
void showALGraph(ALGraph* graph);
void GraphBFS_AL(ALGraph* graph, int startVertexIndex);
void InitLQueue(LQueue* queue);
void push(LQueue* queue, VertexNode* val);
void pop(LQueue* queue, VertexNode* retVertex);
int QueueEmpty(LQueue* queue);
int main() {
ALGraph graph;
InitALGraph(&graph);
InsertVertex(&graph, 1);
InsertVertex(&graph, 2);
InsertVertex(&graph, 3);
InsertVertex(&graph, 4);
InsertVertex(&graph, 5);
InsertVertex(&graph, 6);
InsertVertex(&graph, 7);
InsertEdge(&graph, 1, 3);
InsertEdge(&graph, 1, 2);
InsertEdge(&graph, 3, 2);
InsertEdge(&graph, 2, 5);
InsertEdge(&graph, 2, 4);
InsertEdge(&graph, 5, 7);
InsertEdge(&graph, 5, 6);
showALGraph(&graph);
GraphBFS_AL(&graph, 0);
GraphBFS_AL(&graph, 1);
GraphBFS_AL(&graph, 5);
GraphBFS_AL(&graph, 3);
GraphBFS_AL(&graph, 2);
return 0;
}
void InitLQueue(LQueue* queue) {
queue->head = (LQueueNode*)malloc(sizeof(LQueueNode));
if (queue->head == NULL) {
exit(0);
}
queue->head->next = NULL;
queue->tail = queue->head;
}
void push(LQueue* queue, VertexNode* val) {
LQueueNode* newNode = (LQueueNode*)malloc(sizeof(LQueueNode));
if (newNode == NULL) {
exit(0);
}
newNode->val = val;
newNode->next = NULL;
queue->tail->next = newNode;
queue->tail = newNode;
}
void pop(LQueue* queue, VertexNode* retVertex) {
if (QueueEmpty(queue)) {
exit(0);
}
LQueueNode* pHead = queue->head->next;
*retVertex = *(pHead->val);
queue->head->next = pHead->next;
if (queue->tail == pHead) {
queue->tail = queue->head;
}
free(pHead);
}
int QueueEmpty(LQueue* queue) {
if (queue->head == queue->tail) {
return 1;
}
return 0;
}
void InitALGraph(ALGraph* graph) {
graph->setsOfVertex = (VertexNode*)malloc(sizeof(VertexNode) * MAX_VERTEXNUMS);
graph->edgeNums = 0;
graph->vertexNums = 0;
graph->visited = (int*)malloc(sizeof(int) * MAX_VERTEXNUMS);
}
void InsertVertex(ALGraph* graph, VertexDataType val) {
graph->setsOfVertex[graph->vertexNums].val = val;
graph->setsOfVertex[graph->vertexNums].p_firstAdjEdge = NULL;
graph->visited[graph->vertexNums] = 0;
graph->vertexNums++;
}
int SearchVertexRetIndex(ALGraph* graph, VertexDataType val) {
for (int i = 0; i < graph->vertexNums; i++) {
if (graph->setsOfVertex[i].val == val) {
return i;
}
}
return -1;
}
void InsertEdge(ALGraph* graph, VertexDataType val_1, VertexDataType val_2) {
int v1Index = 0;
int v2Index = 0;
v1Index = SearchVertexRetIndex(graph, val_1);
v2Index = SearchVertexRetIndex(graph, val_2);
EdgeNode* newEdgeNode0 = (EdgeNode*)malloc(sizeof(EdgeNode));
if (newEdgeNode0 == NULL) {
exit(0);
}
newEdgeNode0->adjVertexIndex = v2Index;
newEdgeNode0->p_nextEdge = graph->setsOfVertex[v1Index].p_firstAdjEdge;
graph->setsOfVertex[v1Index].p_firstAdjEdge = newEdgeNode0;
EdgeNode* newEdgeNode1 = (EdgeNode*)malloc(sizeof(EdgeNode));
if (newEdgeNode1 == NULL) {
exit(0);
}
newEdgeNode1->adjVertexIndex = v1Index;
newEdgeNode1->p_nextEdge = graph->setsOfVertex[v2Index].p_firstAdjEdge;
graph->setsOfVertex[v2Index].p_firstAdjEdge = newEdgeNode1;
graph->edgeNums++;
}
void showALGraph(ALGraph* graph) {
EdgeNode* cur = NULL;
printf("当前图的邻接表的状态:\n");
for (int i = 0; i < graph->vertexNums; i++) {
printf("Adjacency List[%d]: %d => ", i, graph->setsOfVertex[i].val);
cur = graph->setsOfVertex[i].p_firstAdjEdge;
while (cur != NULL) {
printf("%d->", graph->setsOfVertex[cur->adjVertexIndex].val);
cur = cur->p_nextEdge;
}
printf("NULL\n");
}
}
void GraphBFS_AL(ALGraph* graph, int startVertexIndex) {
memset(graph->visited, 0, MAX_VERTEXNUMS);
printf("\n从值为%d的顶点开始广度优先遍历得结果为:", graph->setsOfVertex[startVertexIndex].val);
LQueue queue;
InitLQueue(&queue);
push(&queue, &(graph->setsOfVertex[startVertexIndex].val));
VertexNode* retVal = (VertexNode*)malloc(sizeof(VertexNode));
EdgeNode* cur = (EdgeNode*)malloc(sizeof(EdgeNode));
while (!QueueEmpty(&queue)) {
pop(&queue, retVal);
if (retVal == NULL) {
exit(0);
}
cur = retVal->p_firstAdjEdge;
if (graph->visited[SearchVertexRetIndex(graph, retVal->val)] == 0) {
printf("%d ", retVal->val);
graph->visited[SearchVertexRetIndex(graph, retVal->val)] = 1;
}
while (cur) {
if (graph->visited[cur->adjVertexIndex] == 0) {
push(&queue, &(graph->setsOfVertex[cur->adjVertexIndex].val));
}
cur = cur->p_nextEdge;
}
}
free((&queue)->head);
}
?2.3?图最小生成树的Prime算法
#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include <stdlib.h>
typedef char VertexDataType;
typedef int EdgeWeightDataType;
typedef struct {
VertexDataType lowAdjVex;
EdgeWeightDataType lowEdgeWeight;
}closedge;
typedef struct {
VertexDataType* setsOfVertex;
EdgeWeightDataType** AdjacencyMatrix;
closedge* flag;
int numsOfVertex;
int numsOfEdge;
int MaxSizeCnt;
}MatrixGraph;
void InitGraph(MatrixGraph* Graph, int n);
void InsertVertex(MatrixGraph* Graph, VertexDataType vertex);
void InsertEdge(MatrixGraph* Graph, int v1, int v2, EdgeWeightDataType weight);
void ShowMatrix(MatrixGraph* Graph);
int searchVerIndex(MatrixGraph* Graph, VertexDataType verValue);
int Min(MatrixGraph* Graph);
void MST_Prim(MatrixGraph* Graph, VertexDataType vertexValue);
int main() {
MatrixGraph graph;
InitGraph(&graph, 6);
InsertVertex(&graph, 'a');
InsertVertex(&graph, 'b');
InsertVertex(&graph, 'c');
InsertVertex(&graph, 'd');
InsertVertex(&graph, 'e');
InsertVertex(&graph, 'f');
InsertEdge(&graph, 0, 5, 13);
InsertEdge(&graph, 0, 1, 9);
InsertEdge(&graph, 0, 2, 7);
InsertEdge(&graph, 0, 3, 8);
InsertEdge(&graph, 1, 5, 17);
InsertEdge(&graph, 1, 4, 12);
InsertEdge(&graph, 4, 5, 18);
InsertEdge(&graph, 2, 4, 10);
InsertEdge(&graph, 2, 3, 5);
InsertEdge(&graph, 3, 4, 24);
MST_Prim(&graph, 'c');
return 0;
}
void InitGraph(MatrixGraph* Graph, int n) {
Graph->setsOfVertex = (VertexDataType*)malloc(sizeof(VertexDataType) * n);
Graph->AdjacencyMatrix = (EdgeWeightDataType**)malloc(sizeof(int*) * n);
for (int i = 0; i < n; i++) {
Graph->AdjacencyMatrix[i] = (EdgeWeightDataType*)malloc(sizeof(EdgeWeightDataType) * n);
}
if (Graph->AdjacencyMatrix == NULL) {
exit(0);
}
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
Graph->AdjacencyMatrix[i][j] = 2147483647;
}
}
Graph->flag = (closedge*)malloc(sizeof(closedge) * n);
Graph->numsOfEdge = 0;
Graph->numsOfVertex = 0;
Graph->MaxSizeCnt = n;
}
void InsertVertex(MatrixGraph* Graph, VertexDataType vertex) {
int i = Graph->numsOfVertex;
if (i < Graph->MaxSizeCnt) {
Graph->setsOfVertex[i] = vertex;
(Graph->numsOfVertex)++;
}
}
void InsertEdge(MatrixGraph* Graph, int v1, int v2, EdgeWeightDataType weight) {
Graph->AdjacencyMatrix[v1][v2] = weight;
Graph->AdjacencyMatrix[v2][v1] = weight;
Graph->numsOfEdge++;
}
void ShowMatrix(MatrixGraph* Graph) {
printf("\n\n\n");
for (int i = 0; i < Graph->numsOfVertex; i++) {
printf(" [ ");
for (int j = 0; j < Graph->numsOfVertex; j++) {
if (j != Graph->numsOfVertex - 1) {
printf("%02d ", Graph->AdjacencyMatrix[i][j]);
}
else {
printf("%02d ", Graph->AdjacencyMatrix[i][j]);
}
}
printf("]");
printf("\n");
}
}
int searchVerIndex(MatrixGraph* Graph, VertexDataType verValue) {
for (int i = 0; i < Graph->numsOfVertex; i++) {
if (verValue == Graph->setsOfVertex[i]) {
return i;
}
}
return -1;
}
int Min(MatrixGraph* Graph) {
int min = 100, minIndex = 0;
for (int i = 0; i < Graph->numsOfVertex; i++) {
if ((Graph->flag[i].lowEdgeWeight != 0) && (Graph->flag[i].lowEdgeWeight < min)) {
min = Graph->flag[i].lowEdgeWeight;
minIndex = i;
}
}
return minIndex;
}
void MST_Prim(MatrixGraph* Graph, VertexDataType vertexValue) {
MatrixGraph retGraph;
InitGraph(&retGraph, Graph->numsOfVertex);
int initIndex = searchVerIndex(Graph, vertexValue);
for (int i = 0; i < Graph->numsOfVertex; i++) {
InsertVertex(&retGraph, Graph->setsOfVertex[i]);
if (i == initIndex) {
Graph->flag[i].lowEdgeWeight = 0;
}
else {
Graph->flag[i].lowAdjVex = vertexValue;
Graph->flag[i].lowEdgeWeight = Graph->AdjacencyMatrix[initIndex][i];
}
}
int weights = 0;
for (int i = 1; i < Graph->numsOfVertex; i++) {
int minWeightEdgeIndex = Min(Graph);
VertexDataType vertex_0 = Graph->flag[minWeightEdgeIndex].lowAdjVex;
VertexDataType vertex_1 = Graph->setsOfVertex[minWeightEdgeIndex];
int i_1 = searchVerIndex(Graph, vertex_0);
int i_2 = searchVerIndex(Graph, vertex_1);
InsertEdge(&retGraph, i_1, i_2, Graph->flag[minWeightEdgeIndex].lowEdgeWeight);
weights += Graph->flag[minWeightEdgeIndex].lowEdgeWeight;
printf("The %d times two vertices selected are:%c %c\n", i, vertex_0, vertex_1);
(Graph->flag)[minWeightEdgeIndex].lowEdgeWeight = 0;
for (int i = 0; i < Graph->numsOfVertex; i++) {
int edge_0 = Graph->AdjacencyMatrix[minWeightEdgeIndex][i];
int edge_1 = Graph->flag[i].lowEdgeWeight;
if (edge_0 < edge_1) {
(Graph->flag)[i].lowAdjVex = vertex_1;
(Graph->flag)[i].lowEdgeWeight = edge_0;
}
}
}
printf("\n");
printf("MST generated with Prim is:\n");
for (int i = 0; i < retGraph.numsOfVertex; i++) {
for (int j = 0; j < retGraph.numsOfVertex; j++) {
if (j == 0) {
printf("\t [");
}
if (retGraph.AdjacencyMatrix[i][j] == 2147483647) {
printf("00 ");
}
else {
printf("%02d ", retGraph.AdjacencyMatrix[i][j]);
}
if (j == retGraph.numsOfVertex - 1) {
printf("]");
}
}
printf("\n");
}
printf("Minimum Cost Spanning is: %d", weights);
}
?2.4?最小生成树的Kruskal算法
#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include <stdlib.h>
typedef char VertexDataType;
typedef int EdgeWeightDataType;
typedef struct {
VertexDataType head;
VertexDataType tail;
EdgeWeightDataType weight;
}Edge;
typedef struct {
VertexDataType* setsOfVertex;
EdgeWeightDataType** AdjacencyMatrix;
Edge* Edges;
int* vertexSet;
int numsOfVertex;
int numsOfEdge;
int MaxSizeCnt;
}MatrixGraph;
void InitGraph(MatrixGraph* Graph, int n);
void InsertVertex(MatrixGraph* Graph, VertexDataType vertex);
void InsertEdge(MatrixGraph* Graph, int v1, int v2, EdgeWeightDataType weight);
void ShowMatrix(MatrixGraph* Graph);
int searchVerIndex(MatrixGraph* Graph, VertexDataType verValue);
void sort_Edges(MatrixGraph* Graph);
void Kruskal_MSTRelize(MatrixGraph* Graph);
int main() {
MatrixGraph graph;
InitGraph(&graph, 6);
InsertVertex(&graph, 'a');
InsertVertex(&graph, 'b');
InsertVertex(&graph, 'c');
InsertVertex(&graph, 'd');
InsertVertex(&graph, 'e');
InsertVertex(&graph, 'f');
InsertEdge(&graph, 0, 5, 13);
InsertEdge(&graph, 0, 1, 9);
InsertEdge(&graph, 0, 2, 7);
InsertEdge(&graph, 0, 3, 8);
InsertEdge(&graph, 1, 5, 17);
InsertEdge(&graph, 1, 4, 12);
InsertEdge(&graph, 4, 5, 18);
InsertEdge(&graph, 2, 4, 10);
InsertEdge(&graph, 2, 3, 5);
InsertEdge(&graph, 3, 4, 24);
Kruskal_MSTRelize(&graph);
return 0;
}
void InitGraph(MatrixGraph* Graph, int n) {
Graph->setsOfVertex = (VertexDataType*)malloc(sizeof(VertexDataType) * n);
Graph->AdjacencyMatrix = (EdgeWeightDataType**)malloc(sizeof(int*) * n);
for (int i = 0; i < n; i++) {
Graph->AdjacencyMatrix[i] = (EdgeWeightDataType*)malloc(sizeof(EdgeWeightDataType) * n);
}
if (Graph->AdjacencyMatrix == NULL) {
exit(0);
}
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
Graph->AdjacencyMatrix[i][j] = 2147483647;
}
}
Graph->vertexSet = (int*)malloc(sizeof(int) * n);
Graph->Edges = (Edge*)malloc(sizeof(Edge) * n * (n - 1) / 2);
Graph->numsOfEdge = 0;
Graph->numsOfVertex = 0;
Graph->MaxSizeCnt = n;
}
void InsertVertex(MatrixGraph* Graph, VertexDataType vertex) {
int i = Graph->numsOfVertex;
Graph->setsOfVertex[i] = vertex;
Graph->vertexSet[i] = i;
(Graph->numsOfVertex)++;
}
void InsertEdge(MatrixGraph* Graph, int v1, int v2, EdgeWeightDataType weight) {
Graph->AdjacencyMatrix[v1][v2] = weight;
Graph->AdjacencyMatrix[v2][v1] = weight;
Graph->Edges[Graph->numsOfEdge].weight = weight;
Graph->Edges[Graph->numsOfEdge].head = Graph->setsOfVertex[v1];
Graph->Edges[Graph->numsOfEdge].tail = Graph->setsOfVertex[v2];
Graph->numsOfEdge++;
}
void ShowMatrix(MatrixGraph* Graph) {
printf("\n\n\n");
for (int i = 0; i < Graph->numsOfVertex; i++) {
printf(" [");
for (int j = 0; j < Graph->numsOfVertex; j++) {
if (j == 0) {
if (Graph->AdjacencyMatrix[i][j] == 2147483647) printf("00 ");
else printf("%02d ", Graph->AdjacencyMatrix[i][j]);
continue;
}
if (j != Graph->numsOfVertex - 1) {
if (Graph->AdjacencyMatrix[i][j] == 2147483647) printf("00 ");
else printf("%02d ", Graph->AdjacencyMatrix[i][j]);
}
else {
if (Graph->AdjacencyMatrix[i][j] == 2147483647) printf("00");
else printf("%02d", Graph->AdjacencyMatrix[i][j]);
}
}
printf("]");
printf("\n");
}
}
int searchVerIndex(MatrixGraph* Graph, VertexDataType verValue) {
for (int i = 0; i < Graph->numsOfVertex; i++) {
if (verValue == Graph->setsOfVertex[i]) {
return i;
}
}
return -1;
}
void sort_Edges(MatrixGraph* Graph) {
for (int i = 0; i < Graph->numsOfEdge - 1; i++) {
for (int j = 0; j < Graph->numsOfEdge - i - 1; j++) {
if (Graph->Edges[j].weight > Graph->Edges[j + 1].weight) {
Edge tmp = Graph->Edges[j];
Graph->Edges[j] = Graph->Edges[j + 1];
Graph->Edges[j + 1] = tmp;
}
}
}
}
void Kruskal_MSTRelize(MatrixGraph* Graph) {
sort_Edges(Graph);
MatrixGraph KruskalMST;
InitGraph(&KruskalMST, Graph->numsOfVertex);
for (int i = 0; i < Graph->numsOfVertex; i++)
InsertVertex(&KruskalMST, Graph->setsOfVertex[i]);
int cnt = 1;
for (int i = 0; i < Graph->numsOfEdge; i++) {
int v1 = searchVerIndex(Graph, Graph->Edges[i].head);
int v2 = searchVerIndex(Graph, Graph->Edges[i].tail);
int v1_Adj = Graph->vertexSet[v1];
int v2_Adj = Graph->vertexSet[v2];
if (v1_Adj != v2_Adj) {
InsertEdge(&KruskalMST, v1, v2, Graph->Edges[i].weight);
printf("The two vertices of the %d selected edge are: %c %c\n", cnt++ , Graph->Edges[i].head, Graph->Edges[i].tail);
for (int j = 0; j < Graph->numsOfVertex; j++) {
if (Graph->vertexSet[j] == v2_Adj) Graph->vertexSet[j] = v1_Adj;
}
}
}
printf("\n\nThe MST generated with the Kruskal algorithm is:\n");
ShowMatrix(&KruskalMST);
}
?2.5?最短路径(SSSP)的Dijkstra算法
#define _CRT_SECURE_NO_WARNINGS 1
#define Override_MAX_INT 20020427
#include <stdio.h>
#include <stdlib.h>
typedef int EdgeWeightDataType;
typedef struct {
int* setsOfVertex;
EdgeWeightDataType** AdjacencyMatrix;
int* flag_IsSpOfVertex;
int* indexOfForward;
int* spOfVertex;
int numsOfVertex;
int numsOfEdge;
int MaxSizeCnt;
}MatrixGraph;
void InitGraph(MatrixGraph* Graph, int n);
void InsertVertex(MatrixGraph* Graph, int vertex);
void InsertEdge(MatrixGraph* Graph, int v1, int v2, EdgeWeightDataType weight);
void ShowMatrix(MatrixGraph* Graph);
void SSSP_DIJ(MatrixGraph* Graph, int v0);
int main() {
MatrixGraph graph;
InitGraph(&graph, 7);
InsertVertex(&graph, 1);
InsertVertex(&graph, 2);
InsertVertex(&graph, 3);
InsertVertex(&graph, 4);
InsertVertex(&graph, 5);
InsertVertex(&graph, 6);
InsertVertex(&graph, 7);
InsertEdge(&graph, 0, 1, 13);
InsertEdge(&graph, 0, 2, 8);
InsertEdge(&graph, 0, 4, 30);
InsertEdge(&graph, 0, 6, 32);
InsertEdge(&graph, 1, 6, 7);
InsertEdge(&graph, 1, 5, 9);
InsertEdge(&graph, 2, 3, 5);
InsertEdge(&graph, 3, 4, 6);
InsertEdge(&graph, 4, 5, 2);
InsertEdge(&graph, 5, 6, 17);
SSSP_DIJ(&graph, 0);
return 0;
}
void InitGraph(MatrixGraph* Graph, int n) {
Graph->setsOfVertex = (int*)malloc(sizeof(int) * n);
memset(Graph->setsOfVertex, 0, sizeof(int) * n);
Graph->AdjacencyMatrix = (EdgeWeightDataType**)malloc(sizeof(int*) * n);
for (int i = 0; i < n; i++) {
Graph->AdjacencyMatrix[i] = (EdgeWeightDataType*)malloc(sizeof(EdgeWeightDataType) * n);
}
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
Graph->AdjacencyMatrix[i][j] = Override_MAX_INT;
}
}
Graph->flag_IsSpOfVertex = (int*)malloc(sizeof(int) * n);
memset(Graph->flag_IsSpOfVertex, 0, sizeof(int) * n);
Graph->indexOfForward = (int*)malloc(sizeof(int) * n);
memset(Graph->indexOfForward, -1, sizeof(int) * n);
Graph->spOfVertex = (int*)malloc(sizeof(int) * n);
memset(Graph->spOfVertex, Override_MAX_INT, sizeof(int) * n);
Graph->numsOfEdge = 0;
Graph->numsOfVertex = 0;
Graph->MaxSizeCnt = n;
}
void InsertVertex(MatrixGraph* Graph, int vertex) {
if (Graph->numsOfEdge >= Graph->MaxSizeCnt) exit(0);
int i = Graph->numsOfVertex;
Graph->setsOfVertex[i] = vertex;
Graph->numsOfVertex++;
}
void InsertEdge(MatrixGraph* Graph, int v1, int v2, EdgeWeightDataType weight) {
Graph->AdjacencyMatrix[v1][v2] = weight;
Graph->numsOfEdge++;
}
void ShowMatrix(MatrixGraph* Graph) {
printf("\n\n\n");
for (int i = 0; i < Graph->numsOfVertex; i++) {
printf(" [");
for (int j = 0; j < Graph->numsOfVertex; j++) {
if (j != Graph->numsOfVertex - 1) {
if(Graph->AdjacencyMatrix[i][j] == Override_MAX_INT) printf("00 ");
else printf("%02d ", Graph->AdjacencyMatrix[i][j]);
}
else {
if (Graph->AdjacencyMatrix[i][j] == Override_MAX_INT) printf("00");
else printf("%02d", Graph->AdjacencyMatrix[i][j]);
}
}
printf("]");
printf("\n");
}
}
void SSSP_DIJ(MatrixGraph* Graph, int v0) {
int n = Graph->numsOfVertex;
for (int i = 0; i < n; i++) {
Graph->flag_IsSpOfVertex[i] = 0;
Graph->spOfVertex[i] = Graph->AdjacencyMatrix[v0][i];
if (Graph->spOfVertex[i] < Override_MAX_INT) Graph->indexOfForward[i] = v0;
else Graph->indexOfForward[i] = -1;
}
Graph->flag_IsSpOfVertex[v0] = 1;
Graph->spOfVertex[v0] = 0;
for (int i = 0; i < n; i++) {
int minWeightEdgeDesIndex = 0;
int min_FLag = Override_MAX_INT;
for (int j = 0; j < n; j++) {
if (!Graph->flag_IsSpOfVertex[j] && Graph->spOfVertex[j] < min_FLag) {
minWeightEdgeDesIndex = j;
min_FLag = Graph->spOfVertex[j];
}
}
Graph->flag_IsSpOfVertex[minWeightEdgeDesIndex] = 1;
for (int j = 0; j < n; j++) {
int flag = (Graph->spOfVertex[minWeightEdgeDesIndex] + Graph->AdjacencyMatrix[minWeightEdgeDesIndex][j]) < Graph->spOfVertex[j];
if (!Graph->flag_IsSpOfVertex[j] && flag) {
Graph->spOfVertex[j] = Graph->spOfVertex[minWeightEdgeDesIndex] +
Graph->AdjacencyMatrix[minWeightEdgeDesIndex][j];
Graph->indexOfForward[j] = minWeightEdgeDesIndex;
}
}
}
for (int i = 0; i < n; i++) {
if (i == v0) continue;
printf("源点%d到顶点%d的最短路径为:%02d. 所选择的路径为:", Graph->setsOfVertex[i], Graph->setsOfVertex[v0],
Graph->spOfVertex[i]);
int l = i;
printf("( %d", Graph->setsOfVertex[l]);
while (l) {
l = Graph->indexOfForward[l];
printf(", %d", Graph->setsOfVertex[l]);
}
printf(" )\n");
}
}
?2.6?AVO-网的拓扑排序算法
#define _CRT_SECURE_NO_WARNINGS 1
#define MAX_SIZEOFVERTEX 70
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef char VertexDataType;
typedef int EdgeWeightDataType;
typedef struct GraphEdgeNode {
int adjVertexIndex;
struct GraphEdgeNode* p_nextEdge;
EdgeWeightDataType infoOfEdge;
}EdgeNode;
typedef struct GraphVertexNode {
VertexDataType* val;
EdgeNode* p_firstAdjEdge;
}VertexNode;
typedef struct {
VertexNode* setsOfVertex;
int vertexNums;
int edgeNums;
int* indegree;
int* topo;
}ALGraph;
typedef struct SqStack {
VertexNode* bottom;
VertexNode* top;
int capacityOfSqStack;
}SqStack;
void BuildALGraph(ALGraph* graph);
int SearchVertexRetIndex(ALGraph* graph, VertexDataType* val);
void showALGraph(ALGraph* graph);
void Topo_sort(ALGraph* graph);
void insertVertex(ALGraph* graph, VertexDataType* val);
void insertEdge(ALGraph* graph, VertexDataType* from_Vertex, VertexDataType* to_Vertex, EdgeWeightDataType weight);
void SqStackInit(SqStack* s);
void SqStackPushBack(SqStack* s, VertexNode x);
void SqStackPopBack(SqStack* s, VertexNode* retTopElem);
int SqStackEmpty(SqStack* s);
int main() {
ALGraph graph;
BuildALGraph(&graph);
insertVertex(&graph, "C1");
insertVertex(&graph, "C2");
insertVertex(&graph, "C3");
insertVertex(&graph, "C4");
insertVertex(&graph, "C5");
insertVertex(&graph, "C6");
insertVertex(&graph, "C7");
insertVertex(&graph, "C8");
insertVertex(&graph, "C9");
insertVertex(&graph, "C10");
insertVertex(&graph, "C11");
insertVertex(&graph, "C12");
insertEdge(&graph, "C1", "C4", 1);
insertEdge(&graph, "C1", "C2", 1);
insertEdge(&graph, "C1", "C3", 1);
insertEdge(&graph, "C1", "C12", 1);
insertEdge(&graph, "C2", "C3", 1);
insertEdge(&graph, "C3", "C5", 1);
insertEdge(&graph, "C3", "C7", 1);
insertEdge(&graph, "C3", "C8", 1);
insertEdge(&graph, "C4", "C5", 1);
insertEdge(&graph, "C5", "C7", 1);
insertEdge(&graph, "C9", "C12", 1);
insertEdge(&graph, "C9", "C10", 1);
insertEdge(&graph, "C9", "C11", 1);
insertEdge(&graph, "C10", "C12", 1);
insertEdge(&graph, "C11", "C6", 1);
insertEdge(&graph, "C6", "C8", 1);
showALGraph(&graph);
Topo_sort(&graph);
return 0;
}
void BuildALGraph(ALGraph* graph) {
graph->setsOfVertex = (VertexNode*)malloc(sizeof(VertexNode) * MAX_SIZEOFVERTEX);
graph->topo = (int*)malloc(sizeof(int) * MAX_SIZEOFVERTEX);
graph->indegree = (int*)malloc(sizeof(int) * MAX_SIZEOFVERTEX);
memset(graph->indegree, 0, sizeof(int) * MAX_SIZEOFVERTEX);
memset(graph->topo, 0, sizeof(int) * MAX_SIZEOFVERTEX);
graph->edgeNums = 0;
graph->vertexNums = 0;
}
int SearchVertexRetIndex(ALGraph* graph, VertexDataType* val) {
for (int i = 0; i < graph->vertexNums; i++) {
if (!strcmp(graph->setsOfVertex[i].val, val)) {
return i;
}
}
return -1;
}
void showALGraph(ALGraph* graph) {
EdgeNode* cur = NULL;
printf("AOV-网的邻接表:\n\n");
for (int i = 0; i < graph->vertexNums; i++) {
printf(" %s->", graph->setsOfVertex[i].val);
cur = graph->setsOfVertex[i].p_firstAdjEdge;
while (cur != NULL) {
printf("%s->", graph->setsOfVertex[cur->adjVertexIndex].val);
cur = cur->p_nextEdge;
}
printf("NULL\n");
}
printf("\n\n");
}
void insertVertex(ALGraph* graph, VertexDataType* val){
int i = graph->vertexNums;
graph->setsOfVertex[i].val = val;
graph->setsOfVertex[i].p_firstAdjEdge = NULL;
graph->vertexNums++;
}
void insertEdge(ALGraph* graph, VertexDataType* from_Vertex, VertexDataType* to_Vertex, EdgeWeightDataType weight) {
VertexDataType* v1 = (VertexDataType*)malloc(sizeof(VertexDataType) * 3);
VertexDataType* v2 = (VertexDataType*)malloc(sizeof(VertexDataType) * 3);
int v1Index = 0; strcpy(v1, from_Vertex);
int v2Index = 0; strcpy(v2, to_Vertex);
v1Index = SearchVertexRetIndex(graph, v1);
v2Index = SearchVertexRetIndex(graph, v2);
EdgeNode* newEdgeNode0 = (EdgeNode*)malloc(sizeof(EdgeNode));
newEdgeNode0->adjVertexIndex = v2Index;
newEdgeNode0->infoOfEdge = weight;
newEdgeNode0->p_nextEdge = graph->setsOfVertex[v1Index].p_firstAdjEdge;
graph->setsOfVertex[v1Index].p_firstAdjEdge = newEdgeNode0;
}
void Topo_sort(ALGraph* graph) {
for (int i = 0; i < graph->vertexNums; i++) {
EdgeNode* cur = graph->setsOfVertex[i].p_firstAdjEdge;
while (cur) {
int j = cur->adjVertexIndex;
graph->indegree[j]++;
cur = cur->p_nextEdge;
}
}
SqStack s;
SqStackInit(&s);
for (int i = 0; i < graph->vertexNums; i++) {
if (!graph->indegree[i]) {
SqStackPushBack(&s, graph->setsOfVertex[i]);
}
}
int cnt_inputed_Vertex = 0;
while (!SqStackEmpty(&s)) {
VertexNode top_Vertex;
SqStackPopBack(&s, &top_Vertex);
int top_Vertex_index = SearchVertexRetIndex(graph, top_Vertex.val);
graph->topo[cnt_inputed_Vertex] = top_Vertex_index;
cnt_inputed_Vertex++;
EdgeNode* p_fristAdjEdgeOfTop_vertex = top_Vertex.p_firstAdjEdge;
while (p_fristAdjEdgeOfTop_vertex) {
int indexOfAdjVertex = p_fristAdjEdgeOfTop_vertex->adjVertexIndex;
graph->indegree[indexOfAdjVertex]--;
if (graph->indegree[indexOfAdjVertex] == 0) {
SqStackPushBack(&s, graph->setsOfVertex[indexOfAdjVertex]);
}
p_fristAdjEdgeOfTop_vertex = p_fristAdjEdgeOfTop_vertex->p_nextEdge;
}
}
if (cnt_inputed_Vertex < graph->vertexNums) {
printf("AOV-图中有环,无法进行拓扑排序\n");
}
else {
printf("AOV-图的拓扑排序的其中一种为:\n");
for (int i = 0; i < graph->vertexNums; i++) {
printf("%s ", graph->setsOfVertex[graph->topo[i]]);
}
}
}
void SqStackInit(SqStack* s) {
s->bottom = (VertexNode*)malloc(sizeof(VertexNode) * 70);
if (!s->bottom) exit(0);
s->top = s->bottom;
s->capacityOfSqStack = 70;
}
void SqStackPushBack(SqStack* s, VertexNode x) {
if (s->top - s->bottom == 70) {
exit(0);
}
*(s->top) = x;
s->top++;
}
void SqStackPopBack(SqStack* s, VertexNode* retTopElem) {
if (SqStackEmpty(s)) exit(0);
*retTopElem = *(s->top - 1);
s->top--;
}
int SqStackEmpty(SqStack* s) {
if (s->bottom == s->top) return 1;
return 0;
}
?2.7?AOE-网的关键路径算法
#define _CRT_SECURE_NO_WARNINGS 1
#define MAX_SIZEOFVERTEX 70
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef char VertexDataType;
typedef int EdgeWeightDataType;
typedef struct GraphEdgeNode {
int adjVertexIndex;
struct GraphEdgeNode* p_nextEdge;
EdgeWeightDataType infoOfEdge;
char* edgeTitle;
}EdgeNode;
typedef struct GraphVertexNode {
VertexDataType* val;
EdgeNode* p_firstAdjEdge;
}VertexNode;
typedef struct {
VertexNode* setsOfVertex;
int vertexNums;
int edgeNums;
int* indegree;
int* topo;
int* happen_earliest;
int* happen_late;
}ALGraph;
typedef struct SqStack {
VertexNode* bottom;
VertexNode* top;
int capacityOfSqStack;
}SqStack;
void BuildALGraph(ALGraph* graph);
int SearchVertexRetIndex(ALGraph* graph, VertexDataType* val);
void showALGraph(ALGraph* graph);
void Topo_sort(ALGraph* graph);
void CriticalPath(ALGraph* graph);
void insertVertex(ALGraph* graph, VertexDataType* val);
void insertEdge(ALGraph* graph, VertexDataType* from_Vertex, VertexDataType* to_Vertex, EdgeWeightDataType weight, char* edgeTitle);
void SqStackInit(SqStack* s);
void SqStackPushBack(SqStack* s, VertexNode x);
void SqStackPopBack(SqStack* s, VertexNode* retTopElem);
int SqStackEmpty(SqStack* s);
int main() {
ALGraph graph;
BuildALGraph(&graph);
insertVertex(&graph, "V0");
insertVertex(&graph, "V1");
insertVertex(&graph, "V2");
insertVertex(&graph, "V3");
insertVertex(&graph, "V4");
insertVertex(&graph, "V5");
insertVertex(&graph, "V6");
insertVertex(&graph, "V7");
insertVertex(&graph, "V8");
insertEdge(&graph, "V0", "V1", 6, "a1");
insertEdge(&graph, "V0", "V2", 4, "a2");
insertEdge(&graph, "V0", "V3", 5, "a3");
insertEdge(&graph, "V1", "V4", 1, "a4");
insertEdge(&graph, "V2", "V4", 1, "a5");
insertEdge(&graph, "V3", "V5", 2, "a6");
insertEdge(&graph, "V4", "V6", 9, "a7");
insertEdge(&graph, "V4", "V7", 7, "a8");
insertEdge(&graph, "V5", "V7", 4, "a9");
insertEdge(&graph, "V6", "V8", 2, "a10");
insertEdge(&graph, "V7", "V8", 4, "a11");
showALGraph(&graph);
CriticalPath(&graph);
return 0;
}
void BuildALGraph(ALGraph* graph) {
graph->setsOfVertex = (VertexNode*)malloc(sizeof(VertexNode) * MAX_SIZEOFVERTEX);
graph->topo = (int*)malloc(sizeof(int) * MAX_SIZEOFVERTEX);
graph->indegree = (int*)malloc(sizeof(int) * MAX_SIZEOFVERTEX);
graph->happen_late = (int*)malloc(sizeof(int) * MAX_SIZEOFVERTEX);
graph->happen_earliest = (int*)malloc(sizeof(int) * MAX_SIZEOFVERTEX);
for (int i = 0; i < MAX_SIZEOFVERTEX; i++) graph->topo[i] = 0;
for (int i = 0; i < MAX_SIZEOFVERTEX; i++) graph->indegree[i] = 0;
for (int i = 0; i < MAX_SIZEOFVERTEX; i++) graph->happen_earliest[i] = 0;
for (int i = 0; i < MAX_SIZEOFVERTEX; i++) graph->happen_late[i] = 0;
graph->edgeNums = 0;
graph->vertexNums = 0;
}
int SearchVertexRetIndex(ALGraph* graph, VertexDataType* val) {
for (int i = 0; i < graph->vertexNums; i++) {
if (!strcmp(graph->setsOfVertex[i].val, val)) {
return i;
}
}
return -1;
}
void showALGraph(ALGraph* graph) {
EdgeNode* cur = NULL;
printf("AOV-网的邻接表:\n\n");
for (int i = 0; i < graph->vertexNums; i++) {
printf(" %s -> ", graph->setsOfVertex[i].val);
cur = graph->setsOfVertex[i].p_firstAdjEdge;
while (cur != NULL) {
printf("%s -> ", graph->setsOfVertex[cur->adjVertexIndex].val);
cur = cur->p_nextEdge;
}
printf("NULL\n");
}
printf("\n\n");
}
void insertVertex(ALGraph* graph, VertexDataType* val) {
int i = graph->vertexNums;
graph->setsOfVertex[i].val = val;
graph->setsOfVertex[i].p_firstAdjEdge = NULL;
graph->vertexNums++;
}
void insertEdge(ALGraph* graph, VertexDataType* from_Vertex, VertexDataType* to_Vertex, EdgeWeightDataType weight, char* edgeTitle) {
VertexDataType* v1 = (VertexDataType*)malloc(sizeof(VertexDataType) * 3);
VertexDataType* v2 = (VertexDataType*)malloc(sizeof(VertexDataType) * 3);
int v1Index = 0; strcpy(v1, from_Vertex);
int v2Index = 0; strcpy(v2, to_Vertex);
v1Index = SearchVertexRetIndex(graph, v1);
v2Index = SearchVertexRetIndex(graph, v2);
EdgeNode* newEdgeNode0 = (EdgeNode*)malloc(sizeof(EdgeNode));
newEdgeNode0->adjVertexIndex = v2Index;
newEdgeNode0->infoOfEdge = weight;
newEdgeNode0->edgeTitle = edgeTitle;
newEdgeNode0->p_nextEdge = graph->setsOfVertex[v1Index].p_firstAdjEdge;
graph->setsOfVertex[v1Index].p_firstAdjEdge = newEdgeNode0;
}
void Topo_sort(ALGraph* graph) {
for (int i = 0; i < graph->vertexNums; i++) {
EdgeNode* cur = graph->setsOfVertex[i].p_firstAdjEdge;
while (cur) {
int j = cur->adjVertexIndex;
graph->indegree[j]++;
cur = cur->p_nextEdge;
}
}
SqStack s;
SqStackInit(&s);
for (int i = 0; i < graph->vertexNums; i++) {
if (!graph->indegree[i]) {
SqStackPushBack(&s, graph->setsOfVertex[i]);
}
}
int cnt_inputed_Vertex = 0;
while (!SqStackEmpty(&s)) {
VertexNode top_Vertex;
SqStackPopBack(&s, &top_Vertex);
int top_Vertex_index = SearchVertexRetIndex(graph, top_Vertex.val);
graph->topo[cnt_inputed_Vertex] = top_Vertex_index;
cnt_inputed_Vertex++;
EdgeNode* p_fristAdjEdgeOfTop_vertex = top_Vertex.p_firstAdjEdge;
while (p_fristAdjEdgeOfTop_vertex) {
int indexOfAdjVertex = p_fristAdjEdgeOfTop_vertex->adjVertexIndex;
graph->indegree[indexOfAdjVertex]--;
if (graph->indegree[indexOfAdjVertex] == 0) {
SqStackPushBack(&s, graph->setsOfVertex[indexOfAdjVertex]);
}
p_fristAdjEdgeOfTop_vertex = p_fristAdjEdgeOfTop_vertex->p_nextEdge;
}
}
if (cnt_inputed_Vertex < graph->vertexNums) {
printf("AOV-图中有环,无法进行拓扑排序\n");
exit(0);
}
else {
printf("AOV-图的拓扑排序的其中一种为:\n");
for (int i = 0; i < graph->vertexNums; i++) {
printf("%s ", graph->setsOfVertex[graph->topo[i]]);
}
printf("\n");
}
}
void CriticalPath(ALGraph* graph) {
Topo_sort(graph);
printf("\nAOE-网的关键路径为:\n");
int numsOfVertex = graph->vertexNums;
for (int i = 0; i < numsOfVertex; i++) {
graph->happen_earliest[i] = 0;
}
for (int i = 0; i < numsOfVertex; i++) {
int indexOfTopoList = graph->topo[i];
EdgeNode* cur = graph->setsOfVertex[indexOfTopoList].p_firstAdjEdge;
while (cur) {
int adjVer_Index = cur->adjVertexIndex;
if (graph->happen_earliest[adjVer_Index] < graph->happen_earliest[indexOfTopoList] + cur->infoOfEdge) {
graph->happen_earliest[adjVer_Index] = graph->happen_earliest[indexOfTopoList] + cur->infoOfEdge;
}
cur = cur->p_nextEdge;
}
}
for (int i = 0; i < numsOfVertex; i++) {
int late_times = graph->happen_earliest[numsOfVertex - 1];
graph->happen_late[i] = late_times;
}
for (int i = numsOfVertex - 1; i >= 0; i--) {
int indexOfTopoList = graph->topo[i];
EdgeNode* cur = graph->setsOfVertex[indexOfTopoList].p_firstAdjEdge;
while (cur) {
int adjVer_index = cur->adjVertexIndex;
if (graph->happen_late[indexOfTopoList] > graph->happen_late[adjVer_index] - cur->infoOfEdge) {
graph->happen_late[indexOfTopoList] = graph->happen_late[adjVer_index] - cur->infoOfEdge;
}
cur = cur->p_nextEdge;
}
}
printf("源点 -> ");
for (int i = 0; i < numsOfVertex; i++) {
EdgeNode* cur = graph->setsOfVertex[i].p_firstAdjEdge;
while (cur) {
int adjVerIndex = cur->adjVertexIndex;
int e_times = graph->happen_earliest[i];
int l_times = graph->happen_late[adjVerIndex] - cur->infoOfEdge;
if (e_times == l_times) {
printf("%s %s -> ", graph->setsOfVertex[i].val, graph->setsOfVertex[adjVerIndex].val);
}
cur = cur->p_nextEdge;
}
}
printf("汇点\n");
}
void SqStackInit(SqStack* s) {
s->bottom = (VertexNode*)malloc(sizeof(VertexNode) * 70);
if (!s->bottom) exit(0);
s->top = s->bottom;
s->capacityOfSqStack = 70;
}
void SqStackPushBack(SqStack* s, VertexNode x) {
if (s->top - s->bottom == 70) {
exit(0);
}
*(s->top) = x;
s->top++;
}
void SqStackPopBack(SqStack* s, VertexNode* retTopElem) {
if (SqStackEmpty(s)) exit(0);
*retTopElem = *(s->top - 1);
s->top--;
}
int SqStackEmpty(SqStack* s) {
if (s->bottom == s->top) return 1;
return 0;
}
|