2023年郑州轻工业大学软件学院数据结构实验四-图(详解+源码Java版+运行结果)

 需求分析+实验任务

实验四

一、实验目的

1. 能利用图的邻接矩阵和邻接表存储表示法构造图;

2. 掌握图的广度和深度优先搜索遍历、最短路径算法思想;

3. 能够用图的算法思想解决生活中的实际应用问题。

二、课程目标

支撑课程目标(3):能够在工程实践中选择、构建合适的数据结构,描述复杂软件工程问题中的数据及数据之间的关系,体现科学思维能力。

三、实验任务

请设计一个简单的医院导航系统,该医院主要有以下部门:门诊部(A)、住院部(B)、急诊部(C)、药房(D)、收费室(E)、化验室(F)、放射科(G)、手术室(H)、B超室(I)、行政楼(J),各部门之间的路径及距离如图1所示。

 2023年郑州轻工业大学软件学院数据结构实验四-图(详解+源码Java版+运行结果)_第1张图片

图1  某医院各部门之间的路径及距离

要求:

(1)请利用C/C++/Java语言定义数据类型;

(2)请利用邻接矩阵或邻接表创建带权图,以表示该医院各部门之间的关系;

(3)提供各部门信息查询,如输入“急诊部”,显示“急诊部”相关信息的介绍;

(4)输入任意部门A和部门B的名称,为患者提供从A到B的最短路径。

实验设计

 定义一个部门实体类Department,用于存储部门信息

class Department {
    private int id;
    private String name;
    private String location;
    private String description;  // 新增字段,用于存储部门介绍

    public Department(int id,String name, String location, String description) {
        this.id=id;
        this.name = name;
        this.location = location;
        this.description = description;
    }

    public String getName() {
        return name;
    }
    public int getId(){
        return id;
    }
    public String getLocation() {
        return location;
    }

    public String getDescription() {
        return description;
    }
}

定义一个医院类,也相当于一个业务类,用于实现业务代码,以及初始化医院所有部门,该业务代码包括:通过部门id获取部门,通过部门name获取部门

class Hospital {
    private Department[] departments;

    public Hospital() {
        // 初始化医院部门,同时添加部门介绍信息
        departments = new Department[]{
                new Department(0,"门诊部", "A", "门诊部提供非住院患者的医疗服务。"),
                new Department(1,"住院部", "B", "住院部提供住院患者的医疗服务。"),
                new Department(2,"急诊部", "C", "急诊部提供紧急医疗服务。"),
                new Department(3,"药房", "D", "药房提供药品发放服务。"),
                new Department(4,"收费室", "E", "收费室负责患者医疗费用结算。"),
                new Department(5,"化验室", "F", "化验室进行医学检验和化验。"),
                new Department(6,"放射科", "G", "放射科提供影像学诊断服务。"),
                new Department(7,"手术室", "H", "手术室进行各类手术操作。"),
                new Department(8,"B超室", "I", "B超室进行B超检查。"),
                new Department(9,"行政楼", "J", "行政楼为医院的行政管理部门。")
        };
    }
    public Department getDepartmentById(int departmentId) {
        for (Department department : departments) {
            if (department.getId()==departmentId) {
                return department;
            }
        }
        return null;
    }
    public Department getDepartmentByName(String departmentName) {
        for (Department department : departments) {
            if (department.getName().equalsIgnoreCase(departmentName)) {
                return department;
            }
        }
        return null;
    }
}

为所有部门分配权重,所以需要定义一个权重Weighted类(注释非常清楚的标明从哪个部门到哪个部门的距离,也就是权重)

注意:这里的权重是双向的,因为该实验要求既要求A->B的最短距离,也要求B->A的最短距离

 

public class Weighted {
    private int[][] adjacencyMatrix;

    public Weighted(int size) {
        adjacencyMatrix = new int[size][size];
        // 初始化邻接矩阵,用于表示各部门之间的关系
        initializeGraph();
    }

