GRAPH

邻接矩阵

#include <stdio.h>
#include <string.h>
typedef enum GraphKind{DG,UDG,DN,UDN}GraphKind;
//direct graph // undefined direct graph
//direct network //undefined direct network

#define INT_MAX 99999
#define INFINITY INT_MAX
#define MAX_VERTEX_NUM 10
#define MAX_ARC_NUM 10

typedef char status;
#define ERROR 0
#define OK 1
//图弧信息,首先定义二维数组的元素类型
typedef int EdgeType;
typedef struct ArcCell{
    EdgeType adjvex;
}ArcCell,AdjMatrix[MAX_VERTEX_NUM][MAX_VERTEX_NUM];
typedef int VertexType;
typedef struct {
	AdjMatrix arc;//边表,邻接矩阵
	VertexType vex[MAX_VERTEX_NUM];//顶点信息,默认顶点编号是从1开始,通过索引跟我的顶点进行映射//最后弧矩阵中的行索引src,列索引dest
	int vexnum,arcnum;//顶点数,边数
    GraphKind kind;
}MGraph;

status createMGraph(MGraph *mG,VertexType* vset,int vsetlength,VertexType(*arcset)[2],int arcsetlength){
    if(mG==NULL||vset==NULL||arcset==NULL){
        return ERROR;
    }
    //将每个顶点存入到数组
    for(int index=0;index<vsetlength;index++){
        mG->vex[index] = vset[index];
    }
    for(int index=0;index<arcsetlength;index++){
        VertexType src = arcset[index][0];
        VertexType dest = arcset[index][1];
        mG->arc[src][dest].adjvex=1;
    }
    mG->vexnum = vsetlength;
    mG->arcnum= arcsetlength;
    mG->kind = DG;
    return OK;
}

status printMG(MGraph mG){
    if(mG.vexnum<=0||mG.arcnum<=0){
        return ERROR;
    }
    for(int irow=0;irow<mG.vexnum;irow++){
        for(int jcol =0;jcol<mG.vexnum;jcol++){
            if(mG.arc[irow][jcol].adjvex!=0)
                printf("%d %d\n",mG.vex[irow],mG.vex[jcol]);
        }
    }
    for(int index=0;index<mG.vexnum;index++){ 
        printf("%d",mG.vex[index]);
    }
    return OK;
}
int main() {
    VertexType vset[MAX_VERTEX_NUM] = {0};
    int vsetlength = 0; // 记录vset中顶点的数量
    // 打开文件
    FILE* fpvset= fopen("C:/Users/user/Desktop/test/vset.txt", "r");
    if (fpvset != NULL) {
        VertexType vertex;
        while (!feof(fpvset)) {
            fscanf(fpvset, "%d\n", &vertex);
            printf("%d\n",vertex);
            vset[vsetlength] = vertex;
            vsetlength+=1;
        }
        fclose(fpvset); // 关闭文件
    } else {
        printf("Failed to open file.\n");
        return 1; // 退出程序,表示文件打开失败
    }
    // 打印顶点信息
    printf("vex:");
    for (int i = 0; i < vsetlength; i++) {
        printf("%d ", vset[i]);
    }
    printf("\n");
    FILE* fparcset= fopen("C:/Users/user/Desktop/test/arcset.txt", "r");
    int arcset[MAX_ARC_NUM][2];
    int arcsetlength=0;
    int srcVertex,destVertex;
    while (fscanf(fparcset, "%d %d", &srcVertex, &destVertex) == 2) {
    // 处理读取到的数据
    arcset[arcsetlength][0] = srcVertex;
    arcset[arcsetlength][1] = destVertex;
    arcsetlength += 1;
}
    // 打印顶点信息
    printf("arc:\n");
    for (int i = 0; i < arcsetlength; i++) {
        printf("%d %d\n",arcset[i][0],arcset[i][1]);
    }
    printf("\n");

    MGraph mG;
    for(int i= 0;i<MAX_VERTEX_NUM;i++){
        memset(mG.arc[i],0,sizeof(ArcCell)*MAX_VERTEX_NUM);
    }
    mG.vexnum= vsetlength;
    mG.arcnum=arcsetlength;
    mG.kind = DG;    

    status ret=createMGraph(&mG,vset,vsetlength,arcset,arcsetlength);
    if(ret==OK){
        printMG(mG);
    }
    return 0;
}

邻接表

存储结构

typedef struct ArcNode{//表节点
    int adjvex;//目的节点的编号,目的节点对应头节点在数组中的索引;考试时顶点都默认是数组编号,所以和索引一一对应
    struct ArcNode* nextNode;
}ArcNode;
typedef struct VNode{//头节点
    VertexType data;
    ArcNode* firstArc;//指向单链表中第一个弧节点的指针域,跟nextArc一样
}VNode,AdjList[MAX_VERTEX_NUM];//定义一个足够大的存头节点的数组
typedef struct{//邻接表
    AdjList vertices;//邻接数组,专门存顶点信息(头节点)
    int vexnum;
    int arcnum;
    GraphKind kind;
}ALGraph;

邻接表建立无向图

首先读入顶点信息,构建临界数组之后,在读入弧信息。然后在读入弧数据<两个顶点,两个顶点都能做原点,又能做终点,在两个头节点之后使用头插法插入弧节点>重复读取弧数据,生成弧节点插入,直到所有弧数据读完。

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

typedef enum GraphKind { DG, UDG, DN, UDN } GraphKind;

#define INFINITY INT_MAX
#define MAX_VERTEX_NUM 10
#define MAX_ARC_NUM 10

