Dijkstra算法的实现

来源:互联网 发布:2017淘宝直播怎么开通 编辑:程序博客网 时间:2024/05/17 03:54
//dijkstra.cpp
//Dijkstra算法的实现
//读入“DijkstraTxt”中的部分网络数据“Test.txt”(弧段起点ID,弧段终点ID,弧段距离)
//用Dijkstra算法生成的最佳路径再写入“RouteTxt.txt”文件中


#include<iostream>
#include<fstream>
#include<iomanip>
#include<sstream>
using namespace std;
#define MAXIMUM 1000000000 //无穷大


typedef struct recordList{
int startPoint;//起点
int endPoint; //终点
float length; //弧段长度
recordList* next;//结构体指针
}record; //定义Record结构体类型表示从文件中读取的数据记录


void main()
{
//打开Test.txt并从中读取数据
ifstream inPutFile("Test.txt", ios::in);
//以创建方式打开文件RouteTxt.txt并写入数据
ofstream outPutFile("RouteTxt.txt", ios::out);
if (!inPutFile || !outPutFile)//文件打开异常处理
{
cout << "文件打开失败!" << endl;
exit(1);
}
outPutFile << "\tDijkstra 算法实现结果数据\t" << endl;
outPutFile << "起点\t终点\t距离\t\t路径" << endl;


int numPoint; //点数
int numEdge; //边数
int maxPoint; //最大点号
record* head = NULL;//数据链表表头
record* data = NULL;//读取的一行数据


data = (record*)new record;//分配一行数据的内存空间
//读取一行数据,包括起点、终点、弧段长度
inPutFile >> data->startPoint >> data->endPoint >> data->length;
head = data; //数据链表表头指针
numEdge = 1; //初始边数为1
maxPoint = max(data->startPoint, data->endPoint);//初始最大点号


while (!inPutFile.eof())//逐行读取文件中的数据到data中
{
data->next = (record*)new record;//动态分配内存空间
data = data->next;//指向下一个结构体
//读取一行数据,包括起点、终点、弧段长度,数据格式(弧段起点ID,弧段终点ID,弧段距离)
inPutFile >> data->startPoint >> data->endPoint >> data->length;
//若maxPiont小于起点或终点点号,更新maxPoint
if (maxPoint < data->startPoint)
maxPoint = data->startPoint;
if (maxPoint < data->endPoint)
maxPoint = data->endPoint;


numEdge++; //边数增加1
}
inPutFile.close();//关闭文件流
data->next = NULL;//最后的指针赋值为空


////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
///////////以上代码实现从文件读入数据,以下实现算法计算并写入结果到文件/////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////


int i, j, k; //变量
float* path = new float[maxPoint + 1];//路径距离数组
int* route = new int[maxPoint + 1];//路由表
bool* flag = new bool[maxPoint + 1];//最短路径求取成功标记
for (i = 0; i <= maxPoint; i++)//按点号从小到大遍历所有结点做源结点
{
for (j = 0; j <= maxPoint; j++)//初始化路由表和路径距离数组
{
path[j] = MAXIMUM;//路径距离数组初始化为无穷大
route[j] = -1;//-1表示不能到达或最短路径尚未找出
flag[j] = false;
}


record* getData = head;//获得链表数据头指针
float minLength = MAXIMUM;//当前的最小距离
int lastPoint = i;//前一次找出的距离最短的路径的终点


while (getData != NULL)//遍历链表,找出源结点出发的最短路径
{
if (getData->startPoint == i)//起点为i
{
path[getData->endPoint] = getData->length;//获得源结点到目的结点的距离
route[getData->endPoint] = getData->startPoint;//路由信息存储为目的结点的前一个结点
if (minLength > getData->length)//距离小于当前最小距离
{
minLength = getData->length;//获得当前最小距离
lastPoint = getData->endPoint;//获得当前最小距离的终点
}
}
getData = getData->next;//指向下一个结构体
}
flag[lastPoint] = true;//标记起点到当前终点的最短路径已求出


for (k = 0; k < maxPoint; k++)//按点号从小到大遍历所有结点做目的结点
{
getData = head;//获得链表数据头指针
float tempLength = MAXIMUM;//当前的最小距离
int tempPoint = -1;//前一次找出的距离最短的路径的终点


while (getData != NULL)//遍历链表,更新路由信息和距离数组
{
if ((getData->startPoint == lastPoint) && (getData->endPoint != i) && !flag[getData-


>endPoint])
{//起点为上一次最短路径的终点,终点与起点不同,最短路径未求出
if ((minLength + getData->length) < path[getData->endPoint])//有更短的路径
{
path[getData->endPoint] = minLength + getData->length;//获得


源结点到目的结点的距离
route[getData->endPoint] = getData->startPoint;


//路由信息存储为目的结点的前一个结点
}
}
getData = getData->next;//指向下一个结构体
}


for (j = 0; j < maxPoint; j++)
{//遍历path数组,找出到最短路径尚未找出的终点的距离最小值
if (!flag[j] && tempLength >= path[j] && j!=i)
{//最短路径尚未找出,且距离比当前最小距离更小,起点和终点不同
tempLength = path[j];//更新最小距离值
tempPoint = j;//更新当前最短路径的终点
}
}


lastPoint = tempPoint;//获得当前最小距离的终点
minLength = tempLength;//获得当前最小距离
flag[lastPoint] = true;//标记起点到当前终点的最短路径已求出
}


////////////////////下面先指定文件写入结果数据///////////////////////////
for (j = 0; j <= maxPoint; j++)//从每一个结点出发
{
if (path[j] == MAXIMUM)//路径不可达,或者终点和起点重叠
{
//向文件写入信息
outPutFile << i << "\t" << j << "\t--\t\t--" << endl;
}
else
{
string strRoute;//路径信息
int r = route[j];//第j个点为终点时其上一跳位置
while (r!=i) //根据路由表反向查找路径信息
{
stringstream ss;//使用字符串流将int转化为string型
ss << r; //字符串流写入
strRoute = "->" + ss.str() + strRoute;//构建路径信息字符串
r = route[r]; //上一跳
}
//向文件写入数据 “起点 终点 距离 路径”
outPutFile << i << "\t" << j << "\t" << path[j] << "\t\t" << i << strRoute << "->" <<  j << endl;
}
}
}
outPutFile.close();//关闭文件流
return;
}
0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 一年级小朋友不爱写字怎么办 幼儿园小朋友不爱写字怎么办 孩子懒散不积极怎么办 孩子不肯上幼儿园怎么办 孩子不肯去幼儿园怎么办 小孩记不住字怎么办 小孩不会写字要怎么办 一年级孩子不爱写字怎么办 一年级小孩不爱写字怎么办 孩子不爱写字怎么办呢 幼儿园孩子不爱写字怎么办 孩子上学没学籍怎么办 孩子上学务工证怎么办 孩子上学被欺负怎么办 孩子害怕上幼儿园怎么办 孩子写字肩膀疼怎么办 5岁不会写字怎么办 上中班不爱写字怎么办 孩子性子太慢怎么办 13小孩特别懒怎么办 小孩不肯上幼儿园怎么办 宝宝不肯上幼儿园怎么办 宝宝不肯去幼儿园怎么办 小孩子不肯去幼儿园怎么办 上幼儿园不说话怎么办 小孩写字不认真怎么办 游戏打开是乱码怎么办 小孩不写字该怎么办 小孩不喜欢穿袜子怎么办 宝宝不喜欢穿袜子怎么办 看到婆婆就烦怎么办 什么也不想吃怎么办 宝宝不喜欢带围兜怎么办 宝宝宝宝不喜欢脐疝带怎么办 中班小孩不写字怎么办 中班小孩不愿意写字怎么办 中班了不会写字怎么办 胃不舒服没胃口怎么办 不喜欢婆婆带孩子怎么办 小孩咳嗽吃饭吐怎么办 小孩吐不吃饭怎么办