严蔚敏《数据结构》 迪杰斯特拉算法

        迪杰斯特拉算法是在有向网中实现某一单源节点到其他各节点最短路径的算法。

        其基本思想采用了贪心算法的思想,即每次循环过程中选出起始节点到其余各节点中路径最短的节点,然后借助被选出的节点,更新剩余节点的路径长度,依次循环下去,直到所有节点都被选出。算法代码如下:

void Shortest_DIJ(AMGraph G,int v0)
{
	int w,v;
	for(v=0;v<G.vexnum;v++)
	{
		S[v]=0;  //初始化S为空 
		D[v]=G.arcs[v0][v];
		if(D[v]<MaxInt)
		{
			Path[v]=v0;
		} 
		 else Path[v]=-1;
	}
	S[v0]=1;  //将v0加入S
	D[v0]=0;  //源点到源点距离为0 
	for(int i=1;i<G.vexnum;++i)
	{
		int min=MaxInt;
		for(w=0;w<G.vexnum;w++)
		{
			if(!S[w]&&D[w]<min)    //找出未被确定且与源点直接相连顶点中权值最小的顶点 
			{
				v=w;
				min=D[w];
			}
		}
		S[v]=1;  //将v加入S
		for(w=0;w<G.vexnum;++w)      //更新源点到其余各点的最短路径 
		{
			if(!S[w]&&(D[v]+G.arcs[v][w]<D[w]))
			{
				D[w]=D[v]+G.arcs[v][w];
				Path[w]=v;
			}
		 }
	}
	for(w=1;w<G.vexnum;w++)
	{
	 	if(S[w])
	 	{
	 		cout<<"源点"<<v0<<"到"<<w<<"的距离为:"<<D[w]<<endl;
		}
		else
		{
			cout<<"源点"<<v0<<"到"<<w<<"无路径"<<endl; 
		}
	} 
 } 

       (笔者发布文章之前又在VS上测试了一下,发现算法出现爆栈的警告,文章发布前还没有想解决的办法,以上代码仅供参考)

        运行所采用的图也是书上所给出的图

 

         完整代码如下:

#include<iostream>
#include<stack>
#include<queue>
#include<string.h>
#define MaxInt 0x3f
using namespace std;
const int MVNum=100;   //最大顶点数 
int S[100];  //记录相应顶点是否已确定最短路径
int D[101];  //记录相应顶点路径长度
int Path[100];  //记录相应顶点的前驱顶点 
class AMGraph
{
public:
    AMGraph(int n,int e);
    int arcs[MVNum][MVNum];   //邻接矩阵 
    int vexnum,arcnum;     //当前点和边数 
};
AMGraph:: AMGraph(int n,int e)   //邻接矩阵构造有向网 
{
    vexnum=n;
    arcnum=e;
    int v1,v2,w;
    for(int i=0;i<vexnum;i++)    //初始化邻接矩阵 
    {
        for(int j=0;j<vexnum;j++)
        {
            arcs[i][j]=MaxInt;
        }
    }
    cout<<"请输入相邻的点和权值:"<<endl;
    for(int k=0;k<arcnum;k++)
    {
        cin>>v1>>v2>>w;
        arcs[v1][v2]=w;
    }
}

void Shortest_DIJ(AMGraph G,int v0)
{
    int w,v;
    for(v=0;v<G.vexnum;v++)
    {
        S[v]=0;  //初始化S为空 
        D[v]=G.arcs[v0][v];
        if(D[v]<MaxInt)
        {
            Path[v]=v0;
        } 
         else Path[v]=-1;
    }
    S[v0]=1;  //将v0加入S
    D[v0]=0;  //源点到源点距离为0 
    for(int i=1;i<G.vexnum;++i)
    {
        int min=MaxInt;
        for(w=0;w<G.vexnum;w++)
        {
            if(!S[w]&&D[w]<min)    //找出未被确定且与源点直接相连顶点中权值最小的顶点 
            {
                v=w;
                min=D[w];
            }
        }
        S[v]=1;  //将v加入S
        for(w=0;w<G.vexnum;++w)      //更新源点到其余各点的最短路径 
        {
            if(!S[w]&&(D[v]+G.arcs[v][w]<D[w]))
            {
                D[w]=D[v]+G.arcs[v][w];
                Path[w]=v;
            }
         }
    }
    for(w=1;w<G.vexnum;w++)
    {
         if(S[w])
         {
             cout<<"源点"<<v0<<"到"<<w<<"的距离为:"<<D[w]<<endl;
        }
        else
        {
            cout<<"源点"<<v0<<"到"<<w<<"无路径"<<endl; 
        }
    } 
 } 
 
 int main()
 {
     int n,e,v0;
     cout<<"请输入顶点数和边数:"<<endl;
     cin>>n>>e;
     AMGraph G(n,e);
     cout<<"请输入源点"<<endl;
     cin>>v0;
     Shortest_DIJ(G,v0);
     return 0;
 }

本文是笔者学习严蔚敏老师的《数据结构》后所写的文章,因此代码大部分都源于书上的伪代码。写的初衷也只是记录一下,方便日后温习使用。文章仅供参考,不足之处还请各路大神指点。 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值