提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
前言
图的基本操作如下:
基本操作:void CreatGraph(AlGraph &G, VextexType Vlist[], int VlistLength, int arclist[][2], int arcLength,int kind);//图、顶点信息、顶点个数、弧信息、弧个数。
/* 注:VextexType Vlist[]为顶点的集合
arclist[][2]为边或弧的信息集合,当图为无向图时,只需给出边的信息即可,不强调方向性,例如(0,1)与(1,0)是相同的
当其为有向图时强调方向性,例如<0,1><1,0>不同
*/
bool Adjacent(AlGraph G, int x, int y); //判断图G是否存在边<x,y>
void Neighbors(AlGraph G, VextexType x); //列出图G中与节点x相邻接的边
bool InsertVertex(AlGraph &G, VextexType x, int arclist[][2],int arclength); //在图G中插入顶点x
void DeletetVertex(AlGraph &G, VextexType x); //在图G中插入删除x
void AddEdge(AlGraph &G, int x, int y); //若无向边(x,y)或有向边<x,y>不存在,则向图G中添加该边
void RemoveEdge(AlGraph &G, int x, int y); //若无向边(x,y)或有向边<x,y>存在,则向图G中删除该边
int FirstNeighbor(AlGraph G, VextexType x); //求图G中顶点x第一个邻接点,若有则返回顶点号,若x没有邻接点或图G不存在,返回-1
int Get_edge_value(AlGraph G, int x, int y); //获取图G中边(x,y)或弧<x,y>对应的权值
void Set_edge_value(AlGraph &G, int x, int y, int v); //设置图G中边(x,y)或弧<x,y>对应的权值
一、图的基本操作(邻接表)
1.头文件
代码如下(示例):
#ifndef GRAPH_H
#define GRAPH_H
#define MaxVertexNum 10
typedef char VextexType; //顶点类型
/*顶点:vertex,边:edge,弧:arc*/
typedef struct ArcNode //弧/边
{
int Adjvex; //边/弧指向哪个节点
struct ArcNode *next; //指向下一条弧的指针
int info;//边权值
} ArcNode;
typedef struct VNode //顶点
{
VextexType data; //顶点信息
ArcNode *first; //第一条边/弧
} VNode, AdjList[MaxVertexNum];
typedef struct //图
{
AdjList vertices; //节点数组
int vexnum, arcnum; //顶点数和边数
int kind; //图类型:0为无向图,1为有向图
} AlGraph;
void CreatGraph(AlGraph &G, VextexType Vlist[], int VlistLength, int arclist[][2], int arcLength,int kind);//图、顶点信息、顶点个数、弧信息、弧个数。
/* 注:VextexType Vlist[]为顶点的集合
arclist[][2]为边或弧的信息集合,当图为无向图时,只需给出边的信息即可,不强调方向性,例如(0,1)与(1,0)是相同的
当其为有向图时强调方向性,例如<0,1><1,0>不同
*/
bool Adjacent(AlGraph G, int x, int y); //判断图G是否存在边<x,y>
void Neighbors(AlGraph G, VextexType x); //列出图G中与节点x相邻接的边
bool InsertVertex(AlGraph &G, VextexType x, int arclist[][2],int arclength); //在图G中插入顶点x
void DeletetVertex(AlGraph &G, VextexType x); //在图G中插入删除x
void AddEdge(AlGraph &G, int x, int y); //若无向边(x,y)或有向边<x,y>不存在,则向图G中添加该边
void RemoveEdge(AlGraph &G, int x, int y); //若无向边(x,y)或有向边<x,y>存在,则向图G中删除该边
int FirstNeighbor(AlGraph G, VextexType x); //求图G中顶点x第一个邻接点,若有则返回顶点号,若x没有邻接点或图G不存在,返回-1
int Get_edge_value(AlGraph G, int x, int y); //获取图G中边(x,y)或弧<x,y>对应的权值
void Set_edge_value(AlGraph &G, int x, int y, int v); //设置图G中边(x,y)或弧<x,y>对应的权值
#endif // GRAPH_H
2.Graph
代码如下(示例):
#include <stdio.h>
#include <stdlib.h>
#include "Graph.h"
void CreatGraph(AlGraph &G, VextexType Vlist[], int VlistLength, int arclist[][2], int arcLength, int kind) //图、顶点信息、顶点个数、弧信息、弧个数。
{
for (int index = 0; index < VlistLength; index++)
{
G.vertices[index].data = Vlist[index];
G.vertices[index].first = NULL;
}
for (; VlistLength <= MaxVertexNum; VlistLength++)
{
G.vertices[VlistLength].data = '\0';
G.vertices[VlistLength].first = NULL;
}
for (int i = 0; i < arcLength; i++)
{
int v = arclist[i][0]; //边(弧)<v,w>依附的v
int w = arclist[i][1]; //边(弧)<v,w>依附的w
ArcNode *parcnode = (ArcNode *)malloc(sizeof(ArcNode));
parcnode->Adjvex = w;
parcnode->next = G.vertices[v].first;
G.vertices[v].first = parcnode; //头插法
}
G.arcnum = arcLength;
G.vexnum = VlistLength;
G.kind = kind; //G.kind=1(0为无向图,1为有向图)
}
bool Adjacent(AlGraph G, int x, int y) //判断图G是否存在边<x,y>
{
ArcNode *p = G.vertices[x].first;
for (; p != NULL; p = p->next)
{
if (p->Adjvex == y)
return true;
}
return false;
}
void Neighbors(AlGraph G, VextexType x) //列出图G中与节点x相邻接的边
{
int n = -1;
for (int i = 0; G.vertices[i].data != '\0'; i++) //找出节点x所在的那一行
{
if (G.vertices[i].data == x)
n = i;
}
if (n != -1)
{
if (G.kind == 0) //G为无向图
{
ArcNode *p = G.vertices[n].first;
for (; p != NULL; p = p->next)
{
printf("%c", G.vertices[p->Adjvex].data);
}
}
if (G.kind == 1) //G为有向图
{
ArcNode *p = G.vertices[n].first;
for (; p->next != NULL; p = p->next)
{
printf("%c", G.vertices[p->Adjvex].data);
}
for (int i = 0; G.vertices[i].data != '\0'; i++)
{
p = G.vertices[i].first;
for (; p->next != NULL; p = p->next)
{
if (p->Adjvex == n)
printf("%c", G.vertices[i].data);
}
}
}
}
else
printf("图中没有此节点\n");
}
bool InsertVertex(AlGraph &G, VextexType x, int arclist[][2], int arclength) //在图G中插入顶点x,
{
int i = 0, sign;
for (i = 0; G.vertices[i].data != '\0'; i++) //找出节点x所在的那一行
{
if (G.vertices[i].data == x)
return false;
}
G.vertices[i].data = x;
for (int m = 0; m < arclength; m++)
{
int v = arclist[m][0]; //找到需要插入的点
int w = arclist[m][1];
if (v != i && w != i)
return false; //弧信息不包括新加入的节点
if (v == i && w == i)
return false; //弧信息不包括其他节点(指向自己)
ArcNode *p = (ArcNode *)malloc(sizeof(ArcNode));
p->Adjvex = w;
p->next = G.vertices[v].first; //头插法插入元素
G.vertices[v].first = p;
}
return true;
}
void DeletetVertex(AlGraph &G, VextexType x) //在图G中删除x
{
int sign;
for (int i = 0; G.vertices[i].data != '\0'; i++)
{
if (G.vertices[i].data == x)
{
sign = i;
break;
}
}
for (int i = 0; G.vertices[i].data != '\0'; i++)
{
ArcNode *p = G.vertices[i].first;
for (; p != NULL; p = p->next) //删除其他节点的边
{
if (p->Adjvex == sign)
{
if (p->next == NULL)
{
free(p);
break;
}
if (p->next != NULL)
{
p->Adjvex = p->next->Adjvex;
ArcNode *q = p->next;
p->next = q->next;
free(q);
break;
}
}
}
}
ArcNode *t = G.vertices[sign].first;
for (; t != NULL;)
{
ArcNode *m = t;
t = t->next;
G.vertices[sign].first = t;
free(m); //删除操作
}
G.vertices[sign].data = '\0';
//删除操作
}
void AddEdge(AlGraph &G, int x, int y) //若无向边(x,y)或有向边<x,y>不存在,则向图G中添加该边
{
ArcNode *p = G.vertices[x].first;
bool sign = false;
while (p->next != NULL) //遍历寻找y,p指针停留在最后一个节点
{
if (p->Adjvex == y)
{
sign = true;
}
p = p->next;
}
if (p->Adjvex == y) //最后一个节点上面没有遍历到,重新检查一遍这么设计时间复杂度低
sign = true;
if (!sign) //如果没有 插入边
{
ArcNode *q = (ArcNode *)malloc(sizeof(ArcNode));
q->Adjvex = y;
p->next = q;
}
}
void RemoveEdge(AlGraph &G, int x, int y) //若无向边(x,y)或有向边<x,y>存在,则向图G中删除该边
{
ArcNode *p = G.vertices[x].first;
bool sign = false;
while (p->next != NULL) //遍历寻找y,p指针停留在找到的边上
{
if (p->Adjvex == y)
{
sign = true;
break;
}
p = p->next;
}
if (p->Adjvex == y) //最后一个节点上面没有遍历到,重新检查一遍这么设计时间复杂度低
sign = true;
if (sign) //如果有 删除边(偷天换日法)
{
if (p->next == NULL)
free(p);
ArcNode *t = p->next;
p->Adjvex = t->Adjvex;
p->next = t->next;
free(t);
}
}
int FirstNeighbor(AlGraph G, VextexType x) //求图G中顶点x第一个邻接点,若有则返回顶点号,若x没有邻接点或图G不存在,返回-1
{
int sign;
for (int i = 0; G.vertices[i].data != '\0'; i++)
{
if (G.vertices[i].data == x)
{
sign = i;
break;
}
}
ArcNode *p = G.vertices[sign].first;
if(p!=NULL) return p->Adjvex;
else return-1;
}
int Get_edge_value(AlGraph G, int x, int y) //获取图G中边(x,y)或弧<x,y>对应的权值
{
ArcNode *p=G.vertices[x].first;
for(;p!=NULL;p=p->next)
{
if(p->Adjvex==y) return p->info;
}
return 0;
}
void Set_edge_value(AlGraph &G, int x, int y, int v) //设置图G中边(x,y)或弧<x,y>对应的权值
{
ArcNode *p=G.vertices[x].first;
for(;p!=NULL;p=p->next)
{
if(p->Adjvex==y) p->info=v;
}
}
3.main函数
#include <stdio.h>
#include <stdlib.h>
#include"Graph.h"
#include"Graph.cpp"
int main()
{
AlGraph Graph;
VextexType Vlist[]={'A','B','C','D','E','F'};
int VlistLength=6;
int arcLength=14;//边或弧的个数,对应的是二维数组的个数!!
int arclist1[][2]={
{0,1},{0,2},{0,3},
{1,0},{1,4},{1,5},
{2,0},{2,4},
{3,0},{3,5},
{4,1},{4,2},
{5,1},{5,3}
};
int arclist2[][2]={{6,1},{1,6}};
CreatGraph(Graph,Vlist,VlistLength,arclist1,arcLength,0);//创建一个无向图
总结
总结:注释写的很详细啊,欢迎大家在评论区留下意见。