    private void initializeGraph() {
        // 部门之间的关系强度或距离,这里使用简单的示例值
        // 注意:实际情况中需要根据实际需求进行调整
        adjacencyMatrix[0][5] = 150;   // 门诊部(A) 到 化验室(F)
        adjacencyMatrix[0][4] = 190;   // 门诊部(A) 到 收费室(E)
        adjacencyMatrix[0][2] = 100;   // 门诊部(A) 到 急诊部(C)
        adjacencyMatrix[0][9] = 90;   // 门诊部(A) 到 行政楼(J)
        adjacencyMatrix[1][5] = 60;   // 住院部(B) 到 化验室(F)
        adjacencyMatrix[1][7] = 50;   // 住院部(B) 到 手术室(H)
        adjacencyMatrix[1][6] = 130;   // 住院部(B) 到 放射科(G)
        adjacencyMatrix[1][8] = 100;   // 住院部(B) 到 B超室(I)
        adjacencyMatrix[2][0] = 100;   // 急诊部(C) 到 门诊部(A)
        adjacencyMatrix[2][3] = 120;   // 急诊部(C) 到 药房(D)
        adjacencyMatrix[2][9] = 80;   // 急诊部(C) 到 行政楼(J)
        adjacencyMatrix[3][2] = 120;   // 药房(D) 到 急诊部(C)
        adjacencyMatrix[3][4] = 50;   // 药房(D) 到 收费室(E)
        adjacencyMatrix[4][3] = 50;   // 收费室(E) 到 药房(D)
        adjacencyMatrix[4][0] = 190;   // 收费室(E) 到 门诊部(A)
        adjacencyMatrix[4][5] = 150;   // 收费室(E) 到 化验室(F)
        adjacencyMatrix[5][4] = 150;   // 化验室(F) 到 收费室(E)
        adjacencyMatrix[5][0] = 150;   // 化验室(F) 到 门诊部(A)
        adjacencyMatrix[5][1] = 60;   //化验室(F) 到 住院部(B)
        adjacencyMatrix[5][7] = 100;   // 化验室(F) 到 手术室(H)
        adjacencyMatrix[6][9] = 160;   // 放射科(G) 到 行政楼(J)
        adjacencyMatrix[6][8] = 30;   // 放射科(G) 到 B超室(I)
        adjacencyMatrix[6][1] = 130;   // 放射科(G) 到 住院部(B)
        adjacencyMatrix[6][7] = 100;   // 放射科(G) 到 手术室(H)
        adjacencyMatrix[7][5] = 100;   // 手术室(H) 到 化验室(F)
        adjacencyMatrix[7][1] = 50;   // 手术室(H) 到 住院部(B)
        adjacencyMatrix[7][6] = 100;   // 手术室(H) 到 放射科(G)
        adjacencyMatrix[8][1] = 100;   // B超室(I) 到 住院部(B)
        adjacencyMatrix[8][6] = 30;   // B超室(I) 到 放射科(G)
        adjacencyMatrix[9][0] = 90;   // 行政楼(J) 到 门诊部(A)
        adjacencyMatrix[9][2] = 80;   // 行政楼(J) 到 急诊部(C)
        adjacencyMatrix[9][6] = 160;   // 行政楼(J) 到 放射科(G)

    }

    public int[][] getAdjacencyMatrix() {
        return adjacencyMatrix;
    }
}

定义一个定位系统类FindSystem,用于找到这个部门,便于后期进行迪杰斯特拉算法的寻路

public class FindSystem {
    private Hospital hospital;

    public FindSystem(Hospital hospital) {
        this.hospital = hospital;
    }

    public String getDepartmentLocationByName(int departmentId) {

        Department department = hospital.getDepartmentById(departmentId);
        if (department != null) {
            return department.getName();
        } else {
            return "未找到该部门";
        }
    }
}

 定义一个实现迪杰斯特拉算法的类DijkstraAlogorithm类,用于求最短路径

由于迪杰斯特拉算法代码过长,迪杰斯特拉算法便不再详说,大家可以自行查阅资料,也可以翻阅课本

import java.util.*;

public class DijkstraAlgorithm {
    private int[] distances;
    private Set visited;
    private PriorityQueue priorityQueue;

    public DijkstraAlgorithm(int numNodes) {
        distances = new int[numNodes];
        visited = new HashSet<>();
        priorityQueue = new PriorityQueue<>(numNodes, Comparator.comparingInt(node -> node.distance));
    }

