数据结构-公园导航查询程序

本文介绍了使用Java和Eclipse开发环境中,如何运用邻接表和邻接矩阵实现图的存储结构,以及Dijkstra和Floyd算法求解最短路径问题。通过设计公园景点地图应用,展示了如何在实验中解决时间最省的路径规划问题并编写实验报告。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、项目目的

1、掌握图的相关概念;

2、掌握图的存储结构;

3、掌握图的遍历算法;

4、掌握图的应用。

二、实验内容

设计有N个公园景点的平面图,为来访参观游玩的客人提供时间最省的优质服务。(设计公园导游咨询的模拟程序)

  1. 采用邻接表或邻接矩阵存储结构;
  2. 可以查询任意两个景点间的最短路径;
  3. 尝试求解遍历全部景点时间最省的程序。
  4. 用例测试运行程序。

注:景点个数,名称,权值自定。

三、实验要求

1、实验报告要求用Java语言实现,2或3人一组。

2、完成“数据结构项目情境实验报告”。

3、完成项目程序代码的编写,并能正确运行

四、开发环境及人员分工

集成开发环境(IDE)

              Eclipse   JAVA 

项目成员

分工

五、实现过程详细说明

1.采用邻接表或邻接矩阵存储结构,掌握图的相关概念;

2.可以查询任意两个景点间的最短路径,掌握图的存储结构;

3.尝试求解遍历全部景点时间最省的程序,掌握图的遍历算法。

六、实验总结

过而能改,善莫大焉。在课程设计过程中,我们不断发现错误,不断改正,不断领悟,不断获龋最终的检测调试环节,本身就是在践行过而能改,善莫大焉的知行观。机器是比任何教师更严厉的检查者。因此,在数据结构的学习过程中,必须严格按照老师的要求,主动地、积极地、认真地做好每一个实验,以不断提高自己的编程能力与专业素质。

七、代码实现(程序粘贴,运行结果截图)

邻接矩阵图Dijkstra算法:

public void Dijkstra(String name) {

           int v = findByName(name);

           dist = new int[numOfVertex];//存储最短距离数组

           pre = new int[numOfVertex];//前驱顶点数组

           for (int i = 0; i < numOfVertex; i++) {

           //初始化,距离数组(dist)变为起点直接到该点的距离,

           //前驱数组(pre)全变为-1,

           //遍历数组(isVisit)变为false代表没有被遍历

                 isVisit[i] = false;

                 dist[i] = Edge[v][i];

                 if (dist[i] < MAX) {pre[i] = v;} else { pre[i] = -1;}}

           dist[v] = 0;//起点到自身距离为0

           isVisit[v] = true;

           for (int i = 0; i < numOfVertex - 1; i++) {

           //循环次数为顶点个数,松弛(顶点个数-1)次,

           //每次循环确定一个点,表示起点到该点最短距离确定(除起点)

          

                 int min = MAX;//记录最短路径的距离

                 int u = v;//记录最短路径的终点

                 for (int j = 0; j < numOfVertex; j++) {

                 //此循环寻找最短的路径和终点坐标

                 //贪心算法,找路径最短的并加入最短距离构造数组,

                      if (isVisit[j] == false && dist[j] < min) {

                      //如果小于min且最短距离未被找到,替代,并记录终点下标

                            u = j;

                            min = dist[j];

                      }}isVisit[u] = true;//最短的路径终点的最短路径找到for (int k = 0; k < numOfVertex; k++) {

                 //此循环判断,先经过该点再到其他点,距离是否会变短,

                 //若变短,更新距离

                      int w = getWeight(u, k);//获取u到k路径长

                      if (isVisit[k] == false && w < MAX && dist[u] + w < dist[k]) {//若该点最短距离未被找到,判断是否能松弛//判断v直接到k距离短,和v到u再到k距离哪个短

                            dist[k] = dist[u] + w;

                            pre[k] = u; }     }}

           printPath(v);//打印路径}private void printPath(int v) {

           for (int i = 0; i < numOfVertex; i++) {

                 LinkedList d = new LinkedList();//用链表存储路径

                 if (i != v) {//当顶点不等于起点,继续打印路径

                      System.out.print(Vertex[v] + "-->");

                      d.add(Vertex[i]);

                      int dan = pre[i];//获取前驱顶点下标

                      while (dan != v) {//

                            d.add(Vertex[dan]);//将前驱下标顶点信息加入链表

                            dan = pre[dan];//找前驱的前驱

                      }

                      for (int j = d.size(); j > 0; j--) {//链表正序存储反的路径,则逆序打印路径

                            if (j != 1) {

                                  System.out.print(d.get(j - 1) + "-->");} else {System.out.print(d.get(j - 1) + ":" + dist[i]);}      }System.out.println();      }     }}

测试代码:

public class Main {

