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();
        }
        
    }
        

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

  • 相关阅读:
    7.21 高博教育 数组 内存
    【基础扎实】Python操作Excel三模块
    PAT 甲级 1012 The Best Rank
    PAT 甲级 1011  World Cup Betting
    PAT 甲级 1010 Radix
    链式线性表——实验及提升训练
    循环程序设计能力自测
    链表应用能力自测
    PAT 甲级 1009 Product of Polynomials
    1008 Elevator (20分)
  • 原文地址:https://www.cnblogs.com/liuzengzhi/p/11596234.html
Copyright © 2011-2022 走看看