C语言图的邻接矩阵建立算法

目录

1.邻接矩阵(adjacency matrix)

2.无向图的邻接矩阵表示

3.有向图的邻接矩阵表示

4.网的邻接矩阵表示

5.示例源代码


1.邻接矩阵(adjacency matrix)

(1)用一维数组存储顶点信息

(2)用矩阵(二维数组)表示图中顶点邻接关系

2.无向图的邻接矩阵表示

规定:若两节点连通,则在矩阵对应位置元素置1,否则置0

 \begin{bmatrix} 0 & 1 & 0 & 1 \\ 1 & 0 & 1 & 1 \\ 0 & 1 & 0 & 0 \\ 1 & 1 & 0 & 0 \\ \end{bmatrix}

 

3.有向图的邻接矩阵表示

规定:若两节点连通,则矩阵对应位置元素为边上权值,否则为无穷大

\begin{bmatrix} \infty & 5 & 9 & \infty \\ \infty & \infty & \infty & \infty \\ \infty & \infty & \infty & 8 \\ 4 & \infty & \infty & \infty \\ \end{bmatrix}

 

4.网的邻接矩阵表示

规定:若两节点连通,则矩阵对应位置元素为边上权值,否则为无穷大

\begin{bmatrix} \infty & 9 & 6 & 3 & \infty \\ 9 & \infty & 4 & 5 & \infty \\ 6 & 4 & \infty & \infty & 5 \\ 3 & 5 & \infty & \infty & 6 \\ \infty & \infty & 5 & 6 & \infty \\ \end{bmatrix} 

5.示例源代码(以上述无向图为例)

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

#define MAX_VERTEX_NUM 100 // 图中最大节点数
typedef char VertexType;   // 顶点类型设置为字符型
typedef int EdgeType;      // 边上权值类型设置为整型
typedef struct             // 边表节点
{
    VertexType vex[MAX_VERTEX_NUM];                 // 顶点表
    EdgeType edges[MAX_VERTEX_NUM][MAX_VERTEX_NUM]; // 邻接矩阵
    int vexnum;                                     // 节点的数目
    int edgenum;                                    // 边的数目
} MGraph;

void CreateMG(MGraph *MG); // 邻接表法创建无向图
void PrintMG(MGraph MG);   // 邻接矩阵形式输出图MG

int main(void)
{
    MGraph g;

    CreateMG(&g);
    printf("------------------------------\n");
    printf("vexnum = %d ; edgenum = %d\n", g.vexnum, g.edgenum);
    printf("------------------------------\n");
    PrintMG(g);

    return 0;
}
void CreateMG(MGraph *MG)
{
    int i = 0, j, k, w; // w:权值
    char ch;

    printf("请依次输入顶点数、边数:");
    scanf("%d %d", &(MG->vexnum), &(MG->edgenum));

    printf("请依次输入顶点(以回车结束输入):");
    getchar();
    while ((ch = getchar()) != '\n') // 输入顶点信息
        MG->vex[i++] = ch;

    /*
     * for (i = 0; i < MG->vexnum; i++)
     *     scanf("\n%c", &(MG->vex[i]));
     */

    // 初始化邻接矩阵
    for (i = 0; i < MG->vexnum; i++)
        for (j = 0; j < MG->vexnum; j++)
            MG->edges[i][j] = 0;

    printf("顶点 | 下标\n");
    // 显示图中顶点及其对应下标
    for (i = 0; i < MG->vexnum; i++) {
        printf("%3c%6d\n", MG->vex[i], i);
    }

    printf("请输入每条边对应的两个顶点下标(格式:i,j):\n");
    // 建立邻接矩阵
    for (k = 0; k < MG->edgenum; k++) {
        scanf("\n%d,%d", &i, &j);
        MG->edges[i][j] = 1;
        MG->edges[j][i] = 1;
    }
}
void PrintMG(MGraph MG)
{
    int i, j;

    // 输出邻接矩阵
    for (i = 0; i < MG.vexnum; i++) {
        for (j = 0; j < MG.vexnum; j++)
            printf("%2d", MG.edges[i][j]);
        printf("\n");
    }
}

  • 31
    点赞
  • 148
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
邻接矩阵Kruskal算法是生成最小生成树的一种方法,具体实现步骤如下: 1. 定义一个结构体来存储边的信息,如起点、终点、权值等。 2. 构建邻接矩阵,将边的信息存储在邻接矩阵中。 3. 将边按照权值从小到大排序。 4. 定义一个数组来记录每个节点所在的连通块。 5. 遍历排序后的边,如果边的两个端点不在同一个连通块中,则将它们合并成一个连通块,并将这条边加入最小生成树中。 6. 重复步骤5,直到所有节点都在同一个连通块中为止。 下面是使用C语言实现邻接矩阵Kruskal算法的代码: ```c #include <stdio.h> #include <stdlib.h> #include <string.h> #define MAX_VERTEX_NUM 100 #define MAX_EDGE_NUM 10000 typedef struct Edge { int start, end, weight; } Edge; int parent[MAX_VERTEX_NUM]; // 记录每个节点所在的连通块 Edge edges[MAX_EDGE_NUM]; // 存储边的信息 int edgeNum; // 边的数量 int vertexNum; // 节点的数量 int cmp(const void *a, const void *b) { Edge *e1 = (Edge *)a; Edge *e2 = (Edge *)b; return e1->weight - e2->weight; } int find(int x) { // 查找x所在的连通块 if (parent[x] == x) return x; return parent[x] = find(parent[x]); } void merge(int x, int y) { // 合并x和y所在的连通块 int px = find(x); int py = find(y); parent[px] = py; } void kruskal() { int cnt = 0; // 记录加入最小生成树的边数 for (int i = 0; i < vertexNum; i++) { parent[i] = i; // 初始化每个节点所在的连通块为它本身 } qsort(edges, edgeNum, sizeof(Edge), cmp); // 将边按照权值排序 for (int i = 0; i < edgeNum; i++) { int start = edges[i].start; int end = edges[i].end; if (find(start) != find(end)) { // 判断这条边的两个端点是否在同一个连通块中 merge(start, end); // 合并连通块 printf("%d %d %d\n", start, end, edges[i].weight); // 输出加入最小生成树的边的信息 cnt++; if (cnt == vertexNum - 1) break; // 边数达到n-1时退出循环 } } } int main() { scanf("%d%d", &vertexNum, &edgeNum); // 输入节点数和边数 for (int i = 0; i < edgeNum; i++) { scanf("%d%d%d", &edges[i].start, &edges[i].end, &edges[i].weight); // 输入边的信息 } kruskal(); // 执行Kruskal算法 return 0; } ``` 其中,cmp函数用于将边按照权值从小到大排序。find函数用于查找一个节点所在的连通块,采用了路径压缩的方法,可以将每个节点的父节点直接指向它所在的连通块的根节点,从而加速查找。merge函数用于合并两个连通块,采用了按秩合并的方法,可以将较小的连通块合并到较大的连通块中,从而减小合并操作的时间复杂度。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值