数据结构定义
#define maxsize 100
邻接矩阵
typedef struct
{
int no;
}VertexType;
typedef struct
{
int edges[maxsize][maxsize];
int n,e;
VertexType vex[maxsize];
}MGraph;
邻接表
typedef struct ArcNode
{
int adjvex;
struct ANode *next;
}ArcNode;
typedef struct
{
ArcNode *firstarc;
}VNode;
typedef struct
{
VNode adjlist[maxsize];
int n,e;
}AGraph;
图的深度优先遍历
注:遍历过程中经过的边保留所形成的树,称为“深度优先搜索生成树”。
DFS递归实现
int visit[maxsize];
void DFS(AGraph *G,int v){
ArcNode *p;
Visit(v);
visit[v]=1;
p=G->adjlist[v].firstarc;
while(p){
if(visit[p->adjvex]==0)
DFS(G,p->adjvex);
p=p->nextarc;
}
}
DFS非递归实现
void DFS(AGraph *G,int v){
int visit[maxsize];
ArcNode *p;
int stack[maxsize];int top=-1;
int i,k;
for(i=0;i<G->n;++i){
visit[i]=0;
}
Visit(v);
visit[v]=1;
stack[++top]=v;
while(top!=-1){
k=stack[top];
p=G->adjlist[k].firstarc;
while(p!=NULL&&visit[p->adjvex]==1)
p=p->nextarc;
if(p==NULL)
--top;
else{
Visit(p->adjvex);
visit[p->adjvex]=1;
stack[++top]=p->adjvex;
}
}
}
图的广度优先搜索遍历
void BFS(AGraph *G,int v,int visit[]){
ArcNode *p;
int que[maxsize];
int front,rear;
front=rear=0;
int j;
Visit(v);
visit[v]=1;
rear=(rear+1)%maxsize;
que[rear]=v;
while(front!=rear)
{
front=(front+1)%maxsize;
j=que[front];
p=G->adjlist[j].firstarc;
while(p){
if(visit[p->adjvex]==0)
{
rear=(rear+1)%maxsize;
que[rear]=p->adjvex;
visit[p->adjvex]=1;
Visit(p->adjvex);
}
p=p->nextarc;
}
}
}
最小代价生成树
注:两个算法都是针对无向图的
普利姆算法
注:适用于稠密图
void Prim(MGraph g,int v0,int &sum){
int lowcost[maxsize],vset[maxsize],v;
int i,j,min,k;
for(i=0;i<g.n;++i){
lowcost[i]=g.edges[v0][i];
vset[i]=0;
}
vset[v0]=1;
sum=0;
for(i=0;i<g.n-1;++i){
min=INF;
for(j=0;j<g.n;++j){
if(vset[j]==0&&lowcost[j]<min){
min=lowcost[j];
k=j;
}
sum+=min;
v=k;
vset[v]=1;
for(j=0;j<g.n;j++){
if(vset[j]==0&&g.edges[v][j]<lowcost[j])
lowcost[j]=g.edges[v][j];
}
}
}
}
克鲁斯卡尔算法
注:适用于稀疏图
//克鲁斯卡尔算法
typedef struct
{
int a,b;
int w;
}Road;
Road road[maxsize];
int v[maxsize];//并查集
int getRoot(int a){
while(v[a]!=a)
a=v[a];
return a;
}
void Kruskal(MGraph g,int &sum,Road road[]){
int i,j,a,b;
sum=0;
for(i=0;i<g.n;++i){
v[i]=i;
}
sort(road,g.e);//一种排序算法,按照权值对各边排序
for(i=0;i<g.e;++i){
a=getRoot(road[i].a);
b=getRoot(road[i].b);
if(a!=b)
{
v[a]=b;
sum+=road[i].w;
}
}
}
最短路径
迪杰斯特拉算法
//实现某一顶点到其余各顶点的最短路径
//打印路径函数
int PrintfPath(int path[],int a){
int stack[maxsize],top=-1;
while(path[a]!=-1)
{stack[++top]=a;
a=path[a];}
stack[++top]=a;
while(top!=-1)
printf("%d",stack[top--]);
}
void Dijkstra(MGraph g,int v,int dist[],int path[]){
int set[maxsize];
int i,j,k;
for(i=0;i<g.n;++i){
dist[i]=g.edges[v][i];
if(g.edges[v][i]<INF)//INF表示一个巨大的值
path[i]=v;
else
path[i]=-1;
set[i]=0;
}
set[v]=1;path[v]=-1;
for(i=0;i<g.n-1;i++){
int min=INF;
for(j=0;j<g.n;j++){
if(set[j]==0&&dist[j]<min)
{
min=dist[j];
k=j;
}
}
set[k]=1;
for(j=0;j<g.n;j++){
if(set==0&&dist[k]+g.edges[k][j]<dist[j])
{
dist[j]=dist[k]+g.edges[k][j];
path[j]=k;
}
}
}
}
弗洛伊德算法
//求图中任意一对顶点的最短路径
//打印最短路径
void printfPath(int u,int v,int path[][maxsize]){
if(path[u][v]==-1)
直接输出;
else
{
int mid=path[u][v];
printfPath(u,mid,path);
printfPath(mid,v,path);
}
}
//时间复杂度O(n^3)
void Floyd(MGraph g,int path[][maxsize]){
int A[maxsize][maxsize];
int i,j,k;
for(i=0;i<g.n;i++){
for(j=0;j<g.n;j++){
A[i][j]=g.edges[i][j];
path[i][j]=-1;
}
}
for(k=0;k<g.n;k++){
for(i=0;i<g.n;i++){
for(j=0;j<g.n;j++){
if(A[i][j]>A[i][k]+A[k][j])
{
A[i][j]=A[i][k]+A[k][]j;
path[i][j]=k;
}
}
}
}
}
拓扑排序
注:针对有向无环图
typedef struct
{
ArcNode *firstarc;
int count;
}VNode;
int TopSSort(AGraph *G){
int i,j,n=0;
int stack[maxsize],top=-1;
ArcNode *p;
for(i=0;i<G->n;i++){
if(G->adjlist[i].count==0)
stack[++top]=i;
}
while(top!=-1)
{
j=stack[top--];
n++;
printf("%d",j);
p=G->adjlist[j].firstarc;
while(p){
G->adjlist[p->adjvex].count--;
if(G->adjlist[p->adjvex].count==0)
stack[++top]=p->adjvex;
p=p->nexarc;
}
if(n==G->n)
return 1;
else
return 0;
}
}