数据结构与算法-学习笔记(五)

153 阅读1分钟

队列

队列就是一种先进先出的抽象的数据结构。和栈类似,队列的操做也是受限制的,最基本的两个操做:入队enqueue():把数据元素放在队尾和出队dequeue()从队列头部取出一个元素。

队列的实现

顺序队列:数组实现

涉及到数据搬移,时间复杂度较高

链式队列:链表实现

没有重复利用空间,空间复杂度较高 入队时注意空队列的情况;出队时注意最后一个元素。

循环队列

如何解决上述的时间复杂度和空间复杂度较高的问题呢?

class CircleQueue {
    constructor(size) {
        this.size = size;
        this.queue = Array(size);
        this.headIndex = 0;//数组:头尾表示的是Index;链表:就是指向结点的指针了
        this.tailIndex = 0;
        this.isFull = false;
    }

    revertIndex(index) {
        return index%this.size;
    }

    enQueue(data) {
        if(this.isFull)return -1; 
        this.queue[this.tailIndex] = data;
        this.tailIndex++;
        if(this.tailIndex>=this.size) this.tailIndex = this.revertIndex(this.tailIndex);
        this.isFull =  this.revertIndex(this.tailIndex)==this.revertIndex(this.headIndex)
        return 0;
    }
    
    deQueue(){
        if(!this.isFull&&this.tailIndex==this.headIndex)return null;
        var element = this.queue[this.headIndex];
        this.headIndex++;
        if(this.headIndex>=this.size) this.headIndex = this.revertIndex(this.headIndex);

        this.isFull = false;
        
        return element;
        
    }

}

出入队列操作的时间复杂度和空间复杂度都是O(1)。

阻塞队列和并发队列

在队列的基础操作上加了阻塞操作。取数据时,如果队列为空则被阻塞,等待直到有数据可取才返回。插入数据时,如果队列已满则被阻塞,等待直到有空闲位置则插入返回。

显见👆的描述就是一个“生产者-消费者模型”。因此可以使用阻塞队列实现消费者生产者模型。

并发队列

实际上,对于大部分资源有限的场景(如线程池),当没有空闲资源时,基本上都可以通过“队列”这种数据结构来实现请求排队。