(数据结构)对图的顺序存储结构的补充

图的顺序结构存储无向网和有向网

如下是一个有向网!!!

代码实现如下(包括无向网): 

#include <stdio.h>
#define MAX_NUM 20  // 顶点的最大个数

typedef enum{
	DG, DN, UDG, UDN  // 依次代表的值为 0,1,2,3
} GraphKind;  // 枚举图的 4 种类型

typedef struct{
    int adj;
	// 对于无权图(用 1或 0表示是否相邻)对于带权图(直接为权值) 
    char *info;
	// 弧或边额外含有的信息指针
} ArcCell, AdjMatrix[MAX_NUM][MAX_NUM];

typedef struct{
    int vexs[MAX_NUM];  // 存储图中顶点数据
    AdjMatrix arcs;  // 二维数组,记录顶点之间的关系
    int vexnum, arcnum;  // 记录图的顶点数和弧(边)数
    GraphKind kind;  // 记录图的种类 
} MGraph;

// 根据顶点本身数据,判断出顶点在一维数组中的位置
int LocateVex(MGraph *G, int v){
    int i = 0;
    // 遍历一维数组,找到变量 v
    for(; i < G->vexnum; i++){
        if(G->vexs[i] == v) {
            break;
        }
    }
    // 如果找不到,输出提示语句,返回 -1
    if(i > G->vexnum){
        printf("no such vertex.\n");
        return -1;
    }
    return i;
}

// 构造有向图
void CreateDG(MGraph *G){
    // 输入图含有的顶点数和弧的个数
    printf("请输入有向图含有的顶点数和弧的个数(用逗号分开):");
    scanf("%d,%d", &(G->vexnum), &(G->arcnum));
    // 依次输入顶点本身的数据
    printf("请依次输入顶点本身的数据:");
    for(int i = 0; i < G->vexnum; i++){
        scanf("%d", &(G->vexs[i]));
    }
    // 初始化二维矩阵,全部归 0,指针指向 NULL
    for(int i = 0; i < G->vexnum; i++){
        for(int j = 0; j < G->vexnum; j++){
            G->arcs[i][j].adj = 0;
            G->arcs[i][j].info = NULL;
        }
    }
    // 在二维数组中添加弧的数据
    for(int i = 0; i < G->arcnum; i++) {
        int v1, v2;
        // 输入弧头和弧尾
        printf("请依次输入弧头和弧尾(用逗号分开):");
        scanf("%d,%d", &v1, &v2);
        printf("\n");
        // 确定顶点位置
        int n = LocateVex(G, v1);  // 查找弧头在一维数组中的位置 
        int m = LocateVex(G, v2);  // 查找弧尾在一维数组中的位置  
        // 排除错误数据
        if (m == -1 || n == -1) {
            printf("no this vertex\n");  // 无此顶点 
            return;
        }
        // 将正确的弧的数据加入二维数组
        G->arcs[n][m].adj = 1;
    }
}

//构造无向图
void CreateDN(MGraph *G){
	// 输入图含有的顶点数和边的个数
	printf("请输入无向图含有的顶点数和边的个数(用逗号分开):");
    scanf("%d,%d", &(G->vexnum), &(G->arcnum));
    // 依次输入顶点本身的数据
    printf("请依次输入顶点本身的数据:");
    for(int i = 0; i < G->vexnum; i++){
        scanf("%d", &(G->vexs[i]));
    }
    // 初始化二维矩阵,全部归 0,指针指向 NULL
    for(int i = 0; i < G->vexnum; i++){
        for(int j = 0; j < G->vexnum; j++){
            G->arcs[i][j].adj = 0;
            G->arcs[i][j].info = NULL;
        }
    }
    // 在二维数组中添加边的数据
    for(int i = 0; i < G->arcnum; i++) {
        int v1, v2;
        // 输入弧头和弧尾
        printf("只需要输入上三角部分或下三角部分!!!请依次输入初始点和终端点(用逗号分开):");
        scanf("%d,%d", &v1, &v2);
        int n = LocateVex(G, v1);  // 查找弧头在一维数组中的位置 
        int m = LocateVex(G, v2);  // 查找弧尾在一维数组中的位置 
        if(m == -1 || n == -1) {
            printf("no this vertex\n");  // 无此顶点 
            return;
        }
        G->arcs[n][m].adj = 1;
        G->arcs[m][n].adj = 1;  // 无向图的二阶矩阵沿主对角线对称
    }
}