typedef char status;
#define ERROR 0
#define OK 1

typedef int EdgeType;
typedef struct ArcCell {
    EdgeType adjvex;
} ArcCell, AdjMatrix[MAX_VERTEX_NUM][MAX_VERTEX_NUM];

typedef int VertexType;
typedef struct {
    AdjMatrix arc;
    VertexType vex[MAX_VERTEX_NUM];
    int vexnum, arcnum;
    GraphKind kind;
} MGraph;

typedef struct ArcNode {
    int adjvex;
    struct ArcNode* nextNode;
} ArcNode;

typedef struct VNode {
    VertexType data;
    ArcNode* firstArc;
} VNode, AdjList[MAX_VERTEX_NUM];

typedef struct {
    AdjList vertices;
    int vexnum;
    int arcnum;
    GraphKind kind;
} ALGraph;

status createALG(ALGraph* G, VertexType vList[], int vlistlength, VertexType arclist[][2], int arclistlength) {
    if (G == NULL || vList == NULL || arclist == NULL) {
        return ERROR;
    }

    G->kind = UDG;
    G->vexnum = vlistlength;
    G->arcnum = 0;

    for (int index = 0; index < vlistlength; index++) {
        G->vertices[index].data = vList[index];
        G->vertices[index].firstArc = NULL;
    }

    for (int i = 0; i < arclistlength; i++) {
        VertexType src = arclist[i][0] - 1; // 修正顶点编号
        VertexType dest = arclist[i][1] - 1; // 修正顶点编号

        if (src < 0 || src >= vlistlength || dest < 0 || dest >= vlistlength) {
            return ERROR;
        }

        ArcNode* arcPtr = (ArcNode*)malloc(sizeof(ArcNode)); // 分配弧节点内存
        arcPtr->adjvex = dest;
        arcPtr->nextNode = G->vertices[src].firstArc;
        G->vertices[src].firstArc = arcPtr;

        G->arcnum++;
    }

    return OK;
}

void printALG(ALGraph alG) {
    for (int i = 0; i < alG.vexnum; i++) {
        ArcNode* pNextArc = alG.vertices[i].firstArc;
        VertexType src = alG.vertices[i].data;

        while (pNextArc != NULL) {
            printf("%d--->%d\n", src, pNextArc->adjvex + 1); // 修正顶点编号
            pNextArc = pNextArc->nextNode;
        }
    }
}

int main() {
    VertexType vList[MAX_VERTEX_NUM] = { 0 };
    int vListLength = 0;

    FILE* fpvList = fopen("C:/Users/user/Desktop/test/vList.txt", "r");
    if (fpvList != NULL) {
        VertexType vertex;
        while (fscanf(fpvList, "%d\n", &vertex) == 1) {
            vList[vListLength] = vertex;
            vListLength += 1;
        }
        fclose(fpvList);
    }
    else {
        printf("Failed to open file.\n");
        return 1;
    }

    FILE* fparclist = fopen("C:/Users/user/Desktop/test/arclist.txt", "r");
    VertexType arclist[MAX_ARC_NUM][2];
    int arclistLength = 0;
    int srcVertex, destVertex;
    while (fscanf(fparclist, "%d %d", &srcVertex, &destVertex) == 2) {
        arclist[arclistLength][0] = srcVertex;
        arclist[arclistLength][1] = destVertex;
        arclistLength += 1;
    }

    ALGraph alG;
    status ret = createALG(&alG, vList, vListLength, arclist, arclistLength);
    if (ret == OK) {
        printALG(alG);
    }

    return 0;
}

G是一个使用邻接表存储结构的无向图,设计算法删除G中顶点src到dest的边

status deleteEdge(ALGraph* G, VertexType src, VertexType dest) {
    if (G == NULL) {
        return ERROR;
    }

    ArcNode* prevNextArc = NULL;
    ArcNode* nextArcNode = G->vertices[src].firstArc;

    while (nextArcNode != NULL) {
        if (nextArcNode->adjvex == dest) {
            if (prevNextArc == NULL) {
                // 删除头节点
                G->vertices[src].firstArc = nextArcNode->nextNode;
            } else {
                prevNextArc->nextNode = nextArcNode->nextNode;
            }
            free(nextArcNode);
            return OK;
        }
        prevNextArc = nextArcNode;
        nextArcNode = nextArcNode->nextNode;
    }

    return ERROR; // 边不存在
}

设计算法将邻接表表示的网alg转化为邻接矩阵表示的网G

void convertToMatrix(ALGraph alg, MGraph* G) {
    // 初始化邻接矩阵
    for (int i = 0; i < MAX_VERTEX_NUM; i++) {
        for (int j = 0; j < MAX_VERTEX_NUM; j++) {
            G->arc[i][j].adjvex = INFINITY; // 或者其他标记值,表示没有边
        }
    }

    // 遍历邻接表,将边信息转化为邻接矩阵
    for (int i = 0; i < alg.vexnum; i++) {
        ArcNode* pNextArc = alg.vertices[i].firstArc;
        while (pNextArc != NULL) {
            int src = i;
            int dest = pNextArc->adjvex;
            // 设置邻接矩阵中的相应元素,这里假设边的权重为1
            G->arc[src][dest].adjvex = 1; // 或者设置为具体的边权重
            pNextArc = pNextArc->nextNode;
        }
    }

    G->vexnum = alg.vexnum;
    G->arcnum = alg.arcnum;
    G->kind = alg.kind;
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值