图
单源点最短路径的Dijkstra算法
#include <stdio.h>
#include <stdlib.h>
#define MAXSIZE 6
#define INF 32767
void Ppath(int path[],inti,int v0)
{//先序递归查找最短路径上的顶点
int k;
k=path[i];
if(k!=v0)//顶点vk不是源点v0时
{
Ppath(path,k,v0);//递归查找顶点vk的前一个顶点
printf("%d,",k);//输出顶点vk
}
}
void Dispath(int dist[],intpath[],int s[],int v0,int n)
{//输出最短路径函数
int i;
for(i=0;i<n;i++)
if(s[i]==1)
{
printf("从%d到%d的最短路径长度为:%d,路径为:",v0,i,dist[i]);
printf("%d,",v0);//输出路径上的源点v0
Ppath(path,i,v0);//输出路径上的中间顶点vi
printf("%d\n",i);//输出路径上的终点
}
else
printf("从%d到%d不存在最短路径\n",v0,i);
}
void Dijkstra(intgm[][MAXSIZE],int v0,int n)
{
int dist[MAXSIZE],path[MAXSIZE],s[MAXSIZE];
int i,j,k,mindis;
for(i=0;i<n;i++)
{
dist[i]=gm[v0][i];
s[i]=0;//s[i]=0表示顶点vi属于T集
if(gm[v0][i]<INF)//路径初始化
path[i]=v0;//源点v0是vi当前最短路径中的前一个顶点
else
path[i]=-1;//v0到v1没有边
}
s[v0]=1;path[v0]=0;//v0并入集合S且v0的当前最短路径中午前一个顶点
for(i=0;i<n;i++)//对除v0外的n-1顶点寻找最短路径
{
mindis=INF;
for(j=0;j<n;j++)//从当前集合T中选择一个路经长度最短的顶点vk
if(s[j]==0&&dist[j]<mindis)
{
k=j;
mindis=dist[j];
}
s[k]=1;//顶点vk加入集合s中
for(j=0;j<n;j++)//调整源点v0到集合T中任一顶点vj的路径长度
if(s[j]==0)//顶点vj在集合T中
if(gm[k][j]<INF&&dist[k]+gm[k][j]<dist[j])
{//当v0到vj的路径长度小于v0到vk和vk到vj的路径长度是
dist[j]=dist[k]+gm[k][j];
path[j]=k;//vk是当前最短路径中vj的前一个顶点
}
}
Dispath(dist,path,s,v0,n);//输出最短路径
}
void main()
{
intg[MAXSIZE][MAXSIZE]={{INF,20,15,INF,INF,INF},{2,INF,INF,INF,10,30},{INF,4,INF,INF,INF,10},{INF,INF,INF,INF,INF,INF},{INF,INF,INF,15,INF,INF},{INF,INF,INF,4,10,INF}};
Dijkstra(g,0,6);//求顶点0的最短路径
}
关键路径
#include <stdio.h>
#include <stdlib.h>
#define MAXSIZE 30
typedef struct node//邻接表结点
{
int adjvex;//邻接点域
int info;
struct node *next;//指向下一个邻接边结点的指针域
}EdgeNode;//邻接表结点类型
typedef struct vnode//顶点表结点
{
int indegree;//顶点入度
int vertex;//顶点域
EdgeNode *firstedge;//指向邻接表第一个邻接边结点的指针域
}VertexNode;//顶点表结点类型
typedef struct
{
char data[MAXSIZE];
int top;
}SeqStack;
void Init_SeqStack(SeqStack**s)
{//初始化
*s=(SeqStack *)malloc(sizeof(SeqStack));
(*s)->top=-1;
}
int Empty_SeqStack(SeqStack*s)
{
if(s->top==-1)
return 1;
else
return 0;
}
void Push_SeqStack(SeqStack*s,int x)
{//入栈
if(s->top==MAXSIZE-1)
printf("Stack is full!\n");
else
{
s->top++;
s->data[s->top]=x;
}
}
void Pop_SeqStack(SeqStack*s,int *x)
{//出栈
if(s->top==-1)
printf("Stack is empty!\n");
else
{
*x=s->data[s->top];
s->top--;
}
}
void print(VertexNode g[],intve[],int v1[],int n)
{
int i,j,e,l,dut;
char tag;
EdgeNode *p;
printf("(vi,vj)dut最早开始时间 最晚开始时间 关键活动\n");
for(i=0;i<n;i++)
for(p=g[i].firstedge;p!=NULL;p=p->next)
{
j=p->adjvex;
dut=p->info;
e=ve[i];
l=v1[j]-dut;
tag=(e==1)?'*':'';
printf("(%d,%d)54d%11d%11d%8c\n",g[i].vertex,g[j].vertex,dut,e,tag);
}
for(i=0;i<n;i++)
printf("顶点%d的最早发生时间和最迟发生时间:%5d%5d\n",i,ve[i],v1[i]);
}
void CreatAdjlist(VertexNodeg[],int e,int n)
{//建立有向图的邻接表
EdgeNode *p;
int i,j,k,w;
printf("Input data of (0~n-1);\n");
for(i=0;i<n;i++)
{
g[i].vertex=i;
g[i].firstedge=NULL;
g[i].indegree=0;
}
for(k=1;k<=e;k++)
{
printf("Input edgeof(i,j):");
scanf("%d,%d",&i,&j);
printf("Input weight of(%d,%d);",i,j);
scanf("%d",&w);
p=(EdgeNode *)malloc(sizeof(EdgeNode));
p->adjvex=j;
p->info=w;
p->next=g[i].firstedge;
g[i].firstedge=p;
g[j].indegree=g[j].indegree+1;
}
}
voidToplogicalorder(VertexNode g[],int n)
{//AOE网用邻接表存储,求各顶点事件最早发生时间
int i,j,k,dut,count,*x=&j;
int ve[MAXSIZE],v1[MAXSIZE];
EdgeNode *p;
SeqStack *s,*t;
Init_SeqStack(&s);
Init_SeqStack(&t);
count=0;//顶点个数计数器
for(i=0;i<n;i++)//初始化数组
ve[i]=0;
for(i=0;i<n;i++)
if(g[i].indegree==0)//初始化栈
Push_SeqStack(s,i);
while(!Empty_SeqStack(s))
{
Pop_SeqStack(s,x);//弹出零入度顶点
Push_SeqStack(t,j);//将顶点j压入拓扑序列顶点栈
count++;//对入栈t的顶点数计数
p=g[j].firstedge;
while(p!=NULL)//删除顶点j的所有边
{
k=p->adjvex;
g[k].indegree--;//顶点j的邻接边结点k的入度减1
if(g[k].indegree==0)
Push_SeqStack(s,k);//顶点k入度减1后值为0则压入顶点栈s
if(ve[j]+p->info>ve[k])
ve[k]=ve[j]+p->info;//计算顶点事件的最早发生时间
p=p->next;//查找顶点j的下一个邻接边结点
}
}
if(count<n)//拓扑序列顶点未达到n时则AOE网有回路
{
printf("The AOE network has acycle!\n");
goto L1;
}
for(i=0;i<n;i++)
v1[i]=ve[n-1];
while(!Empty_SeqStack(t))//按拓扑排序的逆序求各顶点的v1值
{
Pop_SeqStack(t,x);//弹出拓扑排序顶点栈t中的顶点
for(p=g[i].firstedge;p!=NULL;p=p->next)
{//计算顶点事件的最迟事件
k=p->adjvex;
dut=p->info;
if(v1[k]-dut<v1[j])
v1[j]=v1[k]-dut;
}
}
print(g,ve,v1,n);
L1: ;
}
void main()
{
int e,n;
VertexNode g[MAXSIZE];
printf("Input number ofnode:\n");
scanf("%d",&n);
printf("Input number of edge:\n");
scanf("%d",&e);
printf("Make adjlist :\n");
CreatAdjlist(g,e,n);
Toplogicalorder(g,n);//拓扑排序并求出关键路径
printf("\n");
}
广度优先生成树
#include <stdio.h>
#include <stdlib.h>
#define MAXSIZE 30
typedef struct
{
int data[MAXSIZE];//队中元素存储空间
int rear,front;//队尾队头指针
}SeQueue;
void Int_SeQueue(SeQueue**q)//循环队列初始化
{
*q=(SeQueue *)malloc(sizeof(SeQueue));
(*q)->front=0;
(*q)->rear=0;
}
int Empty_SeQueue(SeQueue*q)//判队空
{
if(q->front==q->rear)
return 1;
else
return 0;
}
void In_SeQueue(SeQueue*q,int x)//元素入队
{
if((q->rear+1)%MAXSIZE==q->front)
printf("Queue is full:\n");
else
{
q->rear=(q->rear+1)%MAXSIZE;
q->data[q->rear]=x;
}
}
void Out_SeQueue(SeQueue*q,int *x)//出队
{
if(q->rear==q->front)
printf("Queue is empty!\n");
else
{
q->front=(q->front+1)%MAXSIZE;
*x=q->data[q->front];
}
}
typedef struct node //邻接表结点
{
int adjvex;//邻接点域
struct node *next;
}EdgeNode;//邻接表结点类型
typedef struct vnode//顶点表结点
{
int vertex;//顶点域
EdgeNode *firstedge;//指向邻接表第一个邻接边结点的指针域
}VertexNode;//顶点表结点类型
void CreatAdjlist(VertexNodeg[],int e,int n)//建立无向图的邻接表
{
EdgeNode *p;
int i,j,k;
printf("Input date ofvetex(0~n-1):\n");
for(i=0;i<n;i++)//建立有n个顶点的顶点表
{
g[i].vertex=i;//读入顶点i的信息
g[i].firstedge=NULL;//初始化指向顶点i的邻接表表头指针
}
for(k=1;k<=e;k++)
{
printf("Input edgeof(i,j):");
scanf("%d,%d",&i,&j);
p=(EdgeNode *)malloc(sizeof(EdgeNode));
p->adjvex=j;
p->next=g[i].firstedge;
g[i].firstedge=p;
p=(EdgeNode *)malloc(sizeof(EdgeNode));
p->adjvex=i;//在顶点vj的邻接表中添加邻接点为i的结点
p->next=g[j].firstedge;//插入在表头进行
g[j].firstedge=p;
}
}
int visited[MAXSIZE];
void BFSTree(VertexNodeg[],int i)//生成广度优先生成树
{
int j,*x=&j;
SeQueue *q;
EdgeNode *p;
visited[i]=1;
Int_SeQueue(&q);
In_SeQueue(q,i);//顶点i入队
while(!Empty_SeQueue(q))
{
Out_SeQueue(q,x);//队头顶点出队并送j
p=g[j].firstedge;//根据顶点j的表头指针查找其邻接表的第一个邻接边结点
while(p!=NULL)
{
if(!visited[p->adjvex])//如果邻接的这个边结点未被访问过
{
printf("(%d,%d)",j,p->adjvex);//输出生成树中的一条边
visited[p->adjvex]=1;//置邻接边结点未访问过标志
In_SeQueue(q,p->adjvex);//将邻接边结点送入队q
}
p=p->next;//在顶点j的邻接表中查找j的下一个邻接边结点
}
}
}
void main()
{
int e,n;
VertexNode g[MAXSIZE];
printf("Inoput number of node:\n");//输入图中结点个数
scanf("%d",&n);
printf("Input number ofedge:\n");//输入图中边的个数
scanf("%d",&e);
printf("Make adjlist:\n");
CreatAdjlist(g,e,n);//建立无向图连接表
printf("BFSTraverse:\n");
BFSTree(g,0);//由顶点0开始生成广度优先生成树
printf("\n");
}
建立无向图的邻接矩阵
#include <stdio.h>
#include <stdlib.h>
#define MAXSIZE 30
typedef struct
{
charvertex[MAXSIZE];//顶点为字符型且顶点表的长度小于MAXSIZE
intedges[MAXSIZE][MAXSIZE];//边为整形且edges为邻接矩阵
}MGraph;//采用邻接矩阵存储的图类型
void CreatMGraph(MGraph *g,int e,int n)
{//建立无向图的邻接矩阵
int i,j,k;
printf("Inputdata of vertex(0~n-1):\n");
for(i=0;i<n;i++)
g->vertex[i]=i;//读入顶点信息
for(i=0;i<n;i++)
for(j=0;j<n;j++)
g->edges[i][j]=0;//初始化邻接矩阵
for(k=1;k<=e;k++)//输入e条边
{
printf("Inputedge of (i,j):");
scanf("%d,%d",&i,&j);
g->edges[i][j]=1;
g->edges[j][i]=1;
}
}
void main()
{
int i,j,n,e;
MGraph *g;//建立指向采用邻接矩阵存储图类型的指针
g=(MGraph*)malloc(sizeof(MGraph));//生成采用邻接矩阵存储类型的存储空间
printf("Inputsize of MGraph:");//输入邻接矩阵的大小
scanf("%d",&n);
printf("Inputnumbers of edge:");//输入邻接矩阵的边数
scanf("%d",&e);
CreatMGraph(g,e,n);//生成存储图的邻接矩阵
printf("OutputMGraph:\n");//输出存储图的邻接矩阵
for(i=0;i<n;i++)
{
for(j=0;j<n;j++)
printf("%4d",g->edges[i][j]);
printf("\n");
}
}
每一对顶点间最短路径的Floyd算法
#include <stdio.h>
#include <stdlib.h>
#define MAXSIZE 6
#define INF 32767
void Ppath(int path[][MAXSIZE],int i,int j)
{//前向递归查找路径上的顶点
int k;
k=path[i][j];
if(k!=-1)//顶点vk不是起点
{
Ppath(path,i,k);//找顶点vi的前一个顶点vk
printf("%d,",k);//输出顶点vk序号k
Ppath(path,k,j);//找顶点vk的前一个顶点vj
}
}
void Dispath(int A[][MAXSIZE],int path[][MAXSIZE],int n)
{
int i,j;
for(i=0;i<n;i++)
for(j=0;j<n;j++)
if(A[i][j]==INF)
{
if(i!=j)
printf("从%d到%d没有路径!\n",i,j);
}
else
{
printf("从%d到%d的路径长度: %d,路径: ",i,j,A[i][j]);
printf("%d,",i);//输出路径上的起点序号
Ppath(path,i,j);//输出路径上的各中间点序号
printf("%d\n",j);//输出路径上的终点序号
}
}
void Floyd(int gm[][MAXSIZE],int n)
{
intA[MAXSIZE][MAXSIZE],path[MAXSIZE][MAXSIZE];
int i,j,k;
for(i=0;i<n;i++)//初始化
for(j=0;j<n;j++)
{
A[i][j]=gm[i][j];//置初值
path[i][j]=-1;//初始时表示没有中间顶点
}
for(k=0;k<n;k++)//按顶点编号k递增的次序查找当前顶点之间的最短路径
for(i=0;i<n;i++)
if(A[i][j]>A[i][k]+A[k][j])
{
A[i][j]=A[i][k]+A[k][j];//从vi到vj经过vk时路径长度更短
path[i][j]=k;//记录中间顶点vk的编号
}
Dispath(gm,path,n);//输出最短路径
}
void main()
{
intg[MAXSIZE][MAXSIZE]={{INF,20,15,INF,INF,INF},{2,INF,INF,INF,10,30},{INF,4,INF,INF,INF,10},{INF,INF,INF,INF,INF,INF},{INF,INF,INF,5,INF,INF},{INF,INF,INF,4,10,INF}};
Floyd(g,MAXSIZE);//求每一对顶点之间的最短路径
}
深度优先生成树
#include <stdio.h>
#include <stdlib.h>
#define MAXSIZE 30
typedef struct node
{
int adjvex;
struct node *next;
}EdgeNode;
typedef struct vnode
{
int vertex;//顶点域
EdgeNode *firstedge;//指向邻接表第一个邻接边结点的指针域
}VertexNode;//顶点表结点类型
void CreatAdjlist(VertexNode g[],int e,int n)//建立无向图的邻接表
{
EdgeNode *p;
int i,j,k;
printf("Inputdata of vertex(0~n-1);\n");
for(i=0;i<n;i++)//建立有n个顶点的顶点表
{
g[i].vertex=i;//读入顶点i信息
g[i].firstedge=NULL;//初始化指向顶点i的邻接表表头指针
}
for(k=1;k<=e;k++)//输入e条边
{
printf("Inputedge of(i,j):");
scanf("%d,%d",&i,&j);
p=(EdgeNode*)malloc(sizeof(EdgeNode));
p->adjvex=j;
p->next=g[i].firstedge;
g[i].firstedge=p;
p=(EdgeNode*)malloc(sizeof(EdgeNode));
p->adjvex=i;//在顶点vj的邻接表中添加邻接点为j的结点
p->next=g[i].firstedge;//插入在邻接表表头进行
g[j].firstedge=p;
}
}
int visited[MAXSIZE];
void DFSTree(VertexNode g[],int i)//图的深度优先搜索
{
EdgeNode *p;
visited[i]=1;//置顶点i为访问过标志
p=g[i].firstedge;
while(p!=NULL)//当邻接边结点不为空时
{
if(!visited[p->adjvex])//如果邻接的这个边结点未被访问过
{
printf("(%d,%d)",i,p->adjvex);//输出生成树中的一条边
DFSTree(g,p->adjvex);//对这个结点进行深度优先搜索
}
p=p->next;//查找顶点i的下一个邻接边结点
}
}
void DFSTraverse(VertexNode g[],int n)//生成深度优先生成树
{
int i;
for(i=0;i<n;i++)
visited[i]=0;//访问标志置0
for(i=0;i<n;i++)//对n个顶点的图查找未访问过的顶点并由该节点开始遍历
if(!visited[i])
DFSTree(g,i);//comng未访问过的顶点i开始遍历
}
void main()
{
int e,n;
VertexNodeg[MAXSIZE];//定义顶点表结点类型数组
printf("Inputnumber of node:\n");//输入图中结点个数
scanf("%d",&n);
printf("Inputnumber of edge:\n");//输入图中边的个数
scanf("%d",&e);
printf("Makeadjlist:\n");
CreatAdjlist(g,e,n);//建立无向图连接表
printf("DFSTraversre :\n");
DFSTraverse(g,n);//生成深度优先生成树
printf("\n");
}
图的广度优先搜索
#include <stdio.h>
#include <stdlib.h>
#define MAXSIZE 30
typedef struct node1//邻接表结点
{
int adjvex;//邻接域
struct node1 *next;//指向下一个邻接边结点的指针域
}EdgeNode;//邻接表结点类型
typedef struct vnode//顶点表结点类型
{
int vertex;//顶点域
EdgeNode *firstedge;//指向邻接表第一个邻接边结点的指针域
}VertexNode;//顶点表结点类型
void CreatAdjlist(VertexNode g[],int e,int n)//建立无向图的邻接表
{
EdgeNode *p;
int i,j,k;
printf("Inputdata of vetex(0~n-1):\n");
for(i=0;i<n;i++)//建立有n个顶点的顶点表
{
g[i].vertex=i;//读入顶点i信息
g[i].firstedge=NULL;//初始化指向顶点i的邻接表表头指针
}
for(k=1;k<=e;k++)//输入e条边
{
printf("Inputedge of(i,j):");
scanf("%d,%d",&i,&j);
p=(EdgeNode*)malloc(sizeof(EdgeNode));
p->adjvex=j;//在顶点vi的邻接表中添加临界点为j的结点
p->next=g[i].firstedge;//插入是在邻接表表头进行
g[i].firstedge=p;
p=(EdgeNode*)malloc(sizeof(EdgeNode));
p->adjvex=i;//在顶点vj的邻接表中添加邻接点为i的结点
p->next=g[j].firstedge;//在插入是在表头进行
g[j].firstedge=p;
}
}
typedef struct node
{
int data;
struct node *next;
}QNode;//链队列结点类型
typedef struct
{
QNode *front,*rear;//将头、尾指针纳入到一个结构体的连队列
}LQueue;//链队列类型
void Init_LQueue(LQueue **q)//创建一个带头结点的空队列
{
QNode *p;
*q=(LQueue*)malloc(sizeof(LQueue));//申请队列
p=(QNode*)malloc(sizeof(QNode));//申请链队列头结点
p->next=NULL;//头结点的next指针置为空
(*q)->front=p;//对头结点指针指向头结点
(*q)->rear=p;//队尾指针指向头结点
}
int Empty_LQueue(LQueue *q)//判队空
{
if(q->front==q->rear)
return 1;
else
return 0;
}
void In_LQueue(LQueue *q,int x)//入队
{
QNode *p;
p=(QNode*)malloc(sizeof(QNode));//申请信新链队列结点
p->data=x;
p->next=NULL;//新结点作为队尾结点时其next域为空
q->rear->next=p;//将新结点*p链到原队尾结点之后
q->rear=p;//使队尾指针指向新的队尾结点*p
}
void Out_LQueue(LQueue *q,int *x)//出队
{
QNode *p;
if(Empty_LQueue(q))
printf("Queue isempty!\n");
else
{
p=q->front->next;//指针p指向链队列第一个数据结点
q->front->next=p->next;//头结点的next指针指向链队列第二个数据结点
*x=p->data;//将删除的头结点数据经x返回
free(p);
if(q->front->next==NULL)//出队后队为空,则值、置为空队列
q->rear=q->front;
}
}
int visited[MAXSIZE];
void BFS(VertexNode g[],LQueue *Q,int i)//广度优先搜索遍历邻接表存储图
{
int j,*x=&j;
EdgeNode *p;
printf("%4d",g[i].vertex);//输出顶点i信息
visited[i]=1;//置顶点i为访问过标志
In_LQueue(Q,i);//顶点i入队Q
while(!Empty_LQueue(Q))
{
Out_LQueue(Q,x);//队头顶点出队
p=g[j].firstedge;//根据顶点j的表头指针查找其邻接表的第一个邻接边结点
while(p!=NULL)
{
if(!visited[p->adjvex])//如果邻接的这个边未访问过
{
printf("%4d",g[p->adjvex].vertex);//输出邻接边的信息
visited[p->adjvex]=1;//置邻接边访问过
In_LQueue(Q,p->adjvex);//将该邻接边结点送入队Q
}
p=p->next;//在顶点的邻接表中查找下一个邻接边结点
}
}
}
void main()
{
int e,n;
VertexNodeg[MAXSIZE];//定义顶点表结点类型为数组
LQueue *q;
printf("Inputnumber of node:\n");//输入结点个数
scanf("%d",&n);
printf("Inputnumber of edge:\n");//输入图中边的个数
scanf("%d",&e);
printf("Makeadjlist :\n");
CreatAdjlist(g,e,n);//建立无向图的邻接表
Init_LQueue(&q);//队列初始化
printf("BFSTraverse:\n");
BFS(g,q,0);//广度优先遍历以邻接表存储的无向图
printf("\n");
}
图的连通性
#include <stdio.h>
#include <stdlib.h>
#define MAXSIZE 30
typedef struct node1
{
int adjvex;//邻接点域
struct node1 *next;//指向下一个邻接边结点的指针域
}EdgeNode;//邻接边结点类型
typedef struct vnode
{
int vertex;//顶点域
EdgeNode *firstedge;//指向邻接表第一个
}VertexNode;//顶点表结点类型
void CreatAdjilist(VertexNode g[],int e,int n)//建立无向图的邻接表
{
EdgeNode *p;
int i,j,k;
printf("Inputdata of vetex(0~n-1);\n");
for(i=0;i<n;i++)//建立有n个顶点的顶点表
{
g[i].vertex=i;//读入顶点i信息
g[i].firstedge=NULL;//初始化指向顶点i的邻接表表头指针
}
for(k=1;k<=e;k++)//输入e条边
{
printf("Inputedge of(i,j):");
scanf("%d,%d",&i,&j);
p=(EdgeNode*)malloc(sizeof(EdgeNode));
p->adjvex=j;//在顶点vi的邻接表中添加邻接点为j的结点
p->next=g[i].firstedge;//插入在邻接表表头进行
g[i].firstedge=p;
p=(EdgeNode*)malloc(sizeof(EdgeNode));
p->adjvex=i;
p->next=g[j].firstedge;//在顶点vj的邻接表中添加邻接点为i的结点
g[i].firstedge=p;
}
}
int visited[MAXSIZE];//MAZSIZE为大于等于无向图顶点个数的常量
void DFS(VertexNode g[],int i)//图的深度优先遍历
{
EdgeNode *p;
printf("%4d",g[i].vertex);//输出顶点i信息
visited[i]=1;//置i为访问过标志
p=g[i].firstedge;//根据顶点i的指针查找其邻接表的第一个邻接边结点
while(p!=NULL)
{
if(!visited[p->adjvex])//如果邻接点的这个边结点未被访问过
DFS(g,p->adjvex);//对这个边结点进行深度优先搜索
p=p->next;//查找顶点i的下一个邻接边结点
}
}
int count=0;//连通分量计数初值为0
void ConnecgtEdge(VertexNode g[],int n)//深度优先搜索遍历
{
int i;
for(i=0;i<n;i++)
visited[i]=0;//访问标志置0
for(i=0;i<n;i++)//对n个顶点的图查找未访问过的顶点并由该店开始遍历
if(!visited[i])//当visited【i】等于0时即顶点i未访问过
{
DFS(g,i);//从未访问过的顶点i开始遍历
count++;//访问过一个连通分量则count加一
}
}
void main()
{
int e,n;
VertexNodeg[MAXSIZE];//定义顶点表结点类型数组
printf("Inputnumber of node:\n");//输入图中结点的个数
scanf("%d",&n);
printf("Inputnumber of edge:\n");//输入图中边的个数
scanf("%d",&e);
printf("Makeadjlist :\n");
CreatAdjilist(g,e,n);//建立无向图的邻接表
printf("DFSTraverse:\n");
ConnecgtEdge(g,n);//求图的连通分量
printf("\nNumberof connect is %d\n",count);//输出连通分量
}
图的深度优先搜索
#include <stdio.h>
#include <stdlib.h>
#define MAXSIZE 30
typedef struct node
{
int adjvex;//邻接域
struct node *next;//指向下一个邻接边结点的指针域
}EdgeNode;//邻接表结点类型
typedef struct vnode//顶点表结点
{
int vertex;//顶点域
EdgeNode *firstedge;//指向邻接表第一个邻接边结点的指针域
}VertexNode;//顶点表结点类型
void CreatAdjlist(VertexNode g[],int e,int n)
{
EdgeNode *p;
int i,j,k;
printf("Inputdata of vetex(0~n-1):\n");
for(i=0;i<n;i++)//建立有n个顶点的顶点表
{
g[i].vertex=i;//读入顶点i信息
g[i].firstedge=NULL;//初始化指向顶点i的邻接表表头指针
}
for(k=1;k<=e;k++)//输入e条边
{
printf("Inputedge of(i,j):");
scanf("%d,%d",&i,&j);
p=(EdgeNode*)malloc(sizeof(EdgeNode));
p->adjvex=j;//在顶点vi的邻接表中添加结点为j的结点
p->next=g[i].firstedge;//插入是在邻接表表头进行的
g[i].firstedge=p;
p=(EdgeNode*)malloc(sizeof(EdgeNode));
p->adjvex=i;//在顶点vj的邻接表中添加邻接点为j的结点
p->next=g[j].firstedge;//插入是在邻接表表头进行
g[j].firstedge=p;
}
}
int visited[MAXSIZE];//MAXSIZE为大于或等于无向图顶点个数的常量
void DFS(VertexNode g[],int i)
{
EdgeNode *p;
printf("%4d",g[i].vertex);//输出顶点i的信息
visited[i]=1;//置顶点i为访问过标志
p=g[i].firstedge;//根据顶点i的指针firstedge查找其邻接表的第一个邻接边结点
while(p!=NULL)//当邻接边结点不为空
{
if(!visited[p->adjvex])//如果邻接的这个边结点未被访问过
DFS(g,p->adjvex);//对这个边结点进行深度优先搜索
p=p->next;//查找顶点i的下一个邻接边结点
}
}
void DfSTraverse(VertexNode g[],int n)//深度优先搜索遍历以邻接表存储的图
{
int i;
for(i=0;i<n;i++)
visited[i]=0;//访问标志置0
for(i=0;i<n;i++)//对n个顶点的图查找未访问过的顶点并由该顶点开始遍历
if(!visited[i])//当visited[i]未被访问过
DFS(g,i);//从未访问过的顶点i开始遍历
}
void main()
{
int e,n;
VertexNodeg[MAXSIZE];//定义顶点表结点类型数组g
printf("Inputnumber of node:\n");//输入图中结点个数
scanf("%d",&n);
printf("Inputnumber of edge:\n");//输入图中边的个数
scanf("%d",&e);
printf("Makeadjlist :\n");
CreatAdjlist(g,e,n);//建立无向图邻接表
printf("DFSTraverse :\n");
DfSTraverse(g,n);//深度优先遍历无向图
printf("\n");
}
拓扑排序
#include <stdio.h>
#include <stdlib.h>
#define MAXSIZE 30
typedef struct node //邻接表结点
{
int adjvex;//邻接点域
struct node *next;//指向下一个邻接边结点的指针域
}EdgeNode;//邻接表结点类型
typedef struct vnode//顶点表结点
{
int indegree;//顶点入度
int vertex;//顶点域
EdgeNode *firstedge;//指向邻接表第一个邻接边结点的指针域
}VertexNode;//顶点表结构结点类型
void CreatAdjlist(VertexNode g[],int e,int n)
{//建立有向图的邻接表
EdgeNode *p;
int i,j,k;
printf("Inputdata of vetex (0~n-1);\n");
for(i=0;i<n;i++)
{
g[i].vertex=i;
g[i].firstedge=NULL;
g[i].indegree=0;
}
for(k=1;k<=e;k++)
{
printf("Inputedge of(i,j):");
scanf("%d,%d",&i,&j);
p=(EdgeNode*)malloc(sizeof(EdgeNode));
p->adjvex=j;
p->next=g[i].firstedge;
g[i].firstedge=p;
g[j].indegree=g[j].indegree+1;
}
}
void Top_Sort(VertexNode g[],int n)
{//用带有入度域的邻接表存储AOV网并输出一种拓扑排序,n为顶点个数
int i,j,k,top,m=0;
EdgeNode *p;
top=-1;//栈顶指针初始化
for(i=0;i<n;i++)//依次将入度为0的顶点链接成一个链栈
if(g[i].indegree==0)
{
g[i].indegree=top;
top=i;
}
while(top!=-1)
{
j=top;//取出栈顶入读为0 的一个顶点
top=g[top].indegree;//栈顶指针指向弹栈后的下一个入读为0 的顶点
printf("%d,",g[j].vertex);//输出刚弹出栈的结点j信息
m++;//m记录已输出拓扑序列顶点个数
p=g[j].firstedge;//根据顶点j的firstedge指针查其邻接表的第一个邻接边结点
while(p!=NULL)//删除顶点j的所有边
{
k=p->adjvex;
g[k].indegree--;//将顶点j的邻接边结点k入读减一
if(g[k].indegree==0)//顶点k入读减1后若其值为0则将该顶点k链入链表
{
g[k].indegree=top;
top=k;
}
p=p->next;//查找顶点j的下一个邻接边结点
}
}
if(m<n)//输出顶点个数未达到n时则AOV网有回路
printf("TheAOV network has a cycle!\n");
}
void main()
{
int e,n;
VertexNode g[MAXSIZE];
printf("Inputnumber of node :\n");
scanf("%d",&n);
printf("Inputnumber of edge:\n");
scanf("%d",&e);
printf("Makeadjlist:\n");
CreatAdjlist(g,e,n);
printf("TopSort:\n");
Top_Sort(g,n);//拓扑排序
printf("\n");
}
最小生成树的Kruskal的算法
#include <stdio.h>
#include <stdlib.h>
#define MAXSIZE 30
#define MAXCOST 32767
typedef struct
{
int u;//边的起始顶点
int v;//边的终止顶点
int w;//边的权值
}Edge;
void Bubblesort(Edge R[],int e)//冒泡排序
{
Edge temp;
int i,j,swap;
for(i=0;i<e-1;j++)
{
swap=0;//置未交换标志
for(j=0;j<e-i-1;j++)
if(R[j].w>R[j+1].w)
{
temp=R[j];R[j]=R[j+1];R[j+1]=temp;
swap=1;//置有交换标志
}
if(swap==0)
break;//本趟比较中未出现交换则结束排序
}
}
void Kruskal(int gm[][6],int n)
{//构造最小生成树
inti,j,u1,v1,sn1,sn2,k;
int vest[MAXSIZE];
EdgeE[MAXSIZE];//MAXSIZE为可存放边数的最大值
k=0;
for(i=0;i<n;i++)
for(j=0;j<n;j++)
if(i<j&&gm[i][j]!=MAXCOST)//用数组E存储联通网中每条边的两个顶点及边上权值信息
{
E[k].u=i;
E[k].v=j;
E[k].w=gm[i][j];
k++;
}
Bubblesort(E,k);//采用冒泡排序对数组E中的k条边按权值递增排序
for(i=0;i<n;i++)//初始化辅助数组
vest[i]=i;//给每个顶点置不同连通分量编号
k=1;//k为当前构造生成树的第n条边,初值为1
j=0;//数组E中元素下标,初值为0
while(k<n)//产生最小生成树的n-1条边
{
u1=E[j].u;
v1=E[j].v;//取一条边的头尾顶点
sn1=vest[u1];
sn2=vest[v1];
if(sn1!=sn2)
{//两定点分属于不同集合则为该边最小生成树的一条边
printf("Edge:(%d,%d),Wight:%d\n",u1,v1,E[j].w);
k++;//生成的变数加一
for(i=0;i<n;i++)//俩个集合统一编号
if(vest[i]==sn2)//集合编号为sn2的第i号边其编号改为是你sn1
vest[i]=sn1;
}
j++;//扫描下一条边
}
}
void main()
{
intg[6][6]={{100,6,1,5,100,100},{6,100,5,100,3,100},{1,5,100,5,6,4},{5,100,5,100,100,2},{100,3,6,100,100,6},{100,100,4,2,6,100}};
Kruskal(g,6);//生成最小生成树
}
最小生成树的Prim算法
#include <stdio.h>
#include <stdlib.h>
#define MAXNODE 30
#define MAXCOST 32767
void Prim(int gm[][6],int closevertex[],int n)
{//建立最小生成树gm为邻接矩阵,n为顶点个数生成的最小生成素存储于closevertex中
int lowcost[MAXNODE];
int i,j,k,mincost;
for(i=1;i<n;i++)
{
lowcost[i]=gm[0][i];//边u0~ui的权值送入lowcost【i】
closevertex[i]=0;//假定顶点u1到顶点u0有一条边
}
lowcost[0]=0;//从序号为0的顶点出发生成最小生成树
closevertex[0]=0;
for(i=1;i<n;i++)//在n个顶点生成n-1条边的最小生成树
{
mincost=MAXCOST;//极大常量值
j=1;k=0;
while(j<n)//寻找未找到的最小权值边
{
if(lowcost[j]!=0&&lowcost[j]<mincost)
{
mincost=lowcost[j];//记下最小权值边的权值
k=j;//记下最小权值边在v-u集中的顶点序号j
}
j++;
}
printf("Edge:(%d,%d),Wight:%d\n",k,closevertex[k],mincost);//输出最小生成树的边和权值
lowcost[k]=0;//顶点k值进入u集
for(j=1;j<n;j++)
if(lowcost[j]!=0&&gm[k][j]<lowcost[j])
{//若点k进入u集后顶点k和另一顶点j构成的边权值变小则改变lowcost[j]为这个小zhi
lowcost[j]=gm[k][j];
closevertex[j]=k;
}
}
}
void main()
{
intclosevertex[MAXNODE];//存放最小生成树所有的边的数组
intg[6][6]={{100,6,1,5,100,100,},{6,100,5,100,3,100},{1,5,100,5,6,4},{5,100,5,100,100,2},{100,3,6,100,100,6},{100,100,4,2,6,100}};
Prim(g,closevertex,6);//生成最小生成树
}