最短路径实现(Dijkstra算法)

        最近 没有其他事情,又面临着毕业找工作,因此看一些C++方面和数据结构中的东西。其中对最短路径算法比较喜欢,因此花费了半天时间将其完成,其中有些不足,还请体谅。现将代码发布如下:

头文件:
// Dijkstra.h: interface for the Dijkstra class.
//
//

#if !defined(AFX_DIJKSTRA_H__41B8B23E_AD66_426C_ADAF_F764924F25A9__INCLUDED_)
#define AFX_DIJKSTRA_H__41B8B23E_AD66_426C_ADAF_F764924F25A9__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

class Dijkstra 
{
public:
    // 输出路径和最短距离
    void OutputPathAndDis();
    // 设置起始节点
    void SetV0();
    void SetV0(int V0);
    // 计算最短路径
    void ShortestPath();
    // 输出邻接关系表
    void OutputGraph();
    // 获得邻接表
    int** GetGraph();
    // 设置邻接表
    void SetGraph(int** intGraph);
    void SetGraph();
    // 输出顶点名称
    void OutputVName();
    // 获得顶点名称
    char** GetVName();
    // 设置定点名称
    void SetVName(char** chVName);
    void SetVName();
    // 获得顶点数
    int GetVertexNum();
    // 设置定点数
    void SetVertexNum();
    void SetVertexNum(int VertexNum);
    // 构造函数
    // 无参数构造函数
    Dijkstra();
    // 构造函数(顶点数)
    Dijkstra(int VertexNum);
    // 析构函数
    virtual ~Dijkstra();

private:
    // 最短路径矩阵
    int** PathMatrix;
    // 路径长度
    int* PathMatrixLength;
    // 最短路径值
    int* ShortPathTable;
    // 起始顶点位置
    int intV0;
    // 邻接关系表
    int** Graph;
    // 顶点名称
    char** VName;
    // 顶点数
    int intVNum;
};

#endif // !defined(AFX_DIJKSTRA_H__41B8B23E_AD66_426C_ADAF_F764924F25A9__INCLUDED_)

CPP文件
// Dijkstra.cpp: implementation of the Dijkstra class.
//
//

#include "Dijkstra.h"
#include <iostream.h>
#include <iomanip.h>

//
// Construction/Destruction
//

///Construction
Dijkstra::Dijkstra()
{
    this->intV0 = 0;
}

///Construction(顶点数)
Dijkstra::Dijkstra(int VertexNum)
{
    this->intVNum = VertexNum;
}

///Destruction
Dijkstra::~Dijkstra()
{

}

///设置顶点数(顶点数)
void Dijkstra::SetVertexNum(int VertexNum)
{
    this->intVNum = VertexNum;
}

///设置顶点数
void Dijkstra::SetVertexNum()
{
    int iNum=0;
    cout<<"请输入顶点的个数:";
    cin>>iNum;
    this->intVNum = iNum;
    if(this->intVNum<=0)
    {
        cout<<"输入的顶点数不能为负数!"<<endl;
    }
}

///设置顶点数
void Dijkstra::SetVName(char** chVName)
{
    this->VName = chVName;
}

///获得顶点个数
int Dijkstra::GetVertexNum()
{
    return this->intVNum;
}

///设置顶点名称
void Dijkstra::SetVName()
{
    // 判断输入顶点数是否正确
    if(this->intVNum<=0)
    {
        cout<<"请设置顶点个数"<<endl;
        return;
    }
    // 输入顶点名称
    this->VName = new char*;
    for(int i=0;i<this->intVNum;i++)
    {
        cout<<"请输入第"<<(i+1)<<"个顶点名称:";
        this->VName[i] = new char[10];
        cin>>this->VName[i];
    }
}

///获得顶点名称
char** Dijkstra::GetVName()
{
    return this->VName;
}

///输出顶点名称
void Dijkstra::OutputVName()
{
    for(int i=0;i<this->intVNum;i++)
    {
        cout<<"第"<<(i+1)<<"个节点名称"<<this->VName[i]<<endl;
    }
}

///输入邻接关系表
void Dijkstra::SetGraph()
{
    // 判断输入顶点数是否正确
    if(this->intVNum<=0)
    {
        cout<<"请设置顶点个数"<<endl;
        return;
    }
    // 输入顶点名称
    this->Graph = new int*;
    cout<<"请输入邻接关系表(不可达使用-1代替):"<<endl;
    for(int i=0;i<this->intVNum;i++)
    {
        this->Graph[i] = new int[this->intVNum];
        for(int j=0;j<this->intVNum;j++)
        {
            if(i==j)
            {
                this->Graph[i][j] = -1;
                continue;
            }
            cout<<this->VName[i]
                <<"-->"
                <<this->VName[j]
                <<":";
            cin>>this->Graph[i][j];
        }
    }
}

