数据结构与算法Java——队列

队列

1.数组模拟一次性队列

代码实现

package 队列;

/*
* 数组模拟一次性队列
*
* 这里在使用数组实现该队列时思维比较简单,但也同样使得该队列有些相当于 “一次性队列” ,即如果用很多次的话,可能就因为rear移动到
* 尾部,导致不能使用了;
*
* 这里使用双指针思想来使用数组实现队列,这样的好处是实现起来简单,但是队列内存不能复用,因为原先队列内元素占据的内存直接随着指针
* 的移动所舍弃了,即在删除元素时没有真正的删除;
* */
public class ArrayQueue {
    private int[] res;
    private int maxSize;  //队列的最大总使用容量
    private int rear;   //指向队列尾部的元素的下标,尾指针
    private int front;  //指向队列头部的元素的前一个下标 ,前指针

    public ArrayQueue(int maxSize){
        this.maxSize = maxSize;
        res = new int[maxSize];
        rear = -1;
        front = -1;
    }

    public boolean isFull(){
        return rear == maxSize - 1;
    }

    public boolean isEmpty(){
        return rear == front;
    }

    //从尾部加元素
    public void addQueue(int num){
        if(isFull()){
            System.out.println("当前队列已经满了~~~~~");
            return;
        }
        rear++; //尾指针移动
        res[rear] = num;
    }

    //从头部拿出元素
    public int getQueue(){
        if(isEmpty()){
            throw new RuntimeException("当前队列为空!");
        }
        front++;  //头指针移动
        return res[front];
    }

    //打印队列内的所有元素
    public void showQueue(){
        if(isEmpty()){
            System.out.println("当前队列为空!");
            return;
        }
        for(int i=front+1 ; i <= rear; i++){
            System.out.println(res[i]+" ");
        }
    }

    //查看头部元素
    public int headQueue(){
        if(isEmpty()){
            throw new RuntimeException("当前队列为空!");
        }
        return res[front+1];
    }
}

2.数组模拟环形队列

代码实现

package 队列;

/*
 * 数组模拟环形队列
 * 就是因为一次性队列浪费了太多空间,不能起到空间复用!
 * 要想起到空间复用,就需要在头尾指针移动到maxSize时返回数组头部,即起到一种环形的思想!
 * 而要实现这种环形思想,就需要使用 % 运算符来实现,即一旦头尾指针超过maxSize,便使其对maxSize取余数,
 * 这样我们发现刚好可以使其返回头部!!!
 * */
public class CircleQueue {
    private int[] res;
    private int maxSize;  //队列的最大总使用容量,但是要注意的是由于我们最后一位空出来了,所以真正队列大小为maxSize-1
    //如果不空出一位的话,isFull方法会错误的!
    private int rear;
    // rear 指向队列的最后一个元素的后一个位置. 因为希望空出一个空间做为约定,尾指针
    private int front;
    // front 就指向队列的第一个元素, 也就是说 arr[front] 就是队列的第一个元素,头指针

    //需要注意的是front和rear都是以下标的形式!!!!所以是不能等于maxSize的

    public CircleQueue(int maxSize){
        this.maxSize = maxSize;
        res = new int[maxSize];
        rear = 0;
        front = 0;
    }

    //当没满时,我们发现取余相当于没作用,所以二者必定不可能相等,因此此时二者没任何关系!
    //当满了后,我们发现,此时头尾直接存在关系,即尾部+1刚好是头部的maxSize倍!!!
    // 比如maxSize为10,那么此时头部为0,尾部为9,所以(9+1) % 10 == 0 ,移动一格后,为头 1 尾 0 ,所以 (0+1)% 10 == 1
    public boolean isFull(){
        return (rear+1) % maxSize == front;
    }

    //空时还是头尾相等,因为front是指向队列的第一个元素,rear是指向队列的最后一个的后一个,
    // 你可能会想为什么不是rear == front-1 ,是因为如果只是第一个元素等下标等于最后一个元素下标只是能说明此时只有一个元素
    //所以为空则代表,此时的头部和尾部的下一个在同一位置
    public boolean isEmpty(){
        return rear == front;
    }

    //从尾部加元素
    public void addQueue(int num){
        if(isFull()){
            System.out.println("当前队列已经满了~~~~~");
            return;
        }
        res[rear] = num;
        rear = (rear+1) % maxSize;  //防止越界,一旦越界便根据环形返回头部
    }

    //从头部拿出元素
    public int getQueue(){
        if(isEmpty()){
            throw new RuntimeException("当前队列为空!");
        }
        int temp = res[front];
        front = (front+1) % maxSize;   //防止越界,一旦越界便根据环形返回头部
        return temp;
    }

    //打印队列内的所有元素
    public void showQueue(){
        if(isEmpty()){
            System.out.println("当前队列为空!");
            return;
        }
        for(int i=front ; i < front+size(); i++){   // 从头指针开始,按个数枚举
            System.out.printf("res[%d] = %d" ,i % maxSize,res[i%maxSize] );    //防止越界,一旦越界便根据环形返回头部
        }
    }

    //查看队列的真正长度
    public int size(){
        return (rear+maxSize-front) % maxSize;   //理解为 rear在前,front在后时的情况
    }

    //查看头部元素
    public int headQueue(){
        if(isEmpty()){
            throw new RuntimeException("当前队列为空!");
        }
        //头部直接对准
        return res[front];
    }
}

class Test{
    public static void main(String[] args) {
        CircleQueue circleQueue = new CircleQueue(4);
        //队列的最大总使用容量,但是要注意的是由于我们最后一位空出来了,所以真正队列大小为3
        //所以此时创建的是一个最大长度为3的队列
        circleQueue.addQueue(1);
        circleQueue.addQueue(2);
        System.out.println(circleQueue.isFull());
    }
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
数据结构算法Java中是密切相关的。数据结构是一门研究组织数据方式的学科,而算法则是处理数据的方法。在Java中,学习好数据结构可以帮助我们编写更漂亮、更高效的代码。数据结构算法的基础,想要学好算法就需要将数据结构学到位。\[1\] 在Java中,我们可以使用各种数据结构算法来解决问题。常见的数据结构包括数组、链表、栈、队列、树、图等。而算法则是对这些数据结构进行操作和处理的方法。通过选择合适的数据结构算法,我们可以提高程序的效率和性能。 在Java中,我们可以使用Java集合框架中提供的数据结构,如ArrayList、LinkedList、HashMap等。这些数据结构已经被封装好,我们可以直接使用它们来解决问题。同时,我们也可以根据具体的需求,自己实现一些特定的数据结构算法。 如果想深入了解Java中的数据结构算法,可以参考一些相关的资料和链接。比如,可以了解Java中的哈希算法及HashMap的底层实现原理,以及常用的数据结构集合框架对比总结。\[2\] \[3\] 总之,数据结构算法Java中是相互依赖的。学习好数据结构可以帮助我们更好地理解和应用算法,而学习好算法则可以提高我们解决问题的效率和质量。 #### 引用[.reference_title] - *1* [数据结构与算法Java版】:第一课](https://blog.csdn.net/sum_12/article/details/115621379)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* [Java——数据结构与算法](https://blog.csdn.net/m0_64359609/article/details/124174183)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] - *3* [数据结构与算法——Java版](https://blog.csdn.net/su2231595742/article/details/120618818)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

向光.

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值