队列

先进先出

队列是一种特殊的线性表,特殊之处在于它只允许在表的前端进行删除操作,而在表的后端进行插入操作,和栈一样,队列是一种操作受限制的线性表。进行插入操作的端称为队尾,进行删除操作的端称为队头。

就像吃饭排队,先站在队伍里的人先拿到饭:smile:

SRE实战 互联网时代守护先锋,助力企业售后服务体系运筹帷幄!一键直达领取阿里云限量特价优惠。

API

public class LinkedQueueOfString//储存字符串的队列
	LinkedQueueOfString()//创建队列
void enqueue(String item)//入队
String dequeue()//出队列
boolean isEmpty()//判断队列是否为空

示例

  • 空队列什么也没有
  • push('a')
graph BT 1(a,队头,队尾)
  • push('b')
graph TD 2(a,队头)==>1(b,队尾)
  • push('c')
graph TD 2(b)==>1(c,队尾) 3(a,队头)==>2
  • pop()
graph TD 2(b,队头)==>1(c,队尾)

链表栈

令链表整体方向由队头指向队尾,保存指向队头和队尾元素的引用,可以提高队列出队入队的效率

Code by java

public class LinkedQueueOfString {
    private class Node{//内部类
        String item;
        Node next;//指向下一个结点的引用
    }
    private Node first,last;//指向队头队尾元素的引用
    public boolean isEmpty(){//指向队头元素的引用为空即队列为空
        return first==null;
    }
    public void enqueue(String item){//入队
        Node copy=last;//拷贝指向当前队尾元素的引用
        last=new Node();//令last重新指向一个新的节点
        last.item=item;//对新节点赋值
        last.next=null;//新节点的next指向空
        if(isEmpty())//如果是队列为空
            first=last;//使得队头队尾指向同一个元素
        else//不然使得旧的队尾元素的next指向新元素
            copy.next=last;
    }
    public String dequeue(){
        String item=first.item;//拷贝当前队头元素的字符串
        first=first.next;//让队头指向下一个节点
        if(isEmpty())//如果队列为空,使得last指向null
            last=null;
        return item;//返回旧的队头元素的字符串
    }
}

数组队列

数组队列使用一个数组当作队列,好处是节省了空间,缺点是长度固定,有多余空间,而且有下标越界的风险,

q[] 0 1 2 3 4
null a b c null
队头 队尾

队尾总是指向最后一个元素的后一个元素

  • enqueue("d")
q[] 0 1 2 3 4
null a b c d
队尾 队头
  • size=(队尾-队头+数组长度)%数组长度=(0-1+5)%5=4
  • dequeue()
q[] 0 1 2 3 4
null null b c d
队尾 队头
  • 可以看出该数组队列可容纳最大元素个数等于数组长度减一
public class FixedCapacityQueueOfString {
    private String[] s;
    private int first=0;//队头
    private int last=0;//队尾

    public FixedCapacityQueueOfString(int capacity) {
        s=new String[capacity];//根据capacity分配空间
    }
    public boolean isEmpty(){//如果队头队尾指向同一个元素说明队列为空
        return first==last;
    }
    public int size(){//循环利用空间
        return (last+s.length-first)%s.length;
    }
    public void enqueue(String item){
        s[last]=item;
        last=(last+1)%s.length;//循环利用空间
    }
    public String dequeue(){
        String copy=s[first];
        s[first]=null;//使得垃圾回收器可以回收一部分空间
        first=(first+1)%s.length;
        return copy;
    }
}

优化-动态数组大小

  • 在入队列时,当队列已满时将数组长度翻倍
  • 在出队列时,当队列元素不足一半数组长度时将数组长度减半
扫码关注我们
微信号:SRE实战
拒绝背锅 运筹帷幄