数组模拟队列&&数组模拟环形队列

队列介绍

队列是一个有序列表,可以用数组或是链表来实现。
遵循先入先出的原则。即:先存入队列的数据,要先取出。后存入的要后取出
示意图:(使用数组模拟队列示意图)
在这里插入图片描述

数组模拟队列

队列本身是有序列表,若使用数组的结构来存储队列的数据,则队列数组的声明如下图, 其中 maxSize 是该队列的最大容量。

因为队列的输出、输入是分别从前后端来处理,因此需要两个变量 front及 rear分别记录队列前后端的下标,front 会随着数据输出而改变,而 rear则是随着数据输入而改变,如图所示:
在这里插入图片描述
数组模拟队列

当我们将数据存入队列时称为”addQueue”,addQueue 的处理需要有两个步骤:思路分析
将尾指针往后移:rear+1 , 当front == rear 【空】
若尾指针 rear 小于队列的最大下标 maxSize-1,则将数据存入 rear所指的数组元素中,否则无法存入数据。 rear == maxSize - 1[队列满]

代码实现
问题分析并优化

class ArrayQueue(arrMaxSize: Int) { val maxSize: Int = arrMaxSize
val array = new ArrayInt
var front: Int = -1
var rear: Int = -1
}

//初始化
val queue = new ArrayQueue(3)

rear 是队列最后[含]
front 是队列最前元素[不含]

数组模拟队列

出队列操作getQueue
显示队列的情况showQueue
查看队列头元素headQueue
退出系统exit

将原来的队列的查看队列头元素的代码写完.

代码示例:

package com.madi.queue;

import com.sun.jmx.remote.internal.ArrayQueue;

import java.util.Scanner;

public class TestQueue {
    public static void main(String[] args) {
          //测试一把
            //创建一个队列
           ArrayQueue queue=new ArrayQueue(3);
           char key=' ';//接收用户输入
        Scanner scanner=new Scanner(System.in);
        boolean loop=true;
        //输出一个菜单
        while (loop){
            System.out.println("s(show):显示队列");
            System.out.println("e(exit):退出程序");
            System.out.println("a(add):添加数据到队列");
            System.out.println("g(get):从队列取出数据");
            System.out.println("h(head):查看队列头的数据");
            key=scanner.next().charAt(0);//接收一个字符
            switch (key){
                case 's':
                    queue.showQueue();
                    break;
                case 'a':
                    System.out.println("输出一个数");
                    int value=scanner.nextInt();
                    queue.addQueue(value);
                    break;
                case 'g'://取出数据
                    try {
                      int res=queue.getQueue();
                      System.out.printf("取出的数据是%d\n",res);
                    }catch (Exception e){
                           System.out.println(e.getMessage());
                    }
                    break;
                case 'h'://查看队列头的数据
                     try {
                      int res=queue.headQueue();
                      System.out.printf("队列头的数据是%d\n",res);
                     }catch (Exception e){
                           System.out.println(e.getMessage());
                     }
                    break;
                case 'e'://退出
                     scanner.close();
                     loop=false;
                    break;

                    default:
                        break;
            }
        }
        System.out.println("程序退出--");
    }

    static class  ArrayQueue {
        private int maxSize;//表示数组的最大容量
        private int front;//队列头
        private int rear;//队列尾
        private int[] arr;//该数据用于模拟数据,存放队列

        //创建队列的构造器
        public ArrayQueue(int arrMxSize) {
            maxSize = arrMxSize;
            arr = new int[maxSize];
            front = -1;//指向队列头部,分析出front是指向队列头的前一个位置
            rear = -1;//指向队列尾,指向队列尾的数据(即就是队列最后一个数据)
        }
        //判断队列是否满
          public  boolean isFull(){
            return  rear==maxSize-1;
          }
         //判断队列是否为空
        public  boolean isEmpty(){
            return  rear==front;
        }
        //添加数据到队列
        public  void addQueue(int n){
            //判断队列是否满
            if(isFull()){
                System.out.println("队列满,不能加入数据");
                return;
            }
            rear++;//让rear后移
            arr[rear]=n;
                               }
           //获取队列的数据,出队列
         public  int getQueue(){
            //判断队列是否为空
             if(isEmpty()){
                 //通过抛出异常
                 throw  new RuntimeException("队列空,不能取数据");

             }
             front++;//front后移
             return  arr[front];

         }
         //显示队列的所有数据
        public void  showQueue(){
            //遍历
            if(isEmpty()){
                System.out.println("队列空的,没有数据");
                 return;
            }
            for (int i=0;i<arr.length;i++){
                System.out.printf("arr[%d]=%d\n",i,arr[i]);
            }
        }
        //显示队列的头数据,注意不是取出数据
            public  int headQueue(){
               //判断
                if(isFull()){
                    System.out.println("队列空的,没有数据");
                    throw new RuntimeException();
                }
                return  arr[front+1];
            }
    }




}