// 构造有向网
void CreateUDG(MGraph *G){
	// 输入图含有的顶点数和弧的个数
	printf("请输入有向网中含有的顶点数和弧的个数(用逗号分开):");
    scanf("%d,%d", &(G->vexnum), &(G->arcnum));
    // 依次输入顶点本身的数据
    printf("请依次输入顶点本身的数据:");
    for(int i = 0; i < G->vexnum; i++){
        scanf("%d", &(G->vexs[i]));
    }
    // 初始化二维矩阵,全部归 0,指针指向 NULL
    for(int i = 0; i < G->vexnum; i++){
        for(int j = 0; j < G->vexnum; j++){
            G->arcs[i][j].adj = 0; 
            G->arcs[i][j].info = NULL;
        }
    }
    // 在二维数组中添加弧的数据
    for(int i = 0; i < G->arcnum; i++) {
        int v1, v2, w;
        // 输入弧头和弧尾及权值 
        printf("请依次输入弧头、弧尾和权值(用逗号分开):");
        scanf("%d,%d,%d", &v1, &v2, &w);
        int n = LocateVex(G, v1);
        int m = LocateVex(G, v2);
        if(m == -1 || n == -1){
            printf("no this vertex\n");  // 无此顶点 
            return;
        }
        G->arcs[n][m].adj = w;
    }
}

//构造无向网
void CreateUDN(MGraph* G){
	// 输入图含有的顶点数和弧的个数
	printf("请输入无向网中含有的顶点数和边的个数(用逗号分开):");
    scanf("%d,%d", &(G->vexnum), &(G->arcnum));
	// 依次输入顶点本身的数据
    printf("请依次输入顶点本身的数据:");
    for(int i = 0; i < G->vexnum; i++){
        scanf("%d", &(G->vexs[i]));
    }
    // 初始化二维矩阵,全部归 0,指针指向 NULL
    for(int i = 0; i < G->vexnum; i++){
        for(int j = 0; j < G->vexnum; j++){
            G->arcs[i][j].adj = 0; 
            G->arcs[i][j].info = NULL;
        }
    }
    // 在二维数组中添加弧的数据
    for(int i = 0; i < G->arcnum; i++){
        int v1, v2, w;
        // 输入弧头和弧尾及权值 
        printf("请依次输入弧头、弧尾和权值(用逗号分开):");
        scanf("%d,%d,%d", &v1, &v2, &w);
        int m = LocateVex(G, v1);
        int n = LocateVex(G, v2);
        if(m == -1 || n == -1){
            printf("no this vertex\n");  // 无此顶点 
            return;
        }
        G->arcs[n][m].adj = w;
        G->arcs[m][n].adj = w;  // 矩阵对称
    }
}

// 选择创造图的类型 
void CreateGraph(MGraph *G){
    // 选择图的类型 
    scanf("%d", &(G->kind));
    // 根据所选类型,调用不同的函数实现构造图的功能
    switch(G->kind){
        case DG:  // 有向图 
            return CreateDG(G);
            break;
        case DN:  // 无向图 
            return CreateDN(G);
            break;
        case UDG:  // 有向网 
            return CreateUDG(G);
            break;
        case UDN:  // 无向网 
            return CreateUDN(G);
            break;
        default:
            break;
    }
}

// 输出函数
void PrintGrapth(MGraph G){
    for(int i = 0; i < G.vexnum; i++){  // 顶点数 
        for(int j = 0; j < G.vexnum; j++){  // 顶点数 
            printf("%d ", G.arcs[i][j].adj);  // 输出图的二阶矩阵 
        }
        printf("\n");
    }
}

// 主函数 
int main(void){
    MGraph G;  // 建立一个图的变量
    CreateGraph(&G);  // 调用创建函数,传入地址参数
    PrintGrapth(G);  // 输出图的二阶矩阵
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

是我来晚了!

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值