Dijkstra_算法实现

  • 简单介绍

    Dijlstra 算法适用于计算从某点出发到其余点的最短路径的算法,其核心步骤大致是:

  1. 初始化
  2. 寻找最小未计算完值,此时该值为计算完的值
  3. 根据该最小值优化其余未计算完的节点路路径
  4. 判断是否全部计算完
  • 代码实现
void Dijkstra(Graph_D &G,int s,int D[],int path[]){
	int n = G.nNum;
//初始化所有节点信息
	for(int i = 0;i<n;i++){
		G.Mark[i] = 0;//为确定好路径
		int w = G.getW(s,i);
		D[i] = w>=0?w:-1;//为确定距离 -1 指无穷大 其余是是权值
		path[i] = s;//s-i无路径
	}
	//初始化期起点信息
	G.Mark[s] = 1;
	D[s] = 0;
	path[s] = s;

	int count = 1;
	while(count != n){
		
		//查找最短路径
		int min = -1;
		int min_i = -1;
		
		for(int j = 0;j<n;j++){
			if(G.Mark[j] == 0){
				if(min_i == -1){
					min = D[j];
					min_i = j;
				}
				else{//比较部分
					if(min == -1){
						min = D[j];
						min_i = j;	
					}
					else{
						if(D[j] != -1&&D[j]<min){
							min = D[j];
							min_i = j;
						}
					}
				}
			}
		}
		G.Mark[min_i] = 1;//该节点已经确定;
		count++;

		//
		//利用min_i 更新其余所有节点
		if(min == -1)continue;//无穷大是无法更新别的节点
		for(int end = 0;end<n;end++){//无穷大----1不需要更新
			if(G.getW(min_i,end)>=0){//有边min_i --> k 的边
			if(G.Mark[end] == 0){//未确定的
				if(D[end] != -1){//不是无穷大
					int w = G.getW(min_i,end);
					if(D[min_i]+w<D[end]){
						D[end] = min+w;
						path[end] = min_i;
					}		
				}else{
					D[end] = min+G.getW(min_i,end);
					path[end] = min_i;
				}
			}
			}
		}


	}

	

}

  • 下面是实例,以邻接表有向图为例:

1.类信息

class Graph_D
{
public:
	int ** matrix;
public:
	int nNum;
	int eNum;
	int * Mark;

	Graph_D(int n):nNum(n){
		Mark = new int[nNum];
		for(int i = 0;i<nNum;i++)Mark[i] = 0;
		matrix =(int **)new int*[nNum];
		for(int i =0;i<nNum;i++)matrix[i] = new int[nNum];
		for(int i = 0;i<nNum;i++)
			for(int j = 0;j<nNum;j++)
				if(i != j)
				matrix[i][j] = -1;
				else matrix[i][j] = 0;		
	}
	int getW(int s,int e){
		return matrix[s][e];
	}
	void setEdge(int f,int s,int w){
		if(f>=0&&f<nNum&&s>=0&&s<nNum){
			if(matrix[f][s]>0){
				eNum++;
			}
			matrix[f][s]  = w;
		}
	}
	~Graph_D(void){
		delete []Mark;
		for(int i = 0;i<nNum;i++)delete []matrix[i];
		delete []matrix;
	}
};

2.测试样例:

#include<iostream>
using namespace std;
#include "Graph_D.h"
int main()
{
	Graph_D G(6);
	G.setEdge(0,2,10);
	G.setEdge(0,4,30);
	G.setEdge(0,5,100);
	G.setEdge(1,2,5);
	G.setEdge(2,3,50);
	G.setEdge(3,5,10);
	G.setEdge(4,3,20);
	G.setEdge(4,5,60);
	int D[6];
	int path[6];
	Dijkstra(G,1,D,path);
	
		cout<<"Node:"<<"\t";	
		for(int i = 0;i<6;i++){
			cout<<i<<"\t";
		}
		cout<<endl;
		cout<<"dist:"<<"\t";
		for(int i = 0;i<6;i++){
			cout<<D[i]<<"\t";
		}
		cout<<endl;
		cout<<"path:"<<"\t";
		for(int i = 0;i<6;i++){
			cout<<path[i]<<"\t";
		}
		cout<<endl;
	return 0;
}
  • 输出结果如下:
Node:012345
dist:-10555-165
path:111213

更多精彩请点击关注
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值