Dijkstra算法

举例:

对一有向图如下图所示:



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算法简介 Dijkstra算法是一种用于解决单源最短路径问题的经典算法,适用于带权重的有向图或无向图中的最短路径计算[^1]。该算法的核心思想是从起始节点出发,逐步扩展已知距离最小的未访问节点,并更新其邻居节点的距离。 --- ### Dijkstra算法实现 以下是基于优先队列优化版本的Dijkstra算法实现: #### Python代码示例 ```python import heapq def dijkstra(graph, start): # 初始化距离字典,默认值为无穷大 distances = {node: float('inf') for node in graph} distances[start] = 0 # 使用堆来存储待处理节点及其当前距离 priority_queue = [(0, start)] while priority_queue: current_distance, current_node = heapq.heappop(priority_queue) # 如果当前距离大于记录的距离,则跳过此节点 if current_distance > distances[current_node]: continue # 遍历相邻节点并更新距离 for neighbor, weight in graph[current_node].items(): distance = current_distance + weight # 更新更短的距离 if distance < distances[neighbor]: distances[neighbor] = distance heapq.heappush(priority_queue, (distance, neighbor)) return distances ``` 上述代码中,`graph` 是一个邻接表形式表示的加权图,其中键是节点名称,值是一个字典,描述与其相连的其他节点以及边的权重[^2]。 --- ### Dijkstra算法的应用场景 1. **网络路由协议** 在计算机网络中,路由器可以利用Dijkstra算法找到到达目标地址的最佳路径,从而提高数据传输效率[^3]。 2. **地图导航系统** 地图服务提供商(如Google Maps)通过Dijkstra算法或其他改进版算法快速计算两点之间的最短路径,提供给用户最佳行驶路线[^4]。 3. **社交网络分析** 社交网络中可以通过Dijkstra算法衡量两个用户的连接紧密程度,帮助推荐好友或者发现潜在的关系链[^5]。 4. **物流配送规划** 物流公司使用类似的最短路径算法优化货物运输线路,减少成本和时间消耗[^6]。 --- ### 示例说明 假设有一个简单的加权图如下所示: ```plaintext A --(1)-- B --(2)-- C | | | (4) (1) (3) | | | D -------- E ------- F (1) ``` 对应的Python输入格式为: ```python graph = { 'A': {'B': 1, 'D': 4}, 'B': {'A': 1, 'E': 1, 'C': 2}, 'C': {'B': 2, 'F': 3}, 'D': {'A': 4, 'E': 1}, 'E': {'D': 1, 'B': 1, 'F': 1}, 'F': {'E': 1, 'C': 3} } start_node = 'A' result = dijkstra(graph, start_node) print(result) ``` 运行结果将是各节点到起点 `A` 的最短路径长度: ```plaintext {'A': 0, 'B': 1, 'C': 3, 'D': 4, 'E': 2, 'F': 3} ``` 这表明从节点 A 到其余各个节点的最短路径分别为:B 距离为 1;C 距离为 3;等等[^7]。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值