数据结构之队列

一、 基本概念

队列(queue)是只允许在一端进行插入操作,而在另一端进行删除操作的线性表。

队列是一种先进先出(First in First Out)的线性表,简称FIFO。允许插入的一端称为队尾,允许删除的一端称为队头。

假设队列是q=(a1,a2,…,an),那么a1就是队头元素,而an是队尾元素。这样我们就可以删除时,总是从a1开始,而插入时,列在最后。这也比较符合我们通常生活中的习惯,排在第一个的优先出列,最后来的当然在队伍的最后。
在这里插入图片描述

二、存储结构及自定义实现基本操作

队列既然是一种线性表,所以线性表的顺序存储和链接存储结构同样适用于队列。

1、顺序存储——数组实现
入队时,通过tail的位置判断队列是否已满。如果没有满,则将tail后移一位,将新元素放置在tail所在位置。出队时,也可以通过tail的位置判断队列是否为空。如果不空,则只需将head后移一位即可。 获取队头元素,判断队列不空,则只需返回head指向位置的元素即可。

但是!!想一下,通过出队操作将数据弹出队列后,head之前的空间还能够再次得到吗?不能。所以使用普通数组实现队列,就再也不能使用head之前的空间了,这会导致大量空间丢失。

所以,在这里我们使用环形队列!!
环形队列为空的时候,此时 head和tail是重合的。
环形队列为满的时候,此时head和tail 也是重合的。

如何解决这个问题?
环形队列如何区分空和满呢??方案:有两个。
1、不要把这个环形队列压榨的那么干净,故意浪费一个空间。即用head和 tail重合表示空队列,使用tail == head - 1表示满队列。
2、不浪费空间,然后专门搞一个size变量记录队列的元素个数.。size == 0就是空, size ==数组长度就是满。

package homework.stackAndqueue;

public class MyQueue {
    private int[] data;
    private int capacity = 100;
    private int head = 0;
    private int tail = 0;
    private int size = 0;

    public MyQueue(){
        data = new int[capacity];
    }

    //入队列
    private void realloc(){
        capacity = capacity + 100;
        int[] newData = new int[capacity];
        int[] data = new int[0];
        for(int i = 0; i < data.length; i++){
            newData[i] = data[i];
        }
    }
    public boolean offer(int val) {
        if (size == data.length) {
            realloc();
            return false;
        }
        data[tail] = val;
        tail++;
        if (tail == data.length) {
            tail = 0;
        }
        size++;
        return true;
    }

    // 出队列
    public Integer poll() {
        if (size == 0) {
            return null;
        }
        int ret = data[head];
        head++;
        if (head == data.length) {
            head = 0;
        }
        size--;
        return ret;
    }

    // 取队首元素
    public Integer peek() {
        if (size == 0) {
            return null;
        }
        return data[head];
    }
}

2、链接存储:使用尾插表示入队列,使用头删表示出队列,直接获取到头结点就是取队首元素。

package homework.stackAndqueue;

public class MyQueueWithNode {
    class Node{
        int val;
        Node next;

        public Node(int val){
            this.val = val;
        }
    }

    private Node head = null;
    private Node tail = null;

    //入队列
    public boolean offer(int val){
        Node newNode = new Node(val);
        if(head == null){
            head = newNode;
            tail = newNode;
            return true;
        }
        tail.next = newNode;
        tail = tail.next;
        return  true;
    }

    //出队列
    public Integer poll(){
        if(head == null){
            return  null;
        }
        int ret = head.val;
        if(head.next == null){
            head = null;
            return ret;
        }
        head = head.next;
        return ret;
    }

    //取队首元素
    public Integer peek(){
        if(head == null){
            return null;
        }
        return head.val;
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值