数据结构——java停车场管理系统

内容描述

设有一个可停放 N 辆汽车的狭长停车场 , 只有一个大门供车辆出入 。车辆按到达先后顺序依次从最里面向大门口停放 。如果已放满 N 辆车 , 再来的车辆只能在大门外的便道上等待 一旦有车辆从停车场离开排在便道上的车辆可依次进入停车场 。
停车场中某辆车离开时 ,在它之后进入停车场的车辆必须为它让路退出停车场 ,等该车辆离开后其后车辆依原次序进入停车场 ,每辆汽车在离开时 ,都要依据停留时间交费 ;停在便道上的车辆不收费 ,在便道上某辆汽车进入停车场或离去后 ,其余车辆仍然保持原来次序。

输入

汽车的模拟输入信息格式可以是 : ( 到达 / 离去的标识 , 汽车牌照号码 , 到达 / 离去的时刻) 。 例如 , ( ‘A’,1,5 ) 表示 1 号牌照汽车在时刻 5 到达 , 而 ( ‘D’,5,20 ) 表示 5 号牌照汽车在时刻 20 离去 。 整个程序在输入信息 (‘E’,0,0 ) 时结束 。

输出

要求程序输出每辆车到达后的 停车位置( 停车场或便道上 ) , 以及某辆车离开停车场时应交纳的费用和在停车场内停留的时间

运行结果

在这里插入图片描述

思路

  1. 首先我们先阅读一下内容要求,重点是一个狭窄的停车场,而且按照进来顺序停放,车辆离开的时候需要后面的车让路离开停车场再停进来,我们显然可以判断这是一个链式存储结构,我们可以用单链表来表示停车场。
  2. 我们再看便道,重点是一头进另一头出,我们可以想到便道则是顺序结构——队列。
  3. 要求中还说了记录时间,我们可以用hashmap,用键值对的形式记录对应的车牌号跟时间。
  4. 还要考虑以下几种情况
    当停车场没停满时: 到达的车直接开进停车场;离开的车直接退出停车场。
    当停车场停满时:
    ①便道有车,到达的车停进便道队尾;离开的车离开停车场,便道在队首的车开进停车场。
    ②便道无车,到达的车直接停到便道队首;离开的车直接退出停车场。

定义我们要使用的数据结构

定义单链表

需要用到的函数

添加:add(int data)

遍历:traverseList()
删除:deleteNode(int data)
长度:size()
是否为空:isEmpty()

class LinkedList {
    private Node first;//定义头节点
    private int nItems;//定义单链表中实际的数据的数目


    /**
     * 初始化
     */
    public LinkedList() {
        this.first = null;
        this.nItems = 0;
    }

    /**
     * 添加头节点
     * @param data
     */
    public void addFirst(int data) {
        //新建节点
        Node newNode = new Node(data);
        //将新节点的下一个节点指向旧的头节点
        newNode.next = first;
        //将新节点设为头节点
        first = newNode;

        nItems ++;
    }


    /**
     * 删除头结点
     * @return
     */
    public boolean deleteFirst() {
        //判断链表是否为空
        if(isEmpty()) {
            System.out.println("链表为空!");
            return false;
        }
        first = first.next;
        nItems --;
        return true;
    }


    /**
     * 插入
     * @param data
     */
    public void add(int data) {
        //创建新节点
        Node newNode = new Node(data);
        //创建要插入节点的位置上原来的节点
        Node current = first;
        //原来位置为新插入节点
        first = newNode;
        //新插入节点的下一个为原节点
        newNode.next = current;
        nItems ++;
    }

    /**
     * 有序链表的插入,这样简单排序就可以用链表来实现,复杂度为O(N)
     * @param data
     */
    public void add2(int data) {
        //创建新节点
        Node newNode = new Node(data);
        //创建要插入节点之前的节点
        Node previous = null;
        //创建要插入节点的位置上原来的节点
        Node current = first;
        //按从小到大的顺序排序
        while(current != null && data > current.data) {
            previous = current;
            current = current.next;
        }
         if(previous == null) {
        first = newNode;
        }else {
            previous.next = newNode;
        }
        newNode.next = current;
        nItems ++;
    }

