zoukankan      html  css  js  c++  java
  • Java数据结构之队列

    队列的基本介绍

    队列,是一个线性表,分为顺序队列和链式队列,本节我们说的是顺序队列。

    队列存储在一段连续的存储空间之内(数组),它自身的特点是:先进先出,即从队尾添加元素,对头删除元素。

    在平时的生活中,打印机等等用到的原理都是队列。

    接下来我所讲的跟队列有关的内容分为两种:普通队列,循环队列。下面所有的代码都是可执行的(本人编写,亲测可用),写了一个小程序,用来实现队列的各种方法。

    普通队列

    示意图如下:

     在这个队列中,我们暂定指向对头的指针为front,指向队尾的指针为rear,我们将front和rear的初始值都设置为-1,front会随着数据的输出而改变,rear也会随着数据的输入而改变。其次,在这个图中我们可以发现,我们需要给定一个数组的最大长度maxSize,并且显示一个数组。因此,我们可以得出的结论就是,在我们Java的构造函数中应该有4个元素:front,rear,maxSize,int[] arr;

    关于普通队列的操作,由上图所示:

    (1).当队列为空时:

    front == rear;

    (2).当队列为满时:

    rear = maxSize-1;

    (3).当添加队列元素时(假设添加的元素是n):

    rear++;
    
    arr[rear] = n;

    (4).当删除队列元素时(这时,我们的程序需要返回删除的元素的值):

    int value = 0;
    
    front++;
    
    value = arr[front];

    (5).当遍历这个队列中的元素的时候,相应的,我们只需要遍历这个数组即可。

    代码展示

    在下面的代码中我会用注释说明,添加元素,删除元素等等的队列操作。(使用的编译器是Eclipse)

    package queue;
    
    import java.util.Scanner;
    
    public class ArrayQueueDemo_1 {
    
        public static void main(String[] args) {
            
            ArrayQueued que = new ArrayQueued(4);
            
            Scanner sc = new Scanner(System.in);
            //用于用户的输入
            char key = ' ';
            //标志变量
            boolean flag = true;
            while(flag){
            
                System.out.println("显示队列元素:s");
                System.out.println("添加队列元素:a");
                System.out.println("删除队列元素:d");
                System.out.println("显示队头元素:h");
                System.out.println("退出程序:e");
                //charAt(0)相当于将字符串用字符返回
                key = sc.next().charAt(0);
                switch(key){
                case 'a':
                    System.out.println("输入一个数字");
                    int value = sc.nextInt();
                    que.add(value);
                    break;
                case 'd':
                    int d = que.delete();
                    System.out.println(d);
                    break;
                case 'h':
                    que.head();
                    break;
                case 's':
                    que.show();
                    break;
                case 'e':
                    sc.close();
                    flag = false;
                    break;
                default:
                    break;
                }
            }
            System.out.println("程序结束");
        }
    }    
    
    //创建了一个队列的类,用来执行队列的各种操作
    class ArrayQueued{
        private int front;  
        private int rear;
        private int[] arr;
        private int maxSize;
        
        //构造器,给指定的元素赋值
        public ArrayQueued(int maxSize){
            front = -1;                  //front的初始值是-1
            rear = -1;                   //rear的初始值是-1
            this.maxSize = maxSize;      //maxSize的初始值由用户输入
            arr = new int[maxSize];      //开辟maxSize大小的数组
        }
        
        //判断队列是否为空
        public boolean isEmpty(){
            return front == rear;           
        }
        
        //判断队列是否为满
        public boolean isFull(){
            return rear == maxSize - 1;
        }
        //向队列添加元素
        public void add(int n){
            try{
                if(isFull()){
                    System.out.println("队列已经满,不能添加~");
                    return;
                }
                rear++;
                arr[rear] = n;
                
            }catch(Exception ex){
                System.out.println(ex.getMessage());
            }
        }
        //删除队列的元素
        public int delete(){
            if(isEmpty()){
                System.out.println("队列为空,不能删除~");
            }
            front++;
            int value = arr[front];
            arr[front] = 0;   //这个赋值是将删除元素的值全变成0
            return value;
        }
        
        //显示队列中的元素
        public void show(){
            if(isEmpty())
                System.out.println("队列为空,没有数据!");
            for(int i=0;i<arr.length;i++){
                System.out.printf("arr[%d] = %d\t",i,arr[i]);
            }
            System.out.println();
        }
        //显示队列中的第一个元素
        public void head(){
            if(isEmpty()){
                System.out.println("队列为空!");
            }
            System.out.printf("对头元素:%d",arr[front+1]);
            System.out.println();
        }
        
    }
        

    循环队列

    刚刚看完了普通队列,它虽然方便,但是有着很大的缺点,就是浪费内存空间(随着front,rear的增加,front下面的元素没法利用了),循环队列就是在普通队列的基础上进行了优化,让整个队列变成一个环,这样所有的空间都可以利用。

    关于循环队列的表述:

    (1).当队列为空时:

    front == rear;

    (2).当队列为满时:我们约定,尾索引的下一个元素为头索引时表示队列满,即:将队列容量空出一个作为约定

    (rear+1)%maxSize == front;

    (3).整个队列中元素的个数

    (rear+maxSize-front)%maxSize

    循环队列的表示跟普通队列有点不同,具体代码如下图所示

    package queue;
    
    import java.util.Scanner;
    
    public class ArrayQueueCircle {
    
        public static void main(String[] args) {
            
            ArrayQueuec que = new ArrayQueuec(4);
            
            Scanner sc = new Scanner(System.in);
            //用于用户的输入
            char key = ' ';
            //标志变量
            boolean flag = true;
            while(flag){
            
                System.out.println("显示队列元素:s");
                System.out.println("添加队列元素:a");
                System.out.println("删除队列元素:d");
                System.out.println("显示队头元素:h");
                System.out.println("退出程序:e");
                //charAt(0)相当于将字符串用字符返回
                key = sc.next().charAt(0);
                switch(key){
                case 'a':
                    System.out.println("输入一个数字");
                    int value = sc.nextInt();
                    que.add(value);
                    break;
                case 'd':
                    int d = que.delete();
                    System.out.println(d);
                    break;
                case 'h':
                    que.head();
                    break;
                case 's':
                    que.show();
                    break;
                case 'e':
                    sc.close();
                    flag = false;
                    break;
                default:
                    break;
                }
            }
            System.out.println("程序结束");
        }
    }    
    
    
    class ArrayQueuec{
        private int front;
        private int rear;
        private int[] arr;
        private int maxSize;
        
        //构造器
        public ArrayQueuec(int maxSize){
            this.maxSize = maxSize;
            arr = new int[maxSize];
        }
        
        //判断队列是否为空
        public boolean isEmpty(){
            return front == rear;
        }
        
        //判断队列是否为满
        public boolean isFull(){
            return (rear+1)%maxSize == front;
        }
        
        //队列长度
        public int size(){
            return (rear+maxSize-front)%maxSize;
        }
        
        //向队列添加元素
        public void add(int n){
            try{
                if(isFull()){
                    System.out.println("队列已经满,不能添加~");
                    return;
                }
                
                arr[rear] = n;
                rear = (rear+1)%maxSize;
                
            }catch(Exception ex){
                System.out.println(ex.getMessage());
            }
        }
        //删除队列的元素
        public int delete(){
            if(isEmpty()){
                System.out.println("队列为空,不能删除~");
            }
            int value = arr[front];
            front = (front+1)%maxSize;
            return value;
        }
        
        //显示队列中的元素
        public void show(){
            if(isEmpty())
                System.out.println("队列为空,没有数据!");
            for(int i=front;i<front+size();i++){
                System.out.printf("arr[%d] = %d\t",i%maxSize,arr[i%maxSize]);
            }
            System.out.println();
        }
        //显示队列中的第一个元素
        public void head(){
            if(isEmpty()){
                System.out.println("队列为空!");
            }
            System.out.printf("对头元素:%d",arr[front]);
            System.out.println();
        }
        
    }
        

    主要关注一下添加,删除还有遍历的不同~~~

  • 相关阅读:
    QK对中断的特殊处理
    程序控制的软件复位方法
    软件的按契约设计(DbC---Design by Contract)
    Arduino平台基于DbC的软件调试
    软件测试中的测不准原理
    关于嵌入式软件
    程序设计的SOLID原则
    CPS---(Cyber-Physical Sytem,信息物理融合系统)
    QP之QF原理
    QP之QEP原理
  • 原文地址:https://www.cnblogs.com/liuzengzhi/p/11596234.html
Copyright © 2011-2022 走看看