#include <stdio.h>
#include <stdlib.h>
#define INFINITY 2147483647
#include "Queue.h"
#include "Stack.h"
#define MaxVertexNum 100
typedef struct {
char value;
int weight;
} Edge[MaxVertexNum][MaxVertexNum];
typedef struct {
char Vertex[MaxVertexNum];
Edge Edge;
int vexnum, arcnum;
int type;
} MGraph;
void InitMGraph(MGraph &G, int type) {
G.Vertex[0] = 'A';
for (int i = 0; i < MaxVertexNum; ++i) {
for (int j = 0; j < MaxVertexNum; ++j) {
G.Edge[i][j].value = -1;
}
}
G.Edge[0][0].value = 0;
G.vexnum = 1;
G.arcnum = 0;
G.type = type;
}
void displayMGraphInfo(MGraph G) {
printf("--------------------------\n");
printf("图的顶点数:%d,边数:%d\n", G.vexnum, G.arcnum);
printf("图的邻接矩阵:\n");
printf(" ");
for (int i = 0; i < G.vexnum; ++i) {
printf("%c ", G.Vertex[i]);
}
printf("\n");
for (int i = 0; i < G.vexnum; ++i) {
printf("%c ", G.Vertex[i]);
for (int j = 0; j < G.vexnum; ++j) {
printf("%d ", G.Edge[i][j]);
}
printf("\n");
}
}
bool isVertex(MGraph G, int x) {
return (x >= 0) && (x < G.vexnum);
}
bool Adjacent(MGraph G, int x, int y) {
if (!isVertex(G, x) || !isVertex(G, y)) {
return false;
}
return G.Edge[x][y].value == 1;
}
void Neighbors(MGraph G, int x) {
if (!isVertex(G, x)) {
return;
}
printf("与顶点%c相邻的边: ", G.Vertex[x]);
for (int i = 0; i < G.vexnum; ++i) {
if (G.type == 1) {
if (G.Edge[i][x].value == 1) {
printf("%c%c ", G.Vertex[i], G.Vertex[x]);
}
if (G.Edge[x][i].value == 1) {
printf("%c%c ", G.Vertex[x], G.Vertex[i]);
}
} else {
if (G.Edge[i][x].value == 1) {
printf("%c%c ", G.Vertex[x], G.Vertex[i]);
}
}
}
printf("\n");
}
void InsertVertex(MGraph &G, int x) {
G.Vertex[G.vexnum] = x;
for (int i = 0; i <= G.vexnum; ++i) {
G.Edge[i][G.vexnum].value = 0;
G.Edge[G.vexnum][i].value = 0;
}
++G.vexnum;
}
void DeleteVertex(MGraph &G, int x) {
if (!isVertex(G, x)) {
return;
}
for (int i = x; i < G.vexnum - 1; i++) {
G.Vertex[i] = G.Vertex[i + 1];
}
G.Vertex[G.vexnum - 1] = '\0';
for (int i = 0; i < G.vexnum; ++i) {
if (G.Edge[i][x].value == 1) {
G.arcnum--;
}
if (G.type == 1) {
if (G.Edge[x][i].value == 1) {
G.arcnum--;
}
}
G.Edge[i][x].value = -1;
G.Edge[x][i].value = -1;
}
for (int i = 0; i < G.vexnum; ++i) {
for (int j = x; j < G.vexnum - 1; ++j) {
G.Edge[i][j].value = G.Edge[i][j + 1].value;
}
}
for (int i = 0; i < G.vexnum; ++i) {
for (int j = x; j < G.vexnum - 1; ++j) {
G.Edge[j][i].value = G.Edge[j + 1][i].value;
}
}
--G.vexnum;
}
void AddEdge(MGraph &G, int x, int y) {
if (!isVertex(G, x) || !isVertex(G, y)) {
return;
}
G.arcnum++;
G.Edge[x][y].value = 1;
if (G.type == 0) {
G.Edge[y][x].value = 1;
}
}
void RemoveEdge(MGraph &G, int x, int y) {
if (!isVertex(G, x) || !isVertex(G, y)) {
return;
}
for (int i = 0; i < G.vexnum; ++i) {
if (G.Vertex[i] == x) {
x = i;
}
if (G.Vertex[i] == y) {
y = i;
}
if (x != -1 && y != -1) {
G.Edge[x][y].value = 0;
G.arcnum--;
if (G.type == 0) {
G.Edge[y][x].value = 0;
}
return;
}
}
printf("边%c%c不存在\n", x, y);
}
int FirstNeighbor(MGraph G, int x) {
if (!isVertex(G, x)) {
return -1;
}
for (int i = 0; i < G.vexnum; ++i) {
if (G.Edge[x][i].value == 1) {
return i;
}
}
return -1;
}
int NextNeighbor(MGraph G, int x, int y) {
if (!isVertex(G, x) || !isVertex(G, y)) {
return -1;
}
for (int i = y + 1; i < G.vexnum; ++i) {
if (
G.Edge[x][i].value == 1) {
return i;
}
}
return -1;
}
int Get_edge_value(MGraph G, int x, int y) {
if (!isVertex(G, x) || !isVertex(G, y) ||
G.Edge[x][y].value != 1) {
return -1;
}
return G.Edge[x][y].weight;
}
void Set_edge_value(MGraph &G, int x, int y, int v) {
if (!isVertex(G, x) || !isVertex(G, y) ||
G.Edge[x][y].value != 1) {
return;
}
G.Edge[x][y].weight = v;
if (G.type == 0) {
G.Edge[y][x].weight = v;
}
}
void visit(MGraph G, int v) {
printf("%c ", G.Vertex[v]);
}
LinkQueue Q;
int visited[MaxVertexNum];
void BFS(MGraph G, int v) {
visit(G, v);
visited[v] = true;
EnQueue(Q, v);
while (!QueueEmpty(Q)) {
int x;
DeQueue(Q, x);
int y = FirstNeighbor(G, x);
while (y != -1) {
if (!visited[y]) {
visited[y] = true;
visit(G, y);
EnQueue(Q, y);
}
y = NextNeighbor(G, x, y);
}
}
}
void BFSTraverse(MGraph G) {
printf("广度优先遍历序列: ");
for (int i = 0; i < G.vexnum; ++i) {
visited[i] = false;
}
InitQueue(Q);
for (int i = 0; i < G.vexnum; ++i) {
if (!visited[i]) {
BFS(G, i);
}
}
printf("\n");
}
void DFS(MGraph G, int v) {
visited[v] = true;
visit(G, v);
for (int w = FirstNeighbor(G, v); w >= 0; w = NextNeighbor(G, v, w)) {
if (!visited[w])
DFS(G, w);
}
}
void DFSTraverse(MGraph G) {
printf("深度优先遍历序列: ");
for (int i = 0; i < G.vexnum; ++i) {
visited[i] = false;
}
for (int i = 0; i < G.vexnum; ++i) {
if (!visited[i]) {
DFS(G, i);
}
}
printf("\n");
}
bool isJoin[MaxVertexNum];
int lowCast[MaxVertexNum];
void Prim(MGraph G) {
printf("Prim算法求最小代价生成树: ");
isJoin[0] = true;
for (int i = 1; i < G.vexnum; ++i) {
isJoin[i] = false;
}
lowCast[0] = 0;
for (int j = 1; j < G.vexnum; ++j) {
int w = Get_edge_value(G, 0, j);
if (w != -1) {
lowCast[G.Vertex[j]] = w;
} else {
lowCast[G.Vertex[j]] = INFINITY;
}
}
int minWeight = -1, minIndex = -1;
while (true) {
minIndex = -1, minWeight = -1;
for (int k = 0; k < G.vexnum; ++k) {
if (!isJoin[k] && lowCast[k] != INFINITY) {
if (minIndex == -1) {
minWeight = lowCast[k];
minIndex = k;
} else {
if (lowCast[k] < minWeight) {
minWeight = lowCast[k];
minIndex = k;
}
}
}
}
if (minIndex == -1)
break;
isJoin[minIndex] = true;
for (int j = 1; j < G.vexnum; ++j) {
if (!isJoin[j]) {
int w = Get_edge_value(G, minIndex, j);
if (w != -1) {
if (w < lowCast[j]) {
lowCast[j] = w;
}
}
}
}
}
int value = 0;
for (int i = 0; i < G.vexnum; ++i) {
value += lowCast[i];
}
printf("最小代价:%d", value);
printf("\n");
}
typedef struct {
int vertex1;
int vertex2;
int weight;
} WeightOrderEdge;
typedef struct Node {
int data;
int parent;
} Node;
typedef struct {
Node sets[MaxVertexNum];
int n;
} UFSets;
void InitUFSets(UFSets &S, int size) {
for (int i = 0; i < size; ++i) {
S.sets[i].data = {i};
S.sets[i].parent = -1;
}
S.n = size;
}
int Find(UFSets S, int i) {
if (S.sets[i].parent == -1)
return i;
while (S.sets[i].parent != -1) {
i = S.sets[i].parent;
}
return i;
}
void Union(UFSets &S, int index1, int index2) {
Node &root1 = S.sets[index1];
Node &root2 = S.sets[index2];
if (root1.parent >= 0 ||
root2.parent >= 0) {
return;
}
root2.parent = index1;
}
void Kruskal(MGraph G) {
printf("\nKruskal算法求最小代价生成树: ");
WeightOrderEdge E[G.arcnum];
for (int i = 0; i < G.arcnum; ++i) {
E[i].weight = INFINITY;
E[i].vertex1 = -1;
E[i].vertex2 = -1;
}
int k = 0;
for (int i = 0; i < G.vexnum; ++i) {
for (int j = 0; j < G.vexnum; ++j) {
if (i <= j) {
int w = Get_edge_value(G, i, j);
if (w != -1) {
E[k].vertex1 = i;
E[k].vertex2 = j;
E[k].weight = w;
k++;
}
}
}
}
for (int i = 0; i < G.arcnum - 1; ++i) {
int min = i;
for (int j = i + 1; j < G.arcnum; ++j) {
if (E[j].weight < E[min].weight) {
min = j;
}
}
if (min != i) {
int minVertex1 = E[min].vertex1, minVertex2 = E[min].vertex2, minWeight = E[min].weight;
int iVertex1 = E[i].vertex1, iVertex2 = E[i].vertex2, iWeight = E[i].weight;
E[min].vertex1 = iVertex1;
E[min].vertex2 = iVertex2;
E[min].weight = iWeight;
E[i].vertex1 = minVertex1;
E[i].vertex2 = minVertex2;
E[i].weight = minWeight;
}
}
UFSets S;
InitUFSets(S, G.arcnum);
int value = 0;
for (int i = 0; i < G.arcnum; ++i) {
int vertex1 = E[i].vertex1;
int vertex2 = E[i].vertex2;
int set1 = Find(S, vertex1);
int set2 = Find(S, vertex2);
if (set1 == set2) {
continue;
} else {
Union(S, set1, set2);
value += E[i].weight;
}
}
printf("最小代价:%d\n", value);
}
int d[MaxVertexNum];
int path[MaxVertexNum];
void BFS_MIN_DISTANCE(MGraph G, int v) {
for (int i = 0; i < G.vexnum; ++i) {
visited[i] = false;
}
InitQueue(Q);
for (int i = 0; i < G.vexnum; ++i) {
d[i] = INFINITY;
path[i] = -1;
}
d[v] = 0;
visited[v] = true;
EnQueue(Q, v);
while (!QueueEmpty(Q)) {
int x;
DeQueue(Q, x);
int y = FirstNeighbor(G, x);
while (y != -1) {
if (!visited[y]) {
d[y] = d[x] + 1;
path[y] = x;
visited[y] = true;
EnQueue(Q, y);
}
y = NextNeighbor(G, x, y);
}
}
}
bool final[MaxVertexNum];
int dist[MaxVertexNum];
void Dijkstra(MGraph G, int v) {
printf("\nDijkstra算法求顶点 %d 到其他各顶点之间的最短路径: ", v);
for (int i = 0; i < G.vexnum; ++i) {
final[i] = false;
dist[i] = INFINITY;
path[i] = -1;
}
path[v] = -1;
dist[v] = 0;
final[v] = true;
for (int j = 0; j < G.vexnum; ++j) {
if (j != v) {
int w = Get_edge_value(G, v, j);
if (w != -1) {
dist[j] = w;
path[j] = v;
}
}
}
int min;
while (true) {
min = -1;
for (int i = 0; i < G.vexnum; ++i) {
if (!final[i]) {
if (min == -1) {
min = i;
} else {
if (dist[i] < dist[min]) {
min = i;
}
}
}
}
if (min == -1) {
break;
}
final[min] = true;
for (int j = 0; j < G.vexnum; ++j) {
if (!final[j]) {
int w = Get_edge_value(G, min, j);
if (w != -1) {
int d = w + dist[min];
if (d < dist[j]) {
dist[j] = d;
path[j] = min;
}
}
}
}
}
printf("\n");
}
int paths[MaxVertexNum][MaxVertexNum];
int A[MaxVertexNum][MaxVertexNum];
LinkStack S;
void getPaths(MGraph G, int i, int j) {
if (paths[i][j] == -1) {
printf("->%d", j);
return;
}
if (A[i][j] != INFINITY) {
int k = paths[i][j];
getPaths(G, i, k);
getPaths(G, k, j);
}
}
void Floyd(MGraph G) {
printf("Floyd算法求各顶点之间的最短路径:\n");
for (int i = 0; i < G.vexnum; ++i) {
for (int j = 0; j < G.vexnum; ++j) {
paths[i][j] = -1;
if (i == j) {
A[i][j] = 0;
continue;
}
int w = Get_edge_value(G, i, j);
if (w != -1) {
A[i][j] = w;
} else {
A[i][j] = INFINITY;
}
}
}
for (int k = 0; k < G.vexnum; ++k) {
for (int i = 0; i < G.vexnum; ++i) {
for (int j = 0; j < G.vexnum; ++j) {
if (A[i][k] == INFINITY || A[k][j] == INFINITY) {
continue;
}
if (A[i][j] > A[i][k] + A[k][j]) {
A[i][j] = A[i][k] + A[k][j];
paths[i][j] = k;
}
}
}
}
InitStack(S);
for (int i = 0; i < G.vexnum; ++i) {
printf("顶点%d到其他顶点 最短路径: \n", G.Vertex[i]);
for (int j = 0; j < G.vexnum; ++j) {
if (A[i][j] != INFINITY) {
printf("%d到%d: ", i, j);
printf("%d", i);
getPaths(G, i, j);
printf("\n");
}
}
}
printf("\n");
}
int indegree[MaxVertexNum];
int print[MaxVertexNum];
bool TopologicalSort(MGraph G) {
for (int i = 0; i < G.vexnum; ++i) {
indegree[i] = 0;
}
for (int i = 0; i < G.vexnum; ++i) {
for (int j = 0; j < G.vexnum; ++j) {
if (Adjacent(G, i, j)) {
indegree[j]++;
}
}
}
InitStack(S);
for (int i = 0; i < G.vexnum; ++i) {
if (indegree[i] == 0) {
Push(S, i);
}
}
int v;
int count = 0;
while (!StackEmpty(S)) {
Pop(S, v);
print[count++] = v;
for (int i = 0; i < G.vexnum; ++i) {
if (Adjacent(G, v, i)) {
if (--indegree[i] == 0) {
Push(S, i);
}
}
}
}
if (count < G.vexnum) {
return false;
} else {
return true;
}
}
int outdegree[MaxVertexNum];
bool ReverseTopologicalSort(MGraph G) {
for (int i = 0; i < G.vexnum; ++i) {
outdegree[i] = 0;
}
for (int i = 0; i < G.vexnum; ++i) {
for (int j = 0; j < G.vexnum; ++j) {
if (Adjacent(G, i, j)) {
outdegree[i]++;
}
}
}
InitStack(S);
for (int i = 0; i < G.vexnum; ++i) {
if (outdegree[i] == 0) {
Push(S, i);
}
}
int v;
int count = 0;
while (!StackEmpty(S)) {
Pop(S, v);
print[count++] = v;
for (int i = 0; i < G.vexnum; ++i) {
if (Adjacent(G, i, v)) {
if (--outdegree[i] == 0) {
Push(S, i);
}
}
}
}
if (count < G.vexnum) {
return false;
} else {
return true;
}
}
void DFSTopo(MGraph G, int v) {
visited[v] = true;
for (int w = FirstNeighbor(G, v); w >= 0; w = NextNeighbor(G, v, w)) {
if (!visited[w])
DFSTopo(G, w);
}
printf("%d ", v);
}
void DFSTraverseTopo(MGraph G) {
printf("使用深度优先遍历算法得到逆拓扑序列: \n");
for (int i = 0; i < G.vexnum; ++i) {
visited[i] = false;
}
for (int i = 0; i < G.vexnum; ++i) {
if (!visited[i]) {
DFSTopo(G, i);
}
}
printf("\n");
}
int main() {
setbuf(stdout, NULL);
MGraph G;
int type = 0;
int vertex, vertex1, vertex2;
InitMGraph(G, type);
InsertVertex(G, 'B');
InsertVertex(G, 'C');
InsertVertex(G, 'D');
InsertVertex(G, 'E');
InsertVertex(G, 'F');
AddEdge(G, 0, 1);
AddEdge(G, 0, 2);
AddEdge(G, 0, 3);
AddEdge(G, 1, 5);
AddEdge(G, 2, 4);
AddEdge(G, 3, 5);
displayMGraphInfo(G);
int x, y;
x = 0, y = 1;
for (int i = 0; i < 6; ++i) {
x = i;
if (type == 0) {
printf("顶点%c存在的边: ", G.Vertex[x]);
} else {
printf("顶点%c存在的弧: ", G.Vertex[x]);
}
for (int j = 0; j < 6; ++j) {
y = j;
if (Adjacent(G, x, y)) {
printf("%c%c ", G.Vertex[x], G.Vertex[y]);
}
}
printf("\n");
}
for (int i = 0; i < 6; ++i) {
x = i;
y = FirstNeighbor(G, x);
if (y != -1) {
int k = 0;
printf("顶点%c的邻接点有: %c ", G.Vertex[x], G.Vertex[y]);
y = (NextNeighbor(G, x, y));
while (y != -1) {
printf("%c ", G.Vertex[y]);
y = (NextNeighbor(G, x, y));
}
printf("\n");
} else {
printf("顶点%c不存在或没有邻接点\n", G.Vertex[x]);
}
}
for (int i = 0; i < 6; ++i) {
Neighbors(G, i);
}
int v;
BFSTraverse(G);
DFSTraverse(G);
LinkStack S;
InitStack(S);
for (int i = 0; i < G.vexnum; ++i) {
BFS_MIN_DISTANCE(G, i);
printf("顶点%c到其他顶点 最短路径: \n", G.Vertex[i]);
for (int j = 0; j < G.vexnum; ++j) {
int k = path[j];
printf("%c到%c: %d ", G.Vertex[i], G.Vertex[j], d[j]);
while (k != -1) {
Push(S, G.Vertex[k]);
k = path[k];
}
while (!StackEmpty(S)) {
int e;
Pop(S, e);
printf("%c->", e);
}
printf("%c\n", G.Vertex[j]);
}
printf("\n");
}
InitMGraph(G, type);
G.Vertex[0] = 0;
InsertVertex(G, 1);
InsertVertex(G, 2);
InsertVertex(G, 3);
InsertVertex(G, 4);
InsertVertex(G, 5);
AddEdge(G, 0, 1);
Set_edge_value(G, 0, 1, 6);
AddEdge(G, 0, 2);
Set_edge_value(G, 0, 2, 5);
AddEdge(G, 0, 3);
Set_edge_value(G, 0, 3, 1);
AddEdge(G, 1, 3);
Set_edge_value(G, 1, 3, 5);
AddEdge(G, 1, 4);
Set_edge_value(G, 1, 4, 3);
AddEdge(G, 2, 3);
Set_edge_value(G, 2, 3, 4);
AddEdge(G, 2, 5);
Set_edge_value(G, 2, 5, 2);
AddEdge(G, 3, 4);
Set_edge_value(G, 3, 4, 6);
AddEdge(G, 3, 5);
Set_edge_value(G, 3, 5, 4);
AddEdge(G, 4, 5);
Set_edge_value(G, 4, 5, 6);
for (int i = 0; i < 6; ++i) {
x = i;
printf("与顶点%d相邻的边的权值: ", G.Vertex[x]);
for (int j = 0; j < 6; ++j) {
y = j;
int w = Get_edge_value(G, x, y);
if (w != -1) {
printf("%d%d: %d ", G.Vertex[x], G.Vertex[y], w);
}
}
printf("\n");
}
printf("\n");
Prim(G);
Kruskal(G);
type = 1;
InitMGraph(G, type);
G.Vertex[0] = 0;
InsertVertex(G, 1);
InsertVertex(G, 2);
InsertVertex(G, 3);
InsertVertex(G, 4);
AddEdge(G, 0, 1);
Set_edge_value(G, 0, 1, 10);
AddEdge(G, 0, 4);
Set_edge_value(G, 0, 4, 5);
AddEdge(G, 1, 2);
Set_edge_value(G, 1, 2, 1);
AddEdge(G, 1, 4);
Set_edge_value(G, 1, 4, 2);
AddEdge(G, 2, 3);
Set_edge_value(G, 2, 3, 4);
AddEdge(G, 3, 0);
Set_edge_value(G, 3, 0, 7);
AddEdge(G, 3, 2);
Set_edge_value(G, 3, 2, 6);
AddEdge(G, 4, 1);
Set_edge_value(G, 4, 1, 3);
AddEdge(G, 4, 2);
Set_edge_value(G, 4, 2, 9);
AddEdge(G, 4, 3);
Set_edge_value(G, 4, 3, 2);
for (int i = 0; i < G.vexnum; ++i) {
Dijkstra(G, i);
printf("顶点%d到其他顶点 最短路径: \n", G.Vertex[i]);
for (int j = 0; j < G.vexnum; ++j) {
int k = path[j];
printf("%d到%d: %d ", G.Vertex[i], G.Vertex[j], dist[j]);
while (k != -1) {
Push(S, G.Vertex[k]);
k = path[k];
}
while (!StackEmpty(S)) {
int e;
Pop(S, e);
printf("%d->", e);
}
printf("%d\n", G.Vertex[j]);
}
printf("\n");
}
type = 1;
InitMGraph(G, type);
G.Vertex[0] = 0;
InsertVertex(G, 1);
InsertVertex(G, 2);
InsertVertex(G, 3);
InsertVertex(G, 4);
AddEdge(G, 0, 2);
Set_edge_value(G, 0, 2, 1);
AddEdge(G, 0, 4);
Set_edge_value(G, 0, 4, 10);
AddEdge(G, 1, 3);
Set_edge_value(G, 1, 3, 1);
AddEdge(G, 1, 4);
Set_edge_value(G, 1, 4, 5);
AddEdge(G, 2, 1);
Set_edge_value(G, 2, 1, 1);
AddEdge(G, 2, 4);
Set_edge_value(G, 2, 4, 7);
AddEdge(G, 3, 4);
Set_edge_value(G, 3, 4, 1);
Floyd(G);
InitMGraph(G, type);
G.Vertex[0] = 0;
InsertVertex(G, 1);
InsertVertex(G, 2);
InsertVertex(G, 3);
InsertVertex(G, 4);
AddEdge(G, 0, 1);
AddEdge(G, 1, 3);
AddEdge(G, 3, 4);
AddEdge(G, 2, 3);
AddEdge(G, 2, 4);
if (TopologicalSort(G)) {
printf("拓扑排序成功,拓扑序列为:\n");
for (int i = 0; i < G.vexnum; ++i) {
printf("%d ", print[i]);
}
printf("\n");
} else {
printf("拓扑排序失败\n");
}
if (ReverseTopologicalSort(G)) {
printf("逆拓扑排序成功,逆拓扑序列为:\n");
for (int i = 0; i < G.vexnum; ++i) {
printf("%d ", print[i]);
}
printf("\n");
} else {
printf("逆拓扑排序失败\n");
}
DFSTraverseTopo(G);
return 0;
}