求Dijkstra算法的源代码
发布网友
发布时间:2022-04-10 04:41
我来回答
共8个回答
热心网友
时间:2022-04-10 06:10
直接给你(清华大学数据结构中关于图的所有操作,编译运行就可,不知道你的编译器是什么,应该不会报错~ 给分吧~
# define true 1
# define false 0
# define ok 1
# define error 0
# define overflow -2
# define null 0
typedef int status;
# include <stdio.h>
# include <stdlib.h>
# include <conio.h>
# define maxlen 10
# define large 999
typedef struct
{
int a[maxlen],b[maxlen],h[maxlen];/*第K边的起点,终点,权值*/
char vexs[maxlen];/*顶点信息集合*/
int vexnum,arcnum;/*顶点数和边数*/
int kind;/*图的类型*/
int arcs[maxlen][maxlen];/*邻接矩阵*/
}graph;
typedef struct node/*表结点结构*/
{
int adjvex;/*存放与头结点相邻接的顶点在数组中的序号*/
int info;/*权值*/
struct node *next;/*指向与头结点相邻接下一个顶点的表结点*/
}edgenode;
typedef struct/*头结点结构*/
{
int id;/*顶点入度*/
char data;/*顶点信息*/
edgenode *link;/*指向头结点对应的单链表中的表结点*/
}vexnode;
typedef struct/*邻接表结构*/
{
vexnode adjs[maxlen];/*邻接表的头结点集合*/
int vexnum,arcnum;/*顶点数,边数*/
int kind;
}adjlist;
typedef struct qnode/*队列存储结构*/
{int data;
struct qnode *next;
}linkqlist;
typedef struct
{linkqlist *front;/*队头指针*/
linkqlist *rear;/*队尾指针*/
} linkqueue;
typedef struct/*栈结构*/
{int stack[maxlen];
int top;
}stackstru;
int cnull=-1;
graph g;
adjlist adjl;
stackstru *t;/*拓扑序列顶点栈*/
stackstru *s;/*零入度顶点栈*/
linkqueue *q;
graph printf_adjmatrix(graph g)/*输出邻接矩阵*/
{
int i,j;
printf("邻接矩阵:\n");
printf("vertex\t");
for (i=0;i<g.vexnum;i++) printf("%4c",g.vexs[i]);
printf("\n");
for(i=0;i<g.vexnum;i++)
{ printf("% 4c \t",g.vexs[i]);
for(j=0;j<g.vexnum;j++) printf("%4d",g.arcs[i][j]);
printf("\n");
}
return g;
}
void create_1(graph g)
{
int i,j,k,c=0;
for (i=0;i<g.vexnum;i++)
for(j=0;j<g.vexnum;j++)
g.arcs[i][j]=c;
for(k=0;k<g.arcnum;k++)
g.arcs[g.a[k]-1][g.b[k]-1]=1;
printf_adjmatrix(g);
}
void create_2(graph g)
{
int i,j,k,c=0;
for (i=0;i<g.vexnum;i++)
for(j=0;j<g.vexnum;j++)
g.arcs[i][j]=c;
for(k=0;k<g.arcnum;k++)
{ g.arcs[g.a[k]-1][g.b[k]-1]=1;
g.arcs[g.b[k]-1][g.a[k]-1]=1;
}
printf_adjmatrix(g);
}
graph create_3(graph g)
{
int i,j,k,c=999;
for (i=0;i<g.vexnum;i++)
for(j=0;j<g.vexnum;j++)
g.arcs[i][j]=c;
for(k=0;k<g.arcnum;k++)
g.arcs[g.a[k]-1][g.b[k]-1]=g.h[k];
printf_adjmatrix(g);
return g;
}
graph create_4(graph g)
{
int i,j,k,c=999;
for (i=0;i<g.vexnum;i++)
for(j=0;j<g.vexnum;j++)
g.arcs[i][j]=c;
for (k=0;k<g.arcnum;k++)
{ g.arcs[g.a[k]-1][g.b[k]-1]=g.h[k];
g.arcs[g.b[k]-1][g.a[k]-1]=g.h[k];
}
printf_adjmatrix(g);
return g;
}
void creategraph(graph g)/*邻接矩阵*/
{
switch(g.kind)
{
case 1:create_1(g);break;
case 2:create_2(g);break;
case 3:create_3(g);break;
case 4:create_4(g);break;
default:printf("Error\n");
}
}
adjlist createlist (graph g ,adjlist adjl)/*邻接表*/
{
int i;
edgenode *p;
if(g.kind==1||g.kind==3)
{ for(i=0;i<adjl.arcnum;i++)
{ p=(edgenode*)malloc(sizeof(edgenode));
p->adjvex=g.b[i];
p->info=g.h[i];
p->next=adjl.adjs[g.a[i]-1].link;
adjl.adjs[g.a[i]-1].link=p;
}
}
if(g.kind==2||g.kind==4)
{ for(i=0;i<adjl.arcnum;i++)
{ p=(edgenode*)malloc(sizeof(edgenode));
p->info=g.h[i];
p->adjvex=g.b[i];
p->next=adjl.adjs[g.a[i]-1].link;
adjl.adjs[g.a[i]-1].link=p;
p=(edgenode*)malloc(sizeof(edgenode));
p->info=g.h[i];
p->adjvex=g.a[i];
p->next=adjl.adjs[g.b[i]-1].link;
adjl.adjs[g.b[i]-1].link=p;
}
}
printf("邻接表为:\n");
for(i=0;i<g.vexnum;i++)
{ printf("[%d,%c]=>",i+1,adjl.adjs[i].data);
p=adjl.adjs[i].link;
while(p!=cnull)
{printf("[%c,%d]-->",adjl.adjs[(p->adjvex)-1].data,p->info);
p=p->next;
}
printf("^\n");
}
return adjl;
}
void initqueue(linkqueue *p)
{ p->front=(linkqlist *)malloc(sizeof(linkqlist));
p->rear=p->front;
(p->front)->next=null;
}
status empty(linkqueue *q)
{int v;
if(q->front==q->rear) v=true;
else v=false;
return v;
}
status addqueue(linkqueue *q,int e)/*入队列*/
{
q->rear->next=(linkqlist *)malloc(sizeof(linkqlist));
q->rear=q->rear->next;
if(!q->rear) return -1;
q->rear->data=e;
q->rear->next=null;
}
status delqueue(linkqueue *q)/*出队列*/
{
linkqlist *p;
int e;
if (q->front==q->rear)
printf("the linklist is overflow");
else p=(q->front)->next;
(q->front)->next=p->next;
e=p->data;
if(q->rear==p)
q->rear=q->front;
free(p);/*释放P所指的内存区*/
return(e);
}
void DFS(int i, adjlist adjl)/*深度优先搜索*/
{edgenode *p;
int j;
int visited[maxlen];/*访问标志数组,访问过为1,未访问过为0*/
for(j=0;j<adjl.vexnum;j++) visited[j]=0;/*初始化,所有点都未访问*/
printf("%4c->",adjl.adjs[i-1].data);
visited[i-1]=1;
p=adjl.adjs[i-1].link;
while(p!=cnull)
{if (visited[(p->adjvex)-1]!=1) DFS((p->adjvex),adjl);
p=p->next;
}
}
void BFS(int i,adjlist adjl)/*广度优先搜索*/
{ edgenode *p;
int j;
int visited[maxlen];
for (j=0;j<adjl.vexnum;j++) visited[j]=0;/*初始化所有点*/
initqueue(q);
printf("%4c->",adjl.adjs[i-1].data);
visited[i-1]=1;
addqueue(q,i);
while(!empty(q))
{i=delqueue(q);
p=adjl.adjs[i-1].link;
while(p!=cnull)
{if (visited[(p->adjvex)-1]==0)
{printf("%4c->",adjl.adjs[p->adjvex-1].data);
visited[(p->adjvex)-1]=1;
addqueue(q,p->adjvex);
p=p->next;
}
}
}
}
status initstack(stackstru *s)/*构造空栈*/
{s->top=0;
return ok;
}
status push(stackstru *s,int x)/*入栈*/
{if (s->top==maxlen)
printf("the stack is overflow!\n");
else{ s->top=s->top+1;
s->stack[s->top]=x;
}
}
status pop(stackstru *s)
{ int y;
if(s->top==0)printf("the stack is empty!\n");
else {y=s->stack[s->top];
s->top=s->top-1;
}
return y;
}
status stackempty(stackstru *s)
{ if (s->top==maxlen) return (true);
else return (false);
}
status topsort(adjlist adjl)/*拓扑排序*/
{
int i,k,count;
edgenode *p;
printf("拓扑排序序列为:\n");
initstack(s);
for(i=0;i<adjl.vexnum;i++)
if(adjl.adjs[i].id==0) push(s,adjl.adjs[i].data);
count=0;
while(!stackempty(s))
{ i=pop(s);
printf("%4c->",adjl.adjs[i].data);
++count;
for(p=adjl.adjs[i].link;p;p=p->next)
{ k=p->adjvex;
if(!(--adjl.adjs[k-1].id)) push(s,k-1);
}
}
if(count<adjl.vexnum)
{ printf("\n网中有环!\n"); /*拓扑排序输出的顶点数<图中的顶点数*/
return error;
}
else return ok;
}
void prim(graph g)/*最小生成树*/
{
int i,j,k,min;
int lowcost[maxlen];/*权值*/
int closet[maxlen];/*最小生成树结点*/
printf("最小生成树的边为:\n");
for(i=1;i<g.vexnum;i++)
{
lowcost[i]=g.arcs[0][i];
closet[i]=1;
}
closet[1]=0;
j=1;
for(i=1;i<g.vexnum;i++)
{
min=lowcost[j];
k=i;
for(j=1;j<g.vexnum;j++)
if(lowcost[j]<min&&closet[j]!=0)
{
min=lowcost[j];
k=j;
}
printf("(%c,%c),",g.vexs[k-1],g.vexs[closet[k-1]]);
closet[k]=0;
for(j=1;j<g.vexnum;j++)
if(g.arcs[k][j]<lowcost[j]&&closet[j]!=0)
{
lowcost[j]=g.arcs[k][j];
closet[j]=k;
}
}
}
int ve[maxlen];/*最早发生时间*/
int vl[maxlen];/*最迟发生时间*/
status toporder(adjlist adjl,stackstru *t)/*求各顶点事件的最早发生时间ve*/
{ int i,j,count,k;
edgenode *p;
initstack(s);
initstack(t);
for(i=0;i<adjl.vexnum;i++)
if(adjl.adjs[i].id==0) push(s,i);
count=0;
for(i=0;i<adjl.vexnum;i++) ve[i]=0;
while(!stackempty(s))
{ j=pop(s);push(t,j);++count;
for(p=adjl.adjs[j].link;p;p=p->next)
{ k=p->adjvex;
if(--adjl.adjs[k-1].id==0) push(s,k-1);
if(ve[j]+(p->info)>ve[k-1]) ve[k-1]=ve[j]+(p->info);
}
}
if(count<adjl.vexnum) return error;
else return ok;
}
status criticalpath(adjlist adjl)/*关键路径*/
{ int i,j,k,t,ee,el;
edgenode *p;
if(!toporder(adjl,t)) return error;
for(i=0;i<adjl.vexnum;i++) vl[i]=ve[i-1];/*初始化顶点事件的最迟发生时间*/
printf("关键路径为:\n");
while(!stackempty(t))/*按拓扑排序的逆序求各顶点的最迟发生时间ve值*/
for(j=pop(t), p=adjl.adjs[j].link;p;p=p->next)
{ k=p->adjvex; t=(p->info);
if(vl[k]-t<vl[j]) vl[j]=vl[k]-t;
}
for(j=0;j<adjl.vexnum;++j)/*求ee,el和关键活动*/
for(p=adjl.adjs[j].link;p;p=p->next)
{ k=p->adjvex;t=p->info;
ee=ve[j];el=vl[k-1]-t;
if(ee==el) printf("(%c,%c)->",adjl.adjs[j].data,adjl.adjs[k-1].data);
}
}
void shortpath_dijkstra(graph g)
{ int cost[maxlen][maxlen];
int dist[maxlen];/*某源点到各顶点的最短路径长度*/
int path[maxlen];/*某源点到终点经过的顶点集合的数组*/
int s[maxlen];/*最短路径的终点集合*/
int i,j,n,v0,min,u;/*U存放最短路径的终点*/
printf("\n请输入起点的编号:");
scanf("%d",&v0);
v0--;
for(i=0;i<g.vexnum;i++)
{for(j=0;j<g.vexnum;j++)
cost[i][j]=g.arcs[i][j];
}
for(i=0;i<g.vexnum;i++)
{ dist[i]=cost[v0][i];
if(dist[i]<large&&dist[i]>0) path[i]=v0;
s[i]=0;
}
s[v0]=1;
for(i=0;i<g.vexnum;i++)
{ min=large;
u=v0;
for(j=0;j<g.vexnum;j++)
if(s[j]==0&&dist[j]<min)
{min=dist[j];u=j;}
s[u]=1; /*U顶点是求得最短路径的顶点编号*/
for(j=0;j<g.vexnum;j++)
if(s[j]==0&&dist[u]+cost[u][j]<dist[j])
{ dist[j]=dist[u]+cost[u][j];
path[j]=u;
}
}
printf("\n顶点%d到各顶点的最短路径长度为:\n",v0);
for(i=0;i<g.vexnum;i++)/*输入结果*/
if(s[i]==1)
{ u=i;
while(u!=v0)
{ printf("%4c<-",g.vexs[u]);
u=path[u];
}
printf("%4c",g.vexs[u]);
printf(":%d\n",path[i]);
}
else printf("%4c<-%4c:无路径\n",g.vexs[i],g.vexs[v0]);
}
void shortpath_floyd(graph g)
{ int path[maxlen][maxlen];
int short3[maxlen][maxlen];/*权值*/
int i,j,k;
for(i=0;i<g.vexnum;i++)
for(j=0;j<g.vexnum;j++)
{ short3[i][j]=g.arcs[i][j];
path[i][j]=0;
}
printf("\n各顶点间的最短路径为:\n");
for(k=0;k<g.vexnum;k++)
for(i=0;i<g.vexnum;i++)
{ if(short3[i][j]>(short3[i][k]+short3[k][j]))
{ short3[i][j]=short3[i][k]+short3[k][j];
path[i][j]=k;
}
printf("(%4c->%4c):%d",g.vexs[i-1],g.vexs[j-1],short3[i][j]);
}
}
main()
{
int a,i,j,k,h;
printf("\n请输入图的类型(1:有向图 2:无向图 3:有向网 4:无向网):");
scanf("%d",&i);
{g.kind=i;adjl.kind=i;}
printf("请输入顶点数,边数:");
scanf("%d,%d",&i,&j);
g.vexnum=i;adjl.vexnum=i;
g.arcnum=j;adjl.arcnum=j;
for (i=0;i<g.vexnum;i++)
{ printf("第%d个顶点的信息:",i+1);
scanf("%s",&g.vexs[i]);
adjl.adjs[i].data=g.vexs[i];
adjl.adjs[i].link=cnull;
adjl.adjs[i].id=0;
}
for (k=1;k<=g.arcnum;k++)
{label:if (g.kind==1||g.kind==3)
printf("第%d条边的起点编号,终点编号:",k);
else printf("第%d条边的两个顶点的编号:",k);
scanf("%d,%d",&i,&j);
g.a[k-1]=i;g.b[k-1]=j;
while (i<1||i>g.vexnum||j<1||j>g.vexnum)
{printf(" 编号超出范围,重新输入");goto label;
}
if (g.kind==3||g.kind==4)
{printf("\t该边的权值:");
scanf("%d",&h);
g.h[k-1]=h;
}
else g.h[k-1]=null;
adjl.adjs[i].id++;
}
loop1:printf("\n1__邻接矩阵\n");
printf("2__邻接表\n");
printf("3__深度优先搜索\n");
printf("4__广度优先搜索\n");
printf("5__最小生成树\n");
printf("6__拓扑排序\n");
printf("7__关键路径\n");
printf("8__从某个源点到其余各顶点的最短路径\n");
printf("9__每一对顶点之间的最短路径\n");
loop:printf("请选择图的实现:\t");
scanf("%d",&a);
switch(a)
{
case 1:creategraph(g);break;
case 2:createlist(g,adjl);break;
case 3:printf("请输入出发点编号:");
scanf("%d",&k);
createlist(g,adjl);
printf("\n从第%d点出发深度优先搜索遍历序列:",k);
DFS(k,adjl);break;
case 4:printf("请输入出发点编号:");
scanf("%d",&k);
createlist( g,adjl);
printf("\n从第%d点出发广度优先搜索遍历序列:",k);
BFS( k,adjl);
break;
case 5:if (g.kind==4)
{create_4(g); prim(g);}
else{printf("\t不能构造最小生成树,请重新选择:\n");goto loop;}
break;
case 6:if (g.kind==1||g.kind==3)
{createlist(g,adjl); topsort(adjl);}
else{printf("\t不能拓扑排序,请重新选择:\n");goto loop;}
break;
case 7:if (g.kind==3)
{createlist(g,adjl);
criticalpath( adjl);
}
else{printf("\t没有关键路径,请重新选择:\n");goto loop;}
break;
case 8:if (g.kind==3)
{create_3(g); shortpath_dijkstra(g);}
else{printf("\t没有最短路径,请重新选择:\n");goto loop;}
break;
case 9:if (g.kind==3)
{create_3(g); shortpath_floyd(g);}
else{printf("\t没有最短路径,请重新选择:\n");goto loop;}
break;
default:printf(" \n\t*** wrong ***\n");
}/*switch*/
goto loop1;
}/*main()*/
热心网友
时间:2022-04-10 07:28
Dijkstra算法--c++源代码--
#include<iostream.h>
void main()
{
int infinity=100,j,i,n,k,t,**w,*s,*p,*d;
cout<<"input the value of n:";
cin>>n;
cout<<endl;
d=new int[n];
s=new int[n];
p=new int[n];
w=new int*[n];
for(i=0;i<n;i++) {w[i]=new int[n];}
for(i=0;i<n;i++)
for(j=0;j<n;j++)
cin>>w[i][j];
for(s[0]=1,i=1;i<n;i++)
{
s[i]=0;d[i]=w[0][i];
if(d[i]<infinity) p[i]=0;
else p[i]=-1;
}
for(i=1;i<n;i++)
{
t=infinity;k=1;
for(j=1;j<n;j++)
if((!s[j])&&(d[j]<t)) {t=d[j];k=j;}
s[k]=1;//point k join the S
for (j=1;j<n;j++)
if((!s[j])&&(d[j]>d[k]+w[k][j]))
{d[j]=d[k]+w[k][j];p[j]=k;}
}
cout<<"从源点到其它顶点的最短距离依次如下:";
for(i=1;i<n;i++) cout<<d[i]<<" ";
}
/*********
顶点个数用n表示,这里给出的例子n=6
100 1 12 100 100 100
100 100 9 3 100 100
100 100 100 100 5 100
100 100 4 100 13 15
100 100 100 100 100 4
100 100 100 100 100 100
具体例子见 电子工业出版社 《算法设计技巧与分析》148页
************/
热心网友
时间:2022-04-10 09:03
C语言代码://清华大学出版社光盘的代码
void ShortestPath_DIJ(MGraph G,int v0,PathMatrix &P,ShortPathTable &D)
{ // 算法7.15
// 用Dijkstra算法求有向网G的v0顶点到其余顶点v的最短路径P[v]
// 及其带权长度D[v]。
// 若P[v][w]为TRUE,则w是从v0到v当前求得最短路径上的顶点。
// final[v]为TRUE当且仅当v∈S,即已经求得从v0到v的最短路径。
int i=0,j, v,w,min;
bool final[MAX_VERTEX_NUM];
for (v=0; v<G.vexnum; ++v) {
final[v] = FALSE;
D[v] = G.arcs[v0][v].adj;
for (w=0; w<G.vexnum; ++w) P[v][w] = FALSE; // 设空路径
if (D[v] < INFINITY) { P[v][v0] = TRUE; P[v][v] = TRUE; }
}
D[v0] = 0; final[v0] = TRUE; // 初始化,v0顶点属于S集
//--- 开始主循环,每次求得v0到某个v顶点的最短路径,并加v到S集 ---
for (i=1; i<G.vexnum; ++i) { // 其余G.vexnum-1个顶点
min = INFINITY; // 当前所知离v0顶点的最近距离
for (w=0; w<G.vexnum; ++w)
if (!final[w]) // w顶点在V-S中
if (D[w]<min) { v = w; min = D[w]; } // w顶点离v0顶点更近
final[v] = TRUE; // 离v0顶点最近的v加入S集
for (w=0; w<G.vexnum; ++w) // 更新当前最短路径及距离
if (!final[w] && (min+G.arcs[v][w].adj<D[w])) {
// 修改D[w]和P[w], w∈V-S
D[w] = min + G.arcs[v][w].adj;
for(j=0;j<G.vexnum;j++) P[w][j] = P[v][j]; //第v行赋值于第w行
P[w][w] = TRUE; // P[w] = P[v]+[w]
}//if
}//for
} // ShortestPath_DIJ
热心网友
时间:2022-04-10 10:54
下面是在百度上找到的一篇,已经发到你的邮箱里面了:)
Dijkstra算法--c++源代码--by 伟伟猪 [转贴 2005-12-15 20:21:00 ] 发表者: 伟伟猪
/***********************************************
设G=(V,E)是一个每条边都有非负长度的有向图,有一个特异的顶点s称为缘。
单源最短路径问题,或者称为最短路径问题,是要确定从s到V中没一个其他
顶点的距离,这里从顶点s到x的距离定义为从s到x的最短路径问题。这个问题
可以用Dijkstra算法解决。下面我给我了c++下的源代码! --by 伟伟猪
************************************************/
#include<iostream.h>
void main()
{
int infinity=100,j,i,n,k,t,**w,*s,*p,*d;
cout<<"input the value of n:";
cin>>n;
cout<<endl;
d=new int[n];
s=new int[n];
p=new int[n];
w=new int*[n];
for(i=0;i<n;i++)
for(i=0;i<n;i++)
for(j=0;j<n;j++)
cin>>w[i][j];
for(s[0]=1,i=1;i<n;i++)
{
s[i]=0;d[i]=w[0][i];
if(d[i]<infinity) p[i]=0;
else p[i]=-1;
}
for(i=1;i<n;i++)
{
t=infinity;k=1;
for(j=1;j<n;j++)
if((!s[j])&&(d[j]<t))
s[k]=1;//point k join the S
for (j=1;j<n;j++)
if((!s[j])&&(d[j]>d[k]+w[k][j]))
}
cout<<"从源点到其它顶点的最短距离依次如下:";
for(i=1;i<n;i++) cout<<d[i]<<" ";
}
/*********
顶点个数用n表示,这里给出的例子n=6
100 1 12 100 100 100
100 100 9 3 100 100
100 100 100 100 5 100
100 100 4 100 13 15
100 100 100 100 100 4
100 100 100 100 100 100
具体例子见 电子工业出版社 《算法设计技巧与分析》148页
************/
热心网友
时间:2022-04-10 13:02
我本人比较喜欢算法,
地杰斯特拉算法是在图中找最短路径用的
你的需求没有写清楚,看的人不清楚
第一 你没有给具体的图的拓扑结构
第二 你没有给出算法要完成的任务(指定时间,指定出发点和终点)
所以 请 将你的需求写清楚!让人家知道你想问什么
热心网友
时间:2022-04-10 15:27
不知所云。。
热心网友
时间:2022-04-10 18:08
没看懂……权值怎么来的?
起点和终点呢?时间和长度有什么关系?
热心网友
时间:2022-04-10 21:06
可你要求什么呢????????????