算法:java使用数组实现单向非循环队列与单向循环队列

队列是一个有序列表,可以由数组或者链表实现
数据先入先出

⭐⭐:写程序之前一定要先把需求写在纸上,然后在下笔

单向队列

public class singlequeue {
    private int maxSize ;
    private int head = 0; // 指向下一个弹出的元素索引
    private int tail = 0; // 指向下一个要存放数据的索引
    private int[] arr ;  // 模拟队列

    public singlequeue(int size){
        if (size < 1){
            throw new RuntimeException("size must > 0");
        }


        maxSize = size;
        arr = new int[size];
    }

    public boolean empty(){
        return head == tail;   // 下一个要弹出的索引 == 下一个存放数据的索引
    }

    // 最大 tail = maxSize - 1;
    public boolean full(){
        return tail == maxSize;  // 下一个要存放数据的索引 【超过了可以存放的范围】
    }

    // 当前队列最大容量
    public int cap(){
        return maxSize;
    }

    // 还可以存放多少个元素
    public int size(){
        return maxSize - tail;  
    }

    // 入队: 先要判断有没有位置存放, 然后tail就是可以存放的位置
    public void push(int ele){
        if (full()){
            throw new RuntimeException("当前队列已经满了");
        }

        arr[tail++] = ele;  // 存放位置,然后tail++
    }



    // head和tail之间一定要有元素才能出队
    public void pop(){
        if (empty() || head > maxSize - 1){
            throw new RuntimeException("空队列, 不能取元素");
        }

        arr[head++] = 0;
    }


    public void printQueue(){
        if (empty()){
            throw new RuntimeException("空队列, 不能取元素");
        }

        for (int i = head; i < tail; i++){  // tail为下一个元素的放置位置,当前还没有元素
            System.out.printf("%d\t", arr[i]);
        }
        System.out.println();
    }
}

import java.util.Scanner;

public class arrayqueue {
    public static void main(String[] args) {
        singlequeue q = new singlequeue(5);
        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("d(delete):出队一个元素");
            key = scanner.next().charAt(0);

            switch (key){
                case 's':
                    q.printQueue();
                    System.out.println(q.size());;
                    break;
                case 'e':
                    loop = false;
                    break;
                case 'a':
                    int t = scanner.nextInt();
                    q.push(t);
                    break;
                case 'd':
                    q.pop();
                    break;
            }
        }
    }


}

问题分析:目前数组使用依次就不能用,没有达到复用的效果
优化:循环队列

循环队列

public class circlequeue {
    private int head = 0; // 尾索引: 指向下一个要取出的位置索引
    private int tail = 0; // 头索引: 指向下一个要放的位置索引
    private int count = 0; // 当前队列元素个数
    private int maxsize = 0; //队列多大
    private int [] arr;

    public circlequeue(int cap){
        maxsize = cap;
        arr = new int[cap];
    }

    public void printQueue(){
        int t = head;
        for (int i = 0; i < count; i++){
            t = head + i;  // 指向下一个要取出的位置索引
            if (t == maxsize){
                t = 0;
            }
            System.out.printf("%d\t", arr[t]);
        }
        System.out.println();
    }

    // 还有多少个位置
    public int  size(){
        return maxsize - count;
    }

    //也就是取出来的位置和放置位置相同,但是放置位置还米有元素,说明当前队列为空
    public boolean empty(){
        return count == 0;
    }

    // 存放元素个数 = 数组长度,满了
    // ( head + 1 ) % maxSize
    public boolean full(){
        return count == maxsize;
    }

    public  void push(int ele){
        if (full()){
            throw new RuntimeException("当前队列已满");
        }

        // 本次
        arr[tail] = ele;
        count++;

        // tail为下一次放置位置, 如果超出了索引,重新开始
 /*       tail++;
        if (tail == maxsize){
            tail = 0;
        }*/
        tail = (tail + 1) % maxsize;
    }

    public void  pop(){
        if (empty()){
            throw new RuntimeException("队列为空");
        }

        arr[head] = 0;
        count--;

/*
        head++;
        if (head == maxsize){
            head = 0;
        }
*/

        head = (head + 1) % maxsize;
    }


}

import java.util.Scanner;

public class arrayqueue {
    public static void main(String[] args) {
        circlequeue q = new circlequeue(5);
        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("d(delete):出队一个元素");
            key = scanner.next().charAt(0);

            switch (key){
                case 's':
                    q.printQueue();
                    System.out.println(q.size());;
                    break;
                case 'e':
                    loop = false;
                    break;
                case 'a':
                    int t = scanner.nextInt();
                    q.push(t);
                    break;
                case 'd':
                    q.pop();
                    break;
            }
        }
    }


}



https://www.cs.usfca.edu/~galles/visualization/QueueArray.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值