    public int[] findShortestPaths(int[][] graph, int startNode) {
        Arrays.fill(distances, Integer.MAX_VALUE);
        distances[startNode] = 0;

        priorityQueue.add(new Node(startNode, 0));

        while (!priorityQueue.isEmpty()) {
            int currentNode = priorityQueue.poll().node;

            if (visited.contains(currentNode)) {
                continue;
            }

            visited.add(currentNode);

            for (int adjacentNode = 0; adjacentNode < graph.length; adjacentNode++) {
                if (!visited.contains(adjacentNode) && graph[currentNode][adjacentNode] != 0) {
                    int newDistance = distances[currentNode] + graph[currentNode][adjacentNode];

                    if (newDistance < distances[adjacentNode]) {
                        distances[adjacentNode] = newDistance;
                        priorityQueue.add(new Node(adjacentNode, newDistance));
                    }
                }
            }
        }

        return distances;
    }

    private static class Node {
        private int node;
        private int distance;

        public Node(int node, int distance) {
            this.node = node;
            this.distance = distance;
        }
    }
}

 定义主函数,实现相关功能

import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        int numDepartments = 10;
        Weighted weightedGraph = new Weighted(numDepartments);
        int[][] adjacencyMatrix = weightedGraph.getAdjacencyMatrix();

        Scanner scanner = new Scanner(System.in);
        System.out.print("请输入起始部门名称:");
        String startDepartment = scanner.nextLine();

        System.out.print("请输入目标部门名称:");
        String targetDepartment = scanner.nextLine();

        Hospital hospital = new Hospital();
        FindSystem findSystem = new FindSystem(hospital);

        int startNode = -1;
        int targetNode = -1;

        // 找到起始部门和目标部门在图中的对应节点编号
        for (int i = 0; i < numDepartments; i++) {
            String departName = findSystem.getDepartmentLocationByName(i);
            Department department = hospital.getDepartmentByName(departName);
            if (department.getName().equalsIgnoreCase(startDepartment)) {
                startNode = i;
            } else if (departName.equalsIgnoreCase(targetDepartment)) {
                targetNode = i;
            }
        }

        if (startNode != -1 && targetNode != -1) {
            DijkstraAlgorithm dijkstraAlgorithm = new DijkstraAlgorithm(numDepartments);
            int[] shortestPaths = dijkstraAlgorithm.findShortestPaths(adjacencyMatrix, startNode);

            int shortestDistance = shortestPaths[targetNode];

            if (shortestDistance == Integer.MAX_VALUE) {
                System.out.println("无法找到从 " + startDepartment + " 到 " + targetDepartment + " 的路径。");
            } else {
                System.out.println("从 " + startDepartment +hospital.getDepartmentByName(startDepartment).getLocation()+ " 到 " + targetDepartment +hospital.getDepartmentByName(targetDepartment).getLocation() +" 的最短路径长度为:" + shortestDistance);
                System.out.println(hospital.getDepartmentByName(targetDepartment).getDescription());
            }
        } else {
            System.out.println("输入的部门名称无效。");
        }
    }
}

代码运行测试

 Test1:门诊部->B超室

2023年郑州轻工业大学软件学院数据结构实验四-图(详解+源码Java版+运行结果)_第2张图片2023年郑州轻工业大学软件学院数据结构实验四-图(详解+源码Java版+运行结果)_第3张图片

Test2:急诊部->放射科 

 2023年郑州轻工业大学软件学院数据结构实验四-图(详解+源码Java版+运行结果)_第4张图片

2023年郑州轻工业大学软件学院数据结构实验四-图(详解+源码Java版+运行结果)_第5张图片 Test3: 药房->手术室

 2023年郑州轻工业大学软件学院数据结构实验四-图(详解+源码Java版+运行结果)_第6张图片

2023年郑州轻工业大学软件学院数据结构实验四-图(详解+源码Java版+运行结果)_第7张图片 


 代码在idea的包的位置如下(大家在创建类的时候安装这种形式创建,然后创建主函数方可运行)

2023年郑州轻工业大学软件学院数据结构实验四-图(详解+源码Java版+运行结果)_第8张图片

最后声明!!!

本文章禁止转载,禁止将代码转卖!本代码免费开源!完全供大家使用,禁止转卖!!禁止转卖!发现必究

你可能感兴趣的:(数据结构,算法,java)