      public static void main(String[] args) {

           Graph g = new Graph(20);

           g.insertVertex("A");

           g.insertVertex("B");

           g.insertVertex("C");

           g.insertVertex("D");

           g.insertVertex("E");

           g.insertEdge("A", "B", 2);

           g.insertEdge("A", "C", 5);

           g.insertEdge("A", "D", 1);

           g.insertEdge("C", "D", 1);

           g.insertEdge("C", "B", 3);

           g.insertEdge("D", "E", 9);

           g.insertEdge("E", "B", 10);

           g.insertEdge("E", "C", 1);

           g.Dijkstra("A");;}邻接链表:

      public void Dijkstra(String name) {

         pre =new int [numVertex];//初始化构造数组,数组长度为顶点个数

         dist =new int [numVertex];

        

         int v = findNum(name);

         inti(v);//初始化三个数组

         LinkedList<Integer> Q = new LinkedList();//未操作顶点集for(int i=0;i<numVertex;i++){//将所有顶点加入Q//表示所以顶点最短路径都还没被找到

              Q.add(i);//顶点下标加入链表

         }hile(!Q.isEmpty()) {//Q不空代表,最短路径并未全被找到

              int u = MIN(Q);//Min找最短路径,并返回终点下标

              //获取u后,开始松弛操作,与u相邻的顶点才能松弛成功

              //所有获取以u相接的边

              LinkedList <Edge> list = Edges[u];//获取与u相邻的边集

              while(!list.isEmpty()) {//当list不空,继续松弛操作relax(list.pop());//松弛操作函数,pop将此边退出}}show();//输出函数}

     public void show() {//打印函数

         Stack<Integer>[] routes = new Stack[numVertex];//利用栈先进后和前驱顶点是从后向前读取的,

         //栈数组依次存储对应顶点的最短路径经过顶点

         for(int i = 0;i<numVertex;i++) {//将对应顶点的前驱顶点依次加入数组

              routes[i] = new Stack();

              int j = i;



              while (j != -1) {//不等于-1,表示未到起点



                   routes[i].push(j);//将当前的前驱顶点加入到栈中



                   j = pre[j];//获取上一个前驱顶点



              }while (!routes[i].isEmpty()) {//输出int k = routes[i].pop();

                   if(routes[i].size()==1) {

                       System.out.print(vertex[k].name);

                   }else {   System.out.print("-->" + vertex[k].name);}}

              if(dist[i]==MAX) {

                   System.out.print("无法到达");

              }else {

                   System.out.print(":"+dist[i]);}

              System.out.println();}

     private void relax(Edge edge) {//松弛操作函数

         int v1 = findNum(edge.Start.name);//获取起点下标

         int v2 = findNum(edge.End.name);//获取终点下标

         int w = edge.getWeight();//获取该边权重

         if(dist[v2]>dist[v1]+w) {//若经过该边到v2更短,则松弛成功

              dist[v2] = dist[v1]+w;//更新dist数组

              pre[v2] = v1;//该边前驱节点}}

     private int MIN(LinkedList<Integer> q) {//找dist里最小的路径

         if(q.isEmpty()) {return -1;}

         int min = q.getFirst();//获取还为找到最短路径的其中一个顶点

         for(int i = 0;i<q.size();i++) {//与Q中剩下的顶点依次比较对应的dist数组里的值

              int v = q.get(i);if(dist[min]>dist[v]) {//依次比较min = v;}}

         q.remove(q.indexOf(min));

         return min;}private void inti(int v) {

         for(int i = 0;i <numVertex;i++) {dist[i] = MAX;

              pre[i] = -1;isVisit[i] = false; }dist[v] = 0;}

多源最短路径(邻接矩阵):public void Floyd() {

           distance = Edge;//复制邻接矩阵

           for (int k = 0; k < numOfVertex; k++) {//k个顶点,依次对各点松弛

                 for (int i = 0; i < numOfVertex; i++) {//松弛i行

                      for (int j = 0; j < numOfVertex; j++) {//松弛j列

                            distance[i][j] = Math.min(distance[i][j], distance[i][k] + distance[k][j]);

                            //更新distance数组,松弛成功获取后一结果

                            //distance[i][k] + distance[k][j]-->i到k到j}}}

           for (int i = 0; i < numOfVertex; i++) {//输出distance数组

                 System.out.print("节点" + (i + 1) + " 的最短路径");

                 for (int j = 0; j < numOfVertex; j++) {

                      if(distance[i][j] == Integer.MAX_VALUE/2) {System.out.print("MAX" + " ");

                      }else {System.out.print(distance[i][j] + " ");}}System.out.println();}}

测试代码public class Main {

     public static void main(String[] args) {

         Graph g = new Graph(20);g.insertVertex("A");g.insertVertex("B");g.insertVertex("C");

         g.insertVertex("D");g.insertVertex("E");g.insertEdge("A", "B", 2);g.insertEdge("A", "C", 5);

         g.insertEdge("A", "D", 1);g.insertEdge("C", "D", 1);g.insertEdge("C", "B", 3);

g.insertEdge("D", "E", 9);g.insertEdge("E", "B", 10);g.insertEdge("E", "C", 1);g.Floyd();}}

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值