邻接矩阵
#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;
}