数据结构复习:图的基本操作、应用(邻接矩阵实现)

本文档详细介绍了图的邻接矩阵存储、基本操作如初始化、添加和删除顶点及边,以及深度优先遍历、广度优先遍历、Prim算法和Kruskal算法等。通过实际代码展示,探讨了广度优先搜索(BFS)、深度优先搜索(DFS)、拓扑排序、最小生成树求解等核心概念。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

#include <stdio.h>
#include <stdlib.h>

#define INFINITY 2147483647

#include "Queue.h"
#include "Stack.h"
//图的邻接矩阵存储
//适合存储稠密图
//缺点 空间复杂度高 O(n^2)
#define MaxVertexNum 100//顶点数目的最大值
typedef struct {
    char value;
    int weight;
} Edge[MaxVertexNum][MaxVertexNum];

typedef struct {
    char Vertex[MaxVertexNum]; //顶点表
    Edge Edge;
    int vexnum, arcnum;//当前顶点数、边数/弧数
    int type;//0 表示无向图,1表示有向图
} 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);
}

//判断图G是否存在边<x,y>或(x,y)
bool Adjacent(MGraph G, int x, int y) {
    if (!isVertex(G, x) || !isVertex(G, y)) {
        return false;
    }
    return G.Edge[x][y].value == 1;
}

//列出图G中与顶点x临界的边
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");
}

//在图G中插入顶点x
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;
}

//在图G中删除顶点x(后面的行和列向前移动)
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;
}


//无向边(x,y) 或 有向边<x,y>不存在,则向图G中添加该边
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;
    }
}

//无向边(x,y) 或 有向边<x,y>存在,则删除该边
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);
}

//求图G中顶点x的第一个邻接点,若有返回顶点号。若x没有邻接点或图中不存在x,返回-1
/**
 *
 * @param G
 * @param x 顶点
 * @return 顶点号
 */
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;
}

//假设图G中顶点y是x的一个邻接点,返回除了y之外顶点x的下一个邻接点的顶点号,若y是x的最后一个邻接点,返回-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;
}

//获取图G中边<x,y>或(x,y)对应的权值
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;
}

//设置图G中边<x,y>或(x,y)对应的权值为v
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;
    }
}


//访问顶点v
void visit(MGraph G, int v) {
    printf("%c ", G.Vertex[v]);
}

LinkQueue Q;//队列用于存放顺序访问的结点
int visited[MaxVertexNum];//存放每个结点的访问情况

//广度优先遍历
void BFS(MGraph G, int v) { //从顶点 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];//各结点加入树的最低代价

//Prim算法求最小代价生成树
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;//如果代价表中不存在未被访问的结点,则为minIndex未更新
        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;
}

//Kruskal算法求最小代价生成树
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];//路径从哪个顶点过来
//求顶点 v 到其他顶点的最短路径
void BFS_MIN_DISTANCE(MGraph G, int v) { //从顶点 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;//顶点v到顶点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;//路径长度 +1
                path[y] = x;//最短路径应从x到y
                visited[y] = true;//访问该邻接点
                EnQueue(Q, y);//入队
            }
            y = NextNeighbor(G, x, y);//访问下一个邻接点
        }
    }
}

bool final[MaxVertexNum];//标记各个顶点是否已找到最短路径
int dist[MaxVertexNum];//最短路径长度
//int path[MaxVertexNum];//路径上的直接前驱

//Dijkstra求单源点最短路径问题(带权图、无权图) 不适合带负权值的图
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);
    }
}

// Floyd 算法求各顶点之间的最短路径
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) {//将所有入度为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) {//将所有出度为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;
//    visit(G, v);
    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);//解决debug时候控制台没有输出
    MGraph G;
    int type = 0;
    int vertex, vertex1, vertex2;
    InitMGraph(G, type);
//    InsertVertex(G, 'G');
    InsertVertex(G, 'B');
    InsertVertex(G, 'C');
    InsertVertex(G, 'D');
    InsertVertex(G, 'E');
    InsertVertex(G, 'F');

    AddEdge(G, 0, 1);//A-B
    AddEdge(G, 0, 2);//A-C
    AddEdge(G, 0, 3);//A-D
//    AddEdge(G, 1, 4);//B-E
    AddEdge(G, 1, 5);//B-F
    AddEdge(G, 2, 4);//C-E
    AddEdge(G, 3, 5);//D-F

    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) {
//                printf("%c ",G.vertices[k].data.value);
                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);

//    InsertVertex(G,'0');

    G.Vertex[0] = 0;
    InsertVertex(G, 1);
    InsertVertex(G, 2);
    InsertVertex(G, 3);
    InsertVertex(G, 4);
    InsertVertex(G, 5);
//    InsertVertex(G,6);

    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);


    //测试 Dijkstra算法
    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");
    }

    //测试 Floyd 算法求各顶点之间的最短路径
//
//    //测试 三个顶点
//    InitALGraph(G, type);
//    G.vertices[0].data.value = 0;
//
//    InsertVertex(G, 1);
//    InsertVertex(G, 2);
//
//    AddEdge(G,0,1);
//    Set_edge_value(G,0,1,6);
//
//    AddEdge(G,1,0);
//    Set_edge_value(G,1,0,10);
//
//    AddEdge(G,0,2);
//    Set_edge_value(G,0,2,13);
//    AddEdge(G,2,0);
//    Set_edge_value(G,2,0,5);
//
//    AddEdge(G,1,2);
//    Set_edge_value(G,1,2,4);
//
//    Floyd(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, 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);
//    AddEdge(G, 4, 2);
    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;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值