《数据结构课程设计》求最佳路径
来源:互联网 发布:ember.js 开发工具 编辑:程序博客网 时间:2024/05/22 15:26
《数据结构课程设计》
课程题目
《求最佳路径》
课程编号
j1620102
学生姓名
纪健欣
所在专业
信息管理与信息系统
所在班级
信管1134班
任课老师
易学明
实习时间
第16—17周
设计成绩
老师评语
数据结构课程设计说明书
1.课程设计题目
GDOU是真是一个好地方,校园如一座大花园,美丽而宽广。校园有许多建筑如教学楼、饭堂、宿舍楼、图书馆、体育馆、运动场、商业街、医院等,还有一些著名的风景点。现请根据学校的平面图,找出一些重要的场所,画出学校的平面图(场所可以根据其重要性适当减少),根据实际画出不同点间的路径,并估算每两个场所间的路径长。请设计数据结构并编程,当给出一个出发点和要到达另外一个场所的信息时,请给出最佳路径,并输出路径相关信息。
2.课程设计功能
① 简单地存储学校地图
② 查找出一处建筑到其他所有建筑的最佳路径和最佳路径的长度
③ 查找出两处建筑之间的最佳路径和最佳路径的长度
3.课程设计要求
根据不同建筑之间的路径,估算每两个建筑之间的路径长度。根据已给出的一个出发点,找出到另一建筑或其他点的最佳路径,并输出路径的相关信息
4.需求分析
① 查找一处建筑到其他所有建筑的最佳路径和最佳路径的长度,也就是求一点到其他点的最短路径问题,可以采用迪杰斯特拉算法(Dijkstra's Algorithm)
② 学校地图反映出各个建筑之间的位置距离,可以利用邻接矩阵来存储
5.代码
main.cpp //main.cpp #include "GraphList.h" int main() { GraphList graphList;//图 int choice;//存放用户的选择 char element_1, element_2; int locate_1, locate_2; int Path[MAX_VERTEX_NUM], Dest[MAX_VERTEX_NUM]; bool DIJFlag = false;//标记是否进行过了DIJ算法 createGraph(graphList); cout << "************************************************************************" << "\n广东海洋大学主要建筑如下:" << "\n a.教学主楼, b.商业中心, c.体育馆, d.钟海楼,\n e.图书馆, f.第三饭堂, g.科技楼, h.宿舍\n" << "\n" << "\n------------------------------------------------------------------------" << "\n--广东海洋大学地图如下所示:"; printGraph(graphList); cout << "\n" << "\n------------------------------------------------------------------------" << "\n--主菜单:" << "\n--1.查询从某点到其他点的最佳路径." << "\n--2.查询两点之间所有路径和最佳路径." << "\n--0.退出." << "\n\n-------------------------------------------" << "\n--请输入您的选择(1/2/0): "; cin >> choice; while(choice != 0) { switch(choice) { case 1: cout << "\n--请输入图中的一个点(e.g.: a): "; cin >> element_1; if((locate_1=findNode(graphList, element_1)) == -1) return 0; if(!DIJFlag)//如果没有进行了DIJ算法查找最短路径 { shortestPath_DIJ(graphList, locate_1, Path, Dest); DIJFlag = true; } printShortestPath_DIJ(graphList, locate_1, Path, Dest); break; case 2: cout << "\n--请输入图中的两个点(e.g.: a b): "; cin >> element_1 >> element_2; locate_1 = findNode(graphList, element_1); locate_2 = findNode(graphList, element_2); if((locate_1==-1) || (locate_2==-1)) return 0; if(!DIJFlag)//如果没有进行了DIJ算法查找最短路径 { shortestPath_DIJ(graphList, locate_1, Path, Dest); DIJFlag = true; } cout << " 点 " << element_1 << " 和 " << " 点 " << element_2 << "之间的路径情况: "; allPath_2Vexs(graphList, locate_1, locate_2);//输出所有路径 cout << "\n--------------------------------------"; printShortestPath_2Vexs(graphList, locate_1, locate_2, Path, Dest); break; default: cout << "--您的输入有误!!!自动退出!!!\n"; return 0; } cout << "\n\n-------------------------------------------" << "\n--请输入您的选择(1/2/0): "; cin >> choice; } deleteGraph(graphList);//删除图,防止内存泄露 return 0; } GraphList.cpp//*************** GraphList.cpp #include "GraphList.h" //查找顶点,工具方法,查找element是否存在于graphlist中,返回element的位置i int findNode(GraphList &graphList, char element) { int i; for(i=0; i<graphList.vertexNum; i++) { if(element == graphList.vertexList[i].data) { break; } } if(i >= graphList.vertexNum) { cout << "找不到该元素!!!\n"; return -1; } return i; } //创建图,并执行初始化 所有顶点以及边都在程序内部定义 bool createGraph(GraphList &graphList) { //初始化定点表 graphList.vertexNum = 0;//顶点数 graphList.edgeNum = 0;//边数 int value = 0;//暂时存放从邻接矩阵中读取的数值 char vexArray[MAX_VERTEX_NUM] = {'a','b', 'c', 'd', 'e', 'f', 'g', 'h'};//顶点的数组//建立顶点表 vertexList for(int v=0; v<MAX_VERTEX_NUM; v++) { if(vexArray[v] != '\0') graphList.vertexNum++;//如果第v+1个顶点不为空值,则顶点数+1 graphList.vertexList[v].data = vexArray[v];//把顶点表中v的数据赋给顶点数组中的v graphList.vertexList[v].firstarc = NULL; } //初始化边表 Edge int edgeArray[MAX_VERTEX_NUM][MAX_VERTEX_NUM] = {//初始化邻接矩阵 //0,1,2,3,4,5,6,7 {0,55,0,40,50,0,0,0},//0 {55,0,10,0,0,0,0,0},//1 {0,10,0,20,0,0,0,0},//2 {40,0,0,0,45,75,25,110},//3 {50,0,20,45,0,0,60,0},//4 {0,0,0,75,0,0,70,60},//5 {0,0,0,25,60,70,0,90},//6 {0,0,0,110,0,60,90,0},//7 }; for(int i=0; i<graphList.vertexNum; i++) { EdgeNode *temp = NULL;//存放临时的节点 EdgeNode *Node = NULL;//存放新生成的节点 for(int j=0; j<graphList.vertexNum; j++) { //edgeArray 边的数组 if((value = edgeArray[i][j]) != 0)//有边 { if(!(Node = new EdgeNode)) { cerr << "No Enough Memory!";//cerr:不经过缓冲区,直接把内容输出到显示屏上 exit(1);//exit(0)正常退出, exit(1)错误退出, } Node->adjvexLocate = j;//把节点在定点表中的位置赋给j Node->value = value; Node->next = NULL;//生成节点 graphList.edgeNum++; if(graphList.vertexList[i].firstarc == NULL)//第一个节点 { graphList.vertexList[i].firstarc = Node; temp = Node; } else { temp->next = Node; temp = Node; } } } } return true; } //输出图bool printGraph(GraphList &graphList) { EdgeNode *temp = NULL; if(!&graphList) return false; for(int i=0; i<graphList.vertexNum; i++) { cout << "\n" << graphList.vertexList[i].data << ": "; temp = graphList.vertexList[i].firstarc; while(temp) { cout << " (" << graphList.vertexList[i].data << "," << graphList.vertexList[temp->adjvexLocate].data << "," << temp->value << ") "; temp = temp->next; } } return true; } //单源最短路径算法/* vex:源点 i:某一终点 Dest[i]:源点vex到点i的最短路径的长度 Path[i]:源点vex到点i的最短路径 */ void shortestPath_DIJ(GraphList &graphList, int vex, int Path[], int Dest[]) { bool finalShortest[MAX_VERTEX_NUM]; EdgeNode *temp = NULL; int minValue = INFINITY;//用作寻找最小的路径权值 int v = 0;//记录每一次寻找的最小路径终点的位置 for(int i=0; i<graphList.vertexNum; i++)//第一步初始化 { finalShortest[i] = false; Path[i] = -1;//没有前驱,即没有路径 Dest[i] = INFINITY;//存放vi与给出的源点之间的最短路径 } finalShortest[vex] = true; Dest[vex] = 0;//修改源点的值 Path[vex] = -1; temp = graphList.vertexList[vex].firstarc; while(temp) { Dest[temp->adjvexLocate] = temp->value; Path[temp->adjvexLocate] = vex;//前驱 temp = temp->next; }//初始化完成 for(int i=1; i<graphList.vertexNum; i++)//执行n-1次循环,对剩余的n-1个顶点操作 { minValue = INFINITY; for(int j=0; j<graphList.vertexNum; j++) { if(!finalShortest[j])//还没有求出最短路径 { if(Dest[j] < minValue) { v = j; minValue = Dest[j]; } } } finalShortest[v] = true;//将此终点加入已求出最短路径的集合 //更新参数 for(int j=0; j<graphList.vertexNum; j++) { int vValue = INFINITY;//存放v 与 j之间的权重 temp = graphList.vertexList[v].firstarc;//一句话如果放错位置就会出现无法预料的错误! while(temp) { if(temp->adjvexLocate == j) { vValue = temp->value; break; } temp = temp->next; } if(!finalShortest[j] && (minValue+vValue<Dest[j])) { Dest[j] = minValue + vValue;//更新为更小的权重 Path[j] = v;//更新前驱节点 } } } } //输出生成的单源最短路径 /* vex:源点 i:某一终点 Dest[i]:源点vex到点i的最短路径的长度 Path[i]:源点vex到点i的最短路径 */ void printShortestPath_DIJ(GraphList &graphList, int vex, int Path[], int Dest[]) { int pre = 0; cout<< "从点" << graphList.vertexList[vex].data << "到其他点的最佳路径为:"; for(int i=0; i<graphList.vertexNum; i++) { if(Dest[i] >= INFINITY || i == vex) continue; cout << "\n\t(" << graphList.vertexList[vex].data << "->" << graphList.vertexList[i].data << "): 路径长度 = " << Dest[i] << "\t路径: " << graphList.vertexList[i].data; pre = Path[i]; while(pre != -1) { cout << " " << graphList.vertexList[pre].data; pre = Path[pre]; } } } //输出两点之间最短路径及距离 /* vex1:源点1vex2:源点2i:vex1或vex2 Dest[i]:源点vex1和源点2之间的最短路径的长度 Path[i]:源点vex1和源点2之间的最短路径 */ void printShortestPath_2Vexs(GraphList &graphList, int vex1, int vex2, int Path[], int Dest[]) { int pre = 0; cout << "\n点" << graphList.vertexList[vex1].data << "和点" << graphList.vertexList[vex2].data << "之间的最佳路径:"; for(int i=0; i<graphList.vertexNum; i++) { if(i == vex2) { cout << "\n\t(" << graphList.vertexList[vex1].data << "->" << graphList.vertexList[vex2].data << "): 路径长度 = " << Dest[i] << "\t路径: " << graphList.vertexList[i].data; pre = Path[i]; while(pre != -1) { cout << " " << graphList.vertexList[pre].data; pre = Path[pre]; } return; } } } //删除图bool deleteGraph(GraphList &graphList) { if(graphList.vertexNum == 0) return false; EdgeNode *temp = NULL; for(int i=0; i<graphList.vertexNum; i++)//定点表中每个顶点 { if((temp = graphList.vertexList[i].firstarc) == NULL) continue; while(temp) { graphList.vertexList[i].firstarc = temp->next; delete temp; temp = graphList.vertexList[i].firstarc; } } return true; } //任意两点之间的所有路径void allPath_2Vexs(GraphList &graphList, int startVex, int endVex) { if(startVex == endVex) { return; } bool status[MAX_VERTEX_NUM] = {false};//标记点被访问的状态 vector<int> pathStack;//记录访问到节点的位置 int length = 0; visit(graphList, startVex, endVex, status, pathStack, length); } //递归访问每个元素 void visit(GraphList &graphList, int vex, int endVex, bool status[], vector<int> &pathStack, int length)//对vex点进行访问 { if(vex == endVex)//找到了终点 { cout << "\n\t路径长度 = " << length << "\t路径: "; for(unsigned int i=0; i<pathStack.size(); i++) { cout << " " << graphList.vertexList[pathStack[i]].data; } cout << " " << graphList.vertexList[endVex].data; return; } status[vex] = true; pathStack.push_back(vex); EdgeNode *current = NULL; for(current=graphList.vertexList[vex].firstarc; current!=NULL; current = current->next) { if(!status[current->adjvexLocate]) { length += current->value; visit(graphList, current->adjvexLocate, endVex, status, pathStack, length); } } status[vex] = false;//修改标志 pathStack.pop_back();//回溯 }GraphList.h //****************** GraphList.h #ifndef GRAPHLIST_H_INCLUDED #define GRAPHLIST_H_INCLUDED #include <iostream> #include <string> //字符串类#include <cstdlib> //引入文件的输入输出的函数库#include <stack> //STL 堆栈容器#include <vector> //STL 动态数组容器using namespace std; #define MAX_VERTEX_NUM 8//最大支持的节点数 #define INFINITY 1000//表示无穷大 typedef int EdgeValueType;//定义边权重类型 typedef char VertexType;//定义顶点表顶点的内容类型 typedef struct EdgeNode//边表节点 { int adjvexLocate;//该弧所指向的顶点在定点表中的位置 EdgeValueType value;//权重 EdgeNode *next;//指向下一个节点 } EdgeNode; typedef struct VertexNode//顶点表 { VertexType data;//顶点名称 EdgeNode *firstarc;//指向第一条依附顶点的指针 } VertexNode, VertexList[MAX_VERTEX_NUM]; //顶点节点,顶点表 typedef struct GraphList { VertexList vertexList;//建立顶点表 int vertexNum, edgeNum;//整个图中存放顶点、边的个数 } GraphList; //函数声明 int findNode(GraphList &graphList, char element);//查找顶点,工具方法 bool createGraph(GraphList &graphList);//创建图 bool printGraph(GraphList &graphList);//输出图 void shortestPath_DIJ(GraphList &graphList, int vex, int P[], int D[]);//单源最短路径算法 void printShortestPath_DIJ(GraphList &graphList, int vex, int Path[], int Dest[]);//输出生成的单源最短路径 void printShortestPath_2Vexs(GraphList &graphList, int vex1, int vex2, int Path[], int Dest[]);//输出两点之间最短路径及距离 void allPath_2Vexs(GraphList &graphList, int startVex, int endVex);//任意两点之间的所有路径 void visit(GraphList &graphList, int vex, int endVex, bool status[], vector<int> &pathStack, int length);//递归访问每个元素 bool deleteGraph(GraphList &graphList);//删除图,防止内存泄露 #endif // GRAPHLIST_H_INCLUDED
6.运行截图
7.收获和体会
通过这次数据结构的课程设计,我进行了一次实践,运用数据结构的知识,针对具体问题,设计了合理的数据结构,确定相应的存储过程,并设计具体操作算法,实现了相应的功能。虽然平时也有实验,但那些只是普通的一小段而已,没有编写整个系统的机会。这次课程设计给了我一个把理论与实践相结合的机会,让我学有所用,学以致用。
这次课程设计也让我意识到一个问题——把如何把实际问题更好的融入到系统中。我认为,这个问题没有最佳答案,因为没有最好,只有更好。当你优化一个方案后,觉得已经很完美了,但是其实还有更好的方案,只是你没有找到而已。这是一个无止尽的专研过程,也是一个无限的学习过程。人生也是如此,走到哪,学到哪,活到老,学到老。
8.不足
代码编写没有特别完善,一些问题处理的也不够好。对于代码的注释也不够多,不够完整。以后做系统的时候要注意这些问题,吸取教训,好好改正,争取把代码写得更好。
- 《数据结构课程设计》求最佳路径
- 数据结构课程设计
- 数据结构课程设计
- 课程设计----数据结构
- 数据结构课程设计
- 数据结构课程设计
- 数据结构课程设计
- 数据结构课程设计
- 数据结构课程设计
- 数据结构课程设计
- 《数据结构》课程设计
- 数据结构课程设计
- 数据结构课程设计
- 数据结构课程设计
- 数据结构课程设计
- 数据结构课程设计
- 数据结构课程设计
- 数据结构课程设计
- MySQL导入.sql文件及常用命令
- 穷举—百鸡百钱
- eclipse启动tomcat访问不到主页
- wampserver apache 500 Internal Server Error
- JDK,TOMCA解压版的环境配置以及Eclipse IDE里连接Tomcat
- 《数据结构课程设计》求最佳路径
- DBUtils与C3P0结合--支持自定义字段映射和线程池
- 算法讲解—【3】—模式识别简介&贝叶斯决策理论
- but nothing on the f
- Rules of Thumb for Database Monitoring
- 那些曾让你哭过的事
- [Leetcode]Same Tree
- SQL优化
- 《你必须知道的495个C语言问题》笔记--自己的