数组模拟环形队列

在这里插入图片描述
在这里插入图片描述

package com.madi.queue;

import java.util.Scanner;

public class CircleArraryQueue  {
    public static void main(String[] args) {
              //测试案例
        System.out.println("测试数组模拟环形队列的案例");
        //创建一个环形队列
        CircleArrary queue=new CircleArrary(4);//说明设置4,其队列的有效数据最大是3
        char key=' ';//接收用户输入
        Scanner scanner=new Scanner(System.in);
        boolean loop=true;
        //输出一个菜单
        while (loop){
            System.out.println("s(show):显示队列");
            System.out.println("e(exit):退出程序");
            System.out.println("a(add):添加数据到队列");
            System.out.println("g(get):从队列取出数据");
            System.out.println("h(head):查看队列头的数据");
            key=scanner.next().charAt(0);//接收一个字符
            switch (key){
                case 's':
                    queue.showQueue();
                    break;
                case 'a':
                    System.out.println("输出一个数");
                    int value=scanner.nextInt();
                    queue.addQueue(value);
                    break;
                case 'g'://取出数据
                    try {
                        int res=queue.getQueue();
                        System.out.printf("取出的数据是%d\n",res);
                    }catch (Exception e){
                        System.out.println(e.getMessage());
                    }
                    break;
                case 'h'://查看队列头的数据
                    try {
                        int res=queue.headQueue();
                        System.out.printf("队列头的数据是%d\n",res);
                    }catch (Exception e){
                        System.out.println(e.getMessage());
                    }
                    break;
                case 'e'://退出
                    scanner.close();
                    loop=false;
                    break;

                default:
                    break;
            }
        }
        System.out.println("程序退出--");
    }

    static class  CircleArrary{
        private int maxSize;//表示数组的最大容量
        //front 变量的含义做一个调整:front就指向队列的第一个元素,也就是说arr[front]
        //front 的初始值=0;
        private int front;//队列头

        //rear变量的含义做一个调整:rear指向队列的最后一个元素的后一个位置,因为希望空出一个位置
        //rear的初始值为=0
        private int rear;//队列尾
        private int[] arr;//该数据用于模拟数据,存放队列

        //创建队列的构造器
        public CircleArrary(int arrMxSize) {
            maxSize = arrMxSize;
            arr = new int[maxSize];

        }
        //判断队列是否满
          public  boolean isFull(){
            return (rear+1) % maxSize==front;
          }
         //判断队列是否为空
        public  boolean isEmpty(){

            return  rear==front;
        }
        //添加数据到队列
        public  void addQueue(int n){
            //判断队列是否满
            if(isFull()){
                System.out.println("队列满,不能加入数据");
                return;
            }
           //直接将数据加入
            arr[rear]=n;
           //将rear后移,这里必须考虑取模
            rear=(rear+1)%maxSize;
        }
           //获取队列的数据,出队列
         public  int getQueue(){
            //判断队列是否为空
             if(isEmpty()){
                 //通过抛出异常
                 throw  new RuntimeException("队列空,不能取数据");

             }
             //这里需要先分析出front是指向队列的第一个元素
             //1.先把front的值保存到一个临时变量
             //2.将front后移,
             //3.将临时保存的变量返回
             int value=arr[front];
             front=(front+1)%maxSize;
              return  value;



         }
         //显示队列的所有数据
        public void  showQueue(){
            //遍历
            if(isEmpty()){
                System.out.println("队列空的,没有数据");
                 return;
            }
            //思路:从front开始遍历,遍历多少个元素
            //
            for (int i=front;i<front+size();i++){
                System.out.printf("arr[%d]=%d\n",i%maxSize,arr[i%maxSize]);
            }
        }
        //求出当前队列有效数据的个数
        public int size(){
            //rear=1;
            //front=0;
            //maxSize=3;
            return (rear+maxSize-front)%maxSize;
        }


