Dijkstra算法

举例:

对一有向图如下图所示:

Dijkstra算法_第1张图片

Dijkstra算法_第2张图片

data.txt数据如下:

7 12    顶点和边数


0 1 2 3 4 5 6  顶点name


0 1 2                顶点与顶点之间的权值
0 3 1
1 3 3
1 4 10
2 0 4
2 5 5
3 2 2
3 4 2
3 5 8
3 6 4
4 6 6
6 5 1


代码如下:

// Dijkstra.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include <stdlib.h>

#define MAX_VERTEX_NUM 20
#define MAX_VALUE_TYPE INT_MAX

typedef int VertexType;

int visit[MAX_VERTEX_NUM];

typedef struct node
{
	VertexType adjvex;
	int weight;
	struct node* next;
}EdgeNode;                //边表节点

typedef struct vnode
{
	VertexType vertex;
	int        dist;
	int        len;
	int        path[MAX_VERTEX_NUM];
	EdgeNode *firstedge;
}VertexNode;             //表头节点

typedef VertexNode adjList[MAX_VERTEX_NUM];

typedef struct  
{
	adjList adjlist;
	int n, e;
}ALGraph;


void CreateALGraph(ALGraph *G)
{
	int i, j;
	int k;

	EdgeNode *s;

	scanf("%d%d", &G->n, &G->e);

	for (i = 0; i <G->n; i++) 
	{  

		scanf("%d", &G->adjlist[i].vertex);  
		G->adjlist[i].firstedge = NULL;//边表设置成空表  
	}  

	for (k = 1; k <= G->e; k++)  
    {  
        int nwight = 0;  
        scanf("%d%d", &i, &j);//i = Locate(G, i); j = Locate(G, j); //查找结点序号  
        s = (EdgeNode *)malloc(sizeof(EdgeNode)); 
        scanf("%d", &nwight);  
        s->weight = nwight;  
        s->adjvex = j;//邻接点序号为j  
        s->next = G->adjlist[i].firstedge;  
        G->adjlist[i].firstedge = s;  
  
          
		s = (EdgeNode *)malloc(sizeof(EdgeNode)); 
		s->adjvex = i; 
		s->weight = nwight; 
		s->next = G->adjlist[j].firstedge; 
		G->adjlist[j].firstedge = s;  
    }  
	
}

void print(ALGraph *G)  
{  
	EdgeNode *p;  
	int i;  
	for(i=0; i<G->n; i++)  
	{  
		printf("index %d VERTEX %d", i, G->adjlist[i].vertex);  
		for(p = G->adjlist[i].firstedge; p ; p = p->next)  
		{  
			printf("->\tVERTEX %d weight %d", p->adjvex, p->weight);  
		}  
		putchar('\n');  
	}  
}  

void GetNewPathWay( ALGraph * g , int k , int i )///---------更新路径函数-------------------------  
{  
	int j;  
	for( j = 0 ; j <= g->adjlist[k].len ; j++ )  
		g->adjlist[i].path[j] = g->adjlist[k].path[j]; //拷贝k中的路径

	g->adjlist[i].path[j] = i;  
}  

void ShowPathWay( ALGraph * g , int y )///----------------------输出路径函数-------------------------  
{  
	/*int i , j;  
	for( i = 0 ; i <= g->adjlist[y].len ; i++)  
	{
	if( g->adjlist[y].path[i] != y )
	{  
	printf("最短路径是:\n");  
	for( j = 0 ; j < i ; j ++)
	{  
	printf("%s->",g->adjlist[g->adjlist[y].path[j]].vertex);  
	}  
	printf("%s\n\n",g->adjlist[g->adjlist[y].path[j]].vertex );  
	printf("最短距离为:\n");  
	printf("%d\n\n",g->adjlist[y].dist);  

	}  
	}
	printf("\nERROR:\n");  
	printf("没有通路\n\n");  */

	int i,j;
	printf("最短路径是:\n");
	for ( i = 0; i <= g->adjlist[y].len; i++)
	{
		printf("%d->",g->adjlist[g->adjlist[y].path[i]].vertex + 1);
	}
	printf("\n最短距离为:\n");
    printf("%d\n\n",g->adjlist[y].dist);
}  

void Visit( ALGraph * g )///-------------初始化路径  
{  
	int i,j;  
	for( i = 0 ; i <g->n ; i ++)
	{  
		visit[i] = false;  
		g->adjlist[i].dist = INT_MAX;  
		g->adjlist[i].len = 0;  
		for( j = 0 ; j < g->n ; j ++ )  
		g->adjlist[i].path[j] = INT_MAX;  
	}  
}  

void Dijkstra( ALGraph * g )///---------------------DIJKSTRA算法---(权值无负数)---------------------------  
{  

	printf("请输入 开始点 和 结束点:\n");  
	int x ,y;  
	while( (scanf("%d",&x))!= EOF , x != -1 && x != 0 && x <= g->n )
	{  
		Visit( g ); //初始化路径 
		int i , j ,  k , m , min = 0 , t;  
		g->adjlist[x-1].dist = 0;  
		g->adjlist[x-1].path[0] = x-1; 
		k = x-1;  
		EdgeNode * p;  
		for( i = 0 ; i < g->n ; i ++)//计算每个点到其实点的距离
		{ 
			t = INT_MAX;  
			p = g->adjlist[k].firstedge;  
			visit[k] = true; //k表示已经访问了 
			while( p )
			{  
				if( !visit[p->adjvex])//如果这个节点没有访问过
				{  
					if( g->adjlist[k].dist == INT_MAX )
					{  
						g->adjlist[p->adjvex].dist = p->weight;  
						g->adjlist[p->adjvex].len = g->adjlist[k].len+1;  
						GetNewPathWay( g , k , p->adjvex);  
					}  
					else if( g->adjlist[k].dist + p->weight < g->adjlist[p->adjvex].dist )
					{  
						g->adjlist[p->adjvex].dist = g->adjlist[k].dist + p->weight;  
						g->adjlist[p->adjvex].len = g->adjlist[k].len+1;  
						GetNewPathWay( g ,k , p->adjvex);  
					}  
				}  

				p = p->next;  
			}

			for( j = 0 ; j < g->n ; j++)
			{  
				if( g->adjlist[j].dist < t && !visit[j] )
				{  
					t = g->adjlist[j].dist;  
					min = j;  
				}  
			}  
			k = min;  
		}

		while(scanf("%d",&y)!=EOF , y != -1 && y != 0 && y <= g->n )
		{  
			
			ShowPathWay( g ,y-1 );  
			printf("请输入%d--> 的下一个顶点(-1结束): \n",x ); 
			break;
		}  
		printf("请输入 开始点 和结束点 (-1结束):\n");  
		break;
	}  
}  

int _tmain(int argc, _TCHAR* argv[])
{
	FILE *fp;
	fp = freopen("my.txt", "r", stdin);
	ALGraph G;
	CreateALGraph(&G);
	/*fclose(fp);*/
	print(&G);
	Dijkstra(&G);


	return 0;
}


你可能感兴趣的:(Dijkstra算法)