///输入邻接关系表
void Dijkstra::SetGraph(int **intGraph)
{
    this->Graph = intGraph;
}

///获得邻接表
int** Dijkstra::GetGraph()
{
    return this->Graph;
}

///输出邻接表
void Dijkstra::OutputGraph()
{
    cout<<"邻接关系表为:"<<endl;
    cout<<setfill(' ')
            <<setiosflags(ios::left)
            <<setw(10)
            <<" ";
    // 输出表头
    for(int k=0;k<this->intVNum;k++)
    {
        cout<<setfill(' ')
            <<setiosflags(ios::left)
            <<setw(10)
            <<this->VName[k];
    }
    cout<<endl;
    // 输出矩阵值
    for(int i=0;i<this->intVNum;i++)
    {
        cout<<setfill(' ')
            <<setiosflags(ios::left)
            <<setw(10)
            <<this->VName[i];
        for(int j=0;j<this->intVNum;j++)
        {
            cout<<setfill(' ')
                <<setiosflags(ios::left)
                <<setw(10)
                <<this->Graph[i][j];
        }
        cout<<endl;
    }
}

///计算最短路径
void Dijkstra::ShortestPath()
{
    // 如果final[i]为TRUE,表明V0到节点i已找到最短路径
    bool *final = new bool[this->intVNum];
    // 最短路径值
    this->ShortPathTable = new int[this->intVNum];
    // 最短路径顶点过程和经过的定点数
    this->PathMatrix = new int*;
    this->PathMatrixLength = new int[this->intVNum];
    // 初始化邻接表(将其中的-1修改为10000000)
    int intMin = 10000000;
    for(int i=0;i<this->intVNum;i++)
    {
        this->PathMatrixLength[i] = 1;
        this->PathMatrix[i] = new int[this->intVNum];
        this->PathMatrix[i][0] = this->intV0;
        for(int j=0;j<this->intVNum;j++)
        {
            if(this->Graph[i][j] == -1)
            {
                this->Graph[i][j] = intMin;
            }           
        }
    }
    // 初始化Dijkstra算法
    for(i=0;i<this->intVNum;i++)
    {
        final[i]=false;
        this->ShortPathTable[i] = this->Graph[this->intV0][i];
        //this->PathMatrix[i] = new int[this->intVNum];
    }
    // 最小值所在节点位置
    int intV = 0;
    // 初始化访问节点和路径值
    final[this->intV0] = true;
    this->ShortPathTable[this->intV0] = 0;
    // 计算最短路径
    for(i=0;i<this->intVNum;i++)
    {
        if(i == this->intV0)
        {
            continue;
        }
        // 获取最小值
        intMin = 1000000;
        for(int j=0;j<this->intVNum;j++)
        {
            if(!final[j] && this->ShortPathTable[j]!=-1 && this->ShortPathTable[j]<intMin)
            {
                intMin = this->ShortPathTable[j];
                intV = j;
            }
        }
        // 将最小添加到访问节点中
        final[intV] = true;
        // 计算下一步中的最值
        for(int k=0;k<this->intVNum;k++)
        {
            if(!final[k] && intMin + this->Graph[intV][k] < this->ShortPathTable[k])
            {
                this->ShortPathTable[k] = intMin + this->Graph[intV][k];
                int m=0;
                for(m=0;m<this->PathMatrixLength[intV];m++)
                {
                    this->PathMatrix[k][m] = this->PathMatrix[intV][m];
                }
                this->PathMatrix[k][m] = intV;
                // =  this->PathMatrix[intV];
                this->PathMatrixLength[k] = m+1;// = this->PathMatrixLength[intV] + 1;
            }
        }
    }
}

///设置起始顶点
void Dijkstra::SetV0(int V0)
{
    this->intV0 = V0;
}

///设置起始节点
void Dijkstra::SetV0()
{
    cout<<"请输入起始结点(使用节点序号代替):";
    cin>>this->intV0;
}

///输出最短路径
void Dijkstra::OutputPathAndDis()
{
    // 循环输出节点
    for(int i=0;i<this->intVNum;i++)
    {
        // 去掉第一个节点
        if(i == this->intV0)
        {
            continue;
        }
        // 不可到达节点
        if(this->ShortPathTable[i] == 10000000)
        {
            cout<<this->VName[this->intV0]
                <<"不可到达结点"
                <<this->VName[i]
                <<endl;
            continue;
        }
        // 可到达节点
        cout<<this->VName[this->intV0]
            <<"到达"
            <<this->VName[i]
            <<":最短距离为:"
            <<this->ShortPathTable[i]
            <<"      路径为:"
            <<this->VName[this->intV0]
            <<"-->";
        for(int j=1;j<this->PathMatrixLength[i];j++)
        {
            cout<<this->VName[this->PathMatrix[i][j]]<<"-->";
        }
        cout<<this->VName[i]
            <<endl;
    }
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值