        //显示队列的头数据,注意不是取出数据
            public  int headQueue(){
               //判断
                if(isFull()){
                    System.out.println("队列空的,没有数据");
                    throw new RuntimeException();
                }
                return  arr[front];
            }
    }




}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
1 目标检测的定义 目标检测(Object Detection)的任务是找出图像所有感兴趣的目标(物体),确定它们的类别和位置,是计算机视觉领域的核心问题之一。由于各类物体有不同的外观、形状和姿态,加上成像时光照、遮挡等因素的干扰,目标检测一直是计算机视觉领域最具有挑战性的问题。 目标检测任务可分为两个关键的子任务,目标定位和目标分类。首先检测图像目标的位置(目标定位),然后给出每个目标的具体类别(目标分类)。输出结果是一个边界框(称为Bounding-box,一般形式为(x1,y1,x2,y2),表示框的左上角坐标和右下角坐标),一个置信度分数(Confidence Score),表示边界框是否包含检测对象的概率和各个类别的概率(首先得到类别概率,经过Softmax可得到类别标签)。 1.1 Two stage方法 目前主流的基于深度学习的目标检测算法主要分为两类:Two stage和One stage。Two stage方法将目标检测过程分为两个阶段。第一个阶段是 Region Proposal 生成阶段,主要用于生成潜在的目标候选框(Bounding-box proposals)。这个阶段通常使用卷积神经网络(CNN)从输入图像提取特征,然后通过一些技巧(如选择性搜索)来生成候选框。第二个阶段是分类和位置精修阶段,将第一个阶段生成的候选框输入到另一个 CNN 进行分类,并根据分类结果对候选框的位置进行微调。Two stage 方法的优点是准确度较高,缺点是速度相对较慢。 常见Tow stage目标检测算法有:R-CNN系列、SPPNet等。 1.2 One stage方法 One stage方法直接利用模型提取特征值,并利用这些特征值进行目标的分类和定位,不需要生成Region Proposal。这种方法的优点是速度快,因为省略了Region Proposal生成的过程。One stage方法的缺点是准确度相对较低,因为它没有对潜在的目标进行预先筛选。 常见的One stage目标检测算法有:YOLO系列、SSD系列和RetinaNet等。 2 常见名词解释 2.1 NMS(Non-Maximum Suppression) 目标检测模型一般会给出目标的多个预测边界框,对成百上千的预测边界框都进行调整肯定是不可行的,需要对这些结果先进行一个大体的挑选。NMS称为非极大值抑制,作用是从众多预测边界框挑选出最具代表性的结果,这样可以加快算法效率,其主要流程如下: 设定一个置信度分数阈值,将置信度分数小于阈值的直接过滤掉 将剩下框的置信度分数从大到小排序,选值最大的框 遍历其余的框,如果和当前框的重叠面积(IOU)大于设定的阈值(一般为0.7),就将框删除(超过设定阈值,认为两个框的里面的物体属于同一个类别) 从未处理的框继续选一个置信度分数最大的,重复上述过程,直至所有框处理完毕 2.2 IoU(Intersection over Union) 定义了两个边界框的重叠度,当预测边界框和真实边界框差异很小时,或重叠度很大时,表示模型产生的预测边界框很准确。边界框A、B的IOU计算公式为: 2.3 mAP(mean Average Precision) mAP即均值平均精度,是评估目标检测模型效果的最重要指标,这个值介于0到1之间,且越大越好。mAP是AP(Average Precision)的平均值,那么首先需要了解AP的概念。想要了解AP的概念,还要首先了解目标检测Precision和Recall的概念。 首先我们设置置信度阈值(Confidence Threshold)和IoU阈值(一般设置为0.5,也会衡量0.75以及0.9的mAP值): 当一个预测边界框被认为是True Positive(TP)时,需要同时满足下面三个条件: Confidence Score > Confidence Threshold 预测类别匹配真实值(Ground truth)的类别 预测边界框的IoU大于设定的IoU阈值 不满足条件2或条件3,则认为是False Positive(FP)。当对应同一个真值有多个预测结果时,只有最高置信度分数的预测结果被认为是True Positive,其余被认为是False Positive。 Precision和Recall的概念如下图所示: Precision表示TP与预测边界框数量的比值 Recall表示TP与真实边界框数量的比值 改变不同的置信度阈值,可以获得多组Precision和Recall,Recall放X轴,Precision放Y轴,可以画出一个Precision-Recall曲线,简称P-R
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值