    /**
     * 查询某个特定值的节点
     * @param data
     * @return
     */
    public Node findNode(int data) {
        //定义一个新节点用于查询
        Node current = first;
        while(current != null && current.data != data) {
            if(current.next == null) {
                System.out.println("该节点不存在");
                return null;
            }
            current = current.next;
        }
        return current;
    }


    /**
     * 删除某个特定值的节点,并返回该节点
     * @param data
     * @return 删除的节点
     */
    public Node deleteNode(int data) {
        //定义被删除节点之前的节点
        Node previous = null;
        //定义被删除的节点
        Node current = first;
        while(current != null && current.data != data) {
            if(current.next == null) {
                System.out.println("该节点不存在");
                return null;
            }
            previous = current;
            current = current.next;
        }
        if(previous == null) {
            first = first.next;
        }else {
            previous.next = current.next;
        }
        nItems --;
        return current;
    }


    /**
     * 遍历链表
     */
    public void traverseList() {
        //定义一个节点用于遍历
        Node current = first;
        //判断链表是否为空
        if(current == null) {
            System.out.println("链表为空!");
            return;
        }
        while(current != null) {
            System.out.println(current.data);
            current = current.next;
        }
    }

    /**
     *
     * @return 链表的长度
     */
    public int size() {
        return nItems;
    }


    /**
     * 判断链表是否为空
     * @return
     */
    public boolean isEmpty() {
        return first == null;
    }

}

定义节点

class Node{

    //指向下一个节点
    public Node next;
    //数据域
    public int data;

    public Node(int data) {
        this.data = data;
    }
}

定义队列

需要用到的函数

添加:insert(int g)
删除:remove()

class Queue {

    private int[] queArray;
    private int maxSize;
    private int front;  //队头
    private int rear;	//队尾
    private int nItems;
    /**
     * 初始化
     */
    public Queue(int maxSize) {
        this.maxSize = maxSize;
        queArray = new int[maxSize];
        front = 0;
        rear = 0;
        nItems = 0;
    }



    /**
     * 在队尾插入
     * @param g
     */
    public void insert(int g) {
        if (rear == maxSize-1) {
            rear = -1;
        }//

        queArray[++rear] = g;
        nItems++;
    }


    /**
     * 从队头删除
     */
    public void remove() {
        int temp = queArray[front++];
        if (front==maxSize) {
            front = 0;
        }
        nItems--;

    }


    /**
     * 查看
     * @return 查看的元素
     */
    public int peekFront() {
       // System.out.println(queArray[front]);
        return queArray[front];
    }


    /**
     * 判断是否为空
     * @return
     */
    public boolean isEmpty() {
        return nItems == 0;
    }


    /**
     * 判断是否已经满了
     * @return
     */
    public boolean isFull() {
        return nItems == maxSize;
    }


    /**
     *
     * @return 队列的大小
     */
    public int size() {
        return nItems;
    }

}

代码实现

public static void main(String[] args) {
        //用队列创建便道,设置能停放9999辆车
        Queue queue=new Queue(99999999);
        //用单链表创建停车场
        LinkedList linkedList=new LinkedList();
        //用hashmap记录时间
        HashMap<Integer,Integer> hashMap=new HashMap<>();
        Scanner scanner=new Scanner(System.in);
        while (true){
          System.out.println("请输入操作A或者D(到达或离开),再输入车牌号,再输入时间");
          String s= scanner.next();
          if (s.equals("end")){
             break;
          }
            /**
             * 车到达
             */
          if (s.equals("A")) {
              //当停车场没停满时
              if (linkedList.size() < 2) {
                    //车牌号
                    int n = scanner.nextInt();
                    //时间
                    int t = scanner.nextInt();
                    //进入停车场
                    linkedList.add(n);
                    //记录时间
                    hashMap.put(n, t);
                    System.out.println("车牌号为"+n+"已到达停车场");
                    continue;
              }
              //停车场满了,需要停便道上
              else {
                    //车牌号
                    int n = scanner.nextInt();
                    //时间
                    int t = scanner.nextInt();
                    //停进便道
                    queue.insert(n);
                    System.out.println("车牌号为"+n+"已到达便道");
                    //这里不需要记录时间
                }
              }
            /**
             * 车离开
             */
          if (s.equals("D")) {
              //停车场没满
                if (linkedList.size() < 2) {
                    //车牌号
                    int n = scanner.nextInt();
                    //离开时间
                    int t = scanner.nextInt();
                    //这辆车的开始时间
                    int starttime = hashMap.get(n);
                    //开走
                    linkedList.deleteNode(n);
                    System.out.println("车牌号为" + n + "的停车时间" + (  t-starttime));

                }
                //停车场满了
                else {
                    //车牌号
                    int n = scanner.nextInt();
                    //离开时间
                    int t = scanner.nextInt();
                    //这辆车的开始时间
                    int starttime = hashMap.get(n);
                    //开走
                    linkedList.deleteNode(n);
                    //停车场车开走
                    System.out.println("车牌号为" + n + "的停车时间" + (  t-starttime));
                    //如果便道空了,就没有车从便道开进停车场
                    if (!queue.isEmpty()){
                    //便道车开走
                    queue.remove();
                    //获得车牌号
                    int car=queue.peekFront();
                    System.out.println(car+"从便道开进停车场");
                    //进停车场
                    linkedList.add(car);
                    //记录进停车场时间
                    hashMap.put(car,t);
                }}
            }
        }}
  }
  • 7
    点赞
  • 62
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
设有一个可以停放n汽车狭长停车场,它只有一个大门可以车辆进出车辆到达停车场时间的早晚依次从停车场最里向大门口处停放(最先到达的第一车放在停车场的最里面)。如果停车场已放满n车,则后来的车只能在停车场大门外的便道上等待,一旦停车场内有车开走,则排在便道上的第一车就进入停车场停车场内如有某车要开走,在它之后进入停车场的车都必须先退出停车场为它让路,待其开出停车场后,这些车辆再依原来的次序进场。每车在离开停车场时,都应根据它在停车场内停留的时间长短交费。如果停留在便道上的车未进停车场就要离去,允许其离去,不收停车费,并且仍然保持在便道上等待的车辆次序。编制一程序模拟该停车场的管理。(2) 实现要求:要求程序输出每到达后的停车位置(停车场或便道上),以及某车离开停车场时应交纳的费用和它在停车场内停留的时间。(2) 实现提示:汽车的模拟输入信息格式可以是:(到达/离去,汽车牌照号码,到达/离去的时刻)。例如,(’A’,1,5)表示1号牌照车在5时刻到达,而(’D’,5,20)表示5号牌照车在20时刻离去。整个程序可以在输入信息为(’E’,0,0)时结束。本题可用顺序存储结构和链式存储结构来实现。本人的一个数据结构课程设计(用C++源码实现,大家学习参考之用,有不妥之处望指正)
实验二 停车场管理 班级:A0712 学号:12 姓名:冷清淼 成绩:__________ 指导教师签名:__________ 一、问题描述 设停车场一个停放n车的狭长通道,且只有一个大门汽车进出。在停车场汽车到达的先后次序,由北向南依次排列(假设大门在最南端)。若停车场已停满 n车,则后来的汽车需在门外的便道上等候,当有车开走时,便道上的第一车即可开 入。当停车场车要离开时,在它之后进入的车辆必须先退出停车场为它让路,待该 车开出大门后,其他车辆再按原次序返回车场。每车离开停车场时,应按其停留时 间的长短交费(在便道上停留的时间不收费)。 设计要求: 1.模拟上述管理过程。要求以顺序栈模拟停车场,以链队列模拟便道。 2.从终端读入汽车到达或离去的数据,每组数据包括三项: (1)是"到达"还是"离开"; (2)汽车牌照; (3)"到达"或"离开"的时刻。 3.与每组输入信息相应的输出信息为:如果是到达车辆,则输出其在停车场中或 便道上的位置;如果是离去的车辆,则输出其在停车场中停留的时间和应交的费用。 二、算法说明 1.数据结构说明 (1)用到两个堆栈:一个为车场栈;另一个为临时栈temp typedef struct NODE{ CarNode *stack[MAX+1]; int top; }SeqStackCar; /*模拟车场*/ 一个队列结构,存储便道车辆信息: typedef struct Node{ QueueNode *head; QueueNode *rear; }LinkQueueCar; /*模拟便道*/ 2.算法说明 (1) 功能模块说明:停车场管理系统含有三个模块,即:车辆到达、离开、列表显示 图1 (2)以模块为单位分析算法 1、"到达"模块:到达时有两种情况,即车场是否满,未满则直接进入停车场;满时,到 便道等待。如图2。 图2 2."离开"模块:离开时,当车库为空时,提示没有车,结束;否则车辆离开。如图3。 图3 3. "显示"模块:显示模块有两个显示选项,即:车场与便道。如图4。 图4 三、测试结果 (一)测试用例(说明:测试用例要合理并且足够,既要有正确用例,也要有错误用例 ,同时检验程序的正确性和强壮性) 1.第一组测试用例 (1)测试输入:停车场车辆离开,如下表: "服务选择 "车牌号/车位 "到达/离开时间 " "1 "QH058 "15:25 " "1 "AB123 "18:45 " "1 "EA642 "23:15 " "2 "2 "0:30 " "2 "1 "0:65(错误) " (2)测试目的:测试离开方法时间格式控制以及费用计算是否正确。 (3)正确输出:第一次离开的是AB123,应交费3.45元。第二次时,当在输入65时, 应该提示输入错误,重输。 (4)实际输出: (5)错误原因:第一个错误是在计算时,一个数字错了;第二个是没有对时间格式 控制。 (6)当前状态:已改正 2.第二组测试用例 (1)测试输入:连续6到达,如下表: " 服务选 " 车牌号 " 到达时间 " "择 " " " "1 "A8828 "7:56 " "1 "S2296 "8:25 " "1 "WW666 "8:45 " "1 "HK456 "15:50 " "1 "GH999 "12:30 " "1 "DD555 "13:40 " 测试目的:测试到达方法与列表显示方法能否正确完成。 (3)正确输出:先到达的五车先进入停车场,最后到达的一在便道等候。 (4)实际输出: (5)错误原因:没有作出时间先后的判断,而是先输入先进入。 (6)当前状态:待修改 3.第三组测试用例 (1)测试输入:接上一步输入离开信息,下表: "服务选择"离开车位"离开时间"便道车进入时 " " " " "间 " "2 "3 "13:30 "13:40 " (2)测试目的:测试离开方法功能是否成功以及便道进入车场是否正确。 (3)正确输出:输出3号车位的车辆离开信息清单,便道1号车进入停车场。 (4)实际输出: 错误原因:没有错误。 (6)当前状态:通过 (二)测试结果分析 此停车管理系统基本可能实现一个小的停车场的管理,其"到达"与"离开"方法都相对比 较完整,以及结算清单明了。尽管在时间先后上有出现混乱,但当其用到实际应用时, 那个时间先后就可以避免了。但在输入数据时,要按照严格的格式输入,否则有可能出 现死去或崩溃。若本系统能加上保存功能就更好了,因为一个系统在使用过程中总会关 机等,而此系统的缺点却是没有保存功能,关闭之后就要重新建立了。会慢慢完善。 附录:源代码 ///系统说明:本系统适应于小型停车场,且停车时间在一天之的短期停放停车场。 //在此系统中,车库容量设置为5,便于测

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值