C语言实现Dijkstra算法(邻接矩阵与邻接表存储方式)

C语言实现Dijkstra算法(邻接矩阵与邻接表存储方式)

  • 代码

    #include <stdio.h>
    #include <stdlib.h>
    typedef int ArcType;
    typedef char VerTextType[20];
    
    #define MVNum 100 //顶点最大数
    #define INF 0x3f3f3f3f
    
    //图的邻接矩阵(Adjacency Matrix)表示
    typedef struct
    {
        VerTextType vexs[MVNum]; //顶点表
        ArcType arcs[MVNum][MVNum]; //邻接矩阵
        int vexnum; //顶点数
        int arcnum; //边数
    } AMGraph; 
    
    
    //图的邻接表存储
    typedef struct ArcNode //边结点
    {
        int adjver; //该边所指向的顶点位置
        struct ArcNode *nextarc; //指向下一条边的指针
        ArcType   weight;
    } ArcNode;
    
    typedef struct VNode //顶点信息
    {
        VerTextType data;
        ArcNode     *firstarc;
    } VNode, AdjList[MVNum];
    
    typedef struct node
    {
        AdjList vertices;
        int     vexnum; //图的当前顶点数
        int     arcnum; //图的当前边数
    } ALGraph; 
    
    //临接矩阵存储方式求最短路(dijkstra),复杂度O(n^2)
    //v0表示起点,D[i]表示从v0到i的最短路径长度,path存储路径
    void ShortestPath_DIJ1(AMGraph G, int v0, ArcType D[], int Path[])
    {
        int ok[MVNum], i, j; // ok数组标记是否确定最短路径
        for(i = 0; i < G.vexnum; i++) {
        	ok[i] = 0;
        	Path[i] = -1;
        	D[i] = INF;
        }
        D[v0] = 0;
        for(i = 0; i < G.vexnum; i++) {
        	int min_node = -1;
        	for(j = 0; j < G.vexnum; j++) {
        		if(ok[j] == 0 && (min_node == -1 || D[j] < D[min_node])) {
        			min_node = j;
        		}
        	}
        	if(min_node == -1) break;
        	ok[min_node] = 1;
    
        	for(j = 0; j < G.vexnum; j++) {
        		if(ok[j] == 0 && G.arcs[min_node][j] != 0 && D[j] > D[min_node] + G.arcs[min_node][j]){
        			D[j] = D[min_node] + G.arcs[min_node][j];
        			Path[j] = min_node;
        		}
        	}
    
        }
    
    }
    
    //临接表存储方式最短路径(dijkstra),复杂度O(n^2)
    void ShortestPath_DIJ2(ALGraph G, int v0, ArcType D[], int Path[])
    {
        int ok[MVNum], i, j; // ok数组标记是否确定最短路径
        for(i = 0; i < G.vexnum; i++) {
        	ok[i] = 0;
        	Path[i] = -1;
        	D[i] = INF;
        }
        D[v0] = 0;
        for(i = 0; i < G.vexnum; i++) {
        	int min_node = -1;
        	for(j = 0; j < G.vexnum; j++) {
        		if(ok[j] == 0 && (min_node == -1 || D[j] < D[min_node])) {
        			min_node = j;
        		}
        	}
        	if(min_node == -1) break;
        	ok[min_node] = 1;
    
        	ArcNode * cur = G.vertices[min_node].firstarc;
        	while(cur != NULL) {
        		if(ok[cur -> adjver] == 0 && D[cur -> adjver] > D[min_node] + cur -> weight) {
        			D[cur -> adjver] = D[min_node] + cur -> weight;
        			Path[cur -> adjver]  = min_node;
        		}
        		cur = cur -> nextarc;
        	}
        }
    
    }
    
    //输入图
    void init_graph(AMGraph *g1, ALGraph *g2) {
    	int n,m;
    	scanf("%d %d",&n,&m);  //输入顶点数和边数
    	g1-> vexnum = g2-> vexnum = n;
    	g1-> arcnum = g2-> arcnum = m;
    
    	for(int i=0;i<MVNum;i++) for(int j=0;j<MVNum;j++) g1-> arcs[i][j]=0;
    	for(int i=0;i<MVNum;i++) g2-> vertices[i].firstarc = NULL;
    
    	for(int i=1;i<=m;i++) {
    		int u,v,w;
    		scanf("%d %d %d",&u,&v,&w);
    		g1-> arcs[u][v] = w;
    
    		ArcNode *cur = g2-> vertices[u].firstarc;
    		if(cur == NULL) {
    			g2-> vertices[u].firstarc = (ArcNode *) malloc(sizeof(ArcNode));
    			g2-> vertices[u].firstarc -> adjver = v;
    			g2-> vertices[u].firstarc -> weight = w;
    			g2-> vertices[u].firstarc -> nextarc = NULL;
    		}else{
    			while(cur ->nextarc != NULL) {  //暴力处理,建议记录尾指针
    				cur = cur -> nextarc;
    			}
    			cur -> nextarc = (ArcNode *) malloc(sizeof(ArcNode));
    			cur = cur -> nextarc;
    			cur -> adjver = v;
    			cur -> weight = w;
    			cur -> nextarc = NULL;
    		}
    	}
    }
    
    int main() {
    	AMGraph g1;
    	ALGraph g2;
    	init_graph(&g1,&g2);
    	int d1[MVNum],d2[MVNum],path1[MVNum],path2[MVNum];
    	ShortestPath_DIJ1(g1,0,d1,path1);
    	for(int i =0;i<g1.vexnum;i++) printf("%d ",path1[i]);
    	printf("\n");
    	ShortestPath_DIJ2(g2,0,d2,path2);
    	for(int i =0;i<g2.vexnum;i++) printf("%d ",path2[i]);
    	printf("\n");
    }
    
    
  • 0
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Dijkstra算法是一种用于计算单源最短路径的贪心算法。该算法的基本思想是从起点开始,逐步向外扩展搜索范围,直到找到终点为止。在搜索过程中,我们会维护一个距离数组,用于记录每个节点到起点的最短距离,同时还需要维护一个标记数组,用于标记哪些节点已经被访问过。 以下是使用C语言实现Dijkstra算法计算单源最短路径的代码示例: ```c #include <stdio.h> #include <limits.h> #define V 6 // 中的节点数 int minDistance(int dist[], int visited[]) { int min = INT_MAX, min_index; for (int i = 0; i < V; i++) { if (visited[i] == 0 && dist[i] <= min) { min = dist[i]; min_index = i; } } return min_index; } void dijkstra(int graph[V][V], int start) { int dist[V]; // 用于记录每个节点到起点的最短距离 int visited[V]; // 用于标记哪些节点已经被访问过 for (int i = 0; i < V; i++) { dist[i] = INT_MAX; visited[i] = 0; } dist[start] = 0; for (int i = 0; i < V - 1; i++) { int u = minDistance(dist, visited); visited[u] = 1; for (int v = 0; v < V; v++) { if (!visited[v] && graph[u][v] && dist[u] != INT_MAX && dist[u] + graph[u][v] < dist[v]) { dist[v] = dist[u] + graph[u][v]; } } } printf("节点\t距离\n"); for (int i = 0; i < V; i++) { printf("%d\t%d\n", i, dist[i]); } } int main() { int graph[V][V] = { {0, 4, 0, 0, 0, 0}, {4, 0, 8, 0, 0, 0}, {0, 8, 0, 7, 0, 4}, {0, 0, 7, 0, 9, 14}, {0, 0, 0, 9, 0, 10}, {0, 0, 4, 14, 10, 0} }; dijkstra(graph, 0); return 0; } ``` 上述代码中,我们首先定义了一个6个节点的,并将其表示邻接矩阵的形式。接下来,我们定义了`minDistance`函数,用于查找距离起点最近的未访问节点。然后,在`dijkstra`函数中,我们初始化距离数组和标记数组,然后从起点开始,依次查找距离起点最近的节点,并更新与该节点相邻的节点的距离。最后,输出每个节点到起点的最短距离。 在上述示例中,我们使用了邻接矩阵表示,这种方式适用于节点数较少的情况。当节点数较多时,可以考虑使用邻接表或其他数据结构来表示

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值