美文网首页
数据结构与算法 (队列实现篇)

数据结构与算法 (队列实现篇)

作者: Evtion | 来源:发表于2019-05-16 23:10 被阅读0次

数据结构与算法 (队列实现篇)

在数据结构与算法中,队列(queue)是一种受限的线性储存结构,特殊之处在于它只允许在表的前端(front)进行删除操作,而在表的后端(rear)进行插入操作,和栈一样,队列是一种操作受限制的线性表。进行插入操作的端称为队尾,进行删除操作的端称为队头。遵循先进先出(FIFO)的规则。

队列结构示意图
queue.png
队列结构使用

生活中很多地方使用到队列,例如医院门诊看病就是按挂号的号数来排队就诊;公司里面的打印机是按文件发送的顺序进行打印。

3.jpg

在编程中,队列常用作消息发送。例如消息发送队列。待发送的消息依次入队列,待一个消息出队列发送完毕,才会进行下一个消息出队列进行发送。

实现普通队列结构的功能
  • push(element):push是入队列操作,其中element是需要进队列的元素,返回操作成功与否布尔值。
  • shift():shift移除队列front元素操作,返回移除的移除元素。
  • size():获取栈中的队列元素数量,返回一个数字。
  • isEmpty():判断队列是否为空,返回一个布尔值。
  • peek():返回队头元素,但不移除栈顶元素。
  • bottom():返回队尾元素。
  • clear():清除所有队列元素,返回操作成功与否布尔值。
进队列与出队列流程
flow.png
ES6 队列结构代码
class Queue{
    constructor(){
        this.lists = [];
    }
    size(){
        return this.lists.length;
    }
    isEmpty(){
        return this.lists.length === 0;
    }
    peek(){
        return this.list[0];
    }
    bottom(){
        const topIndex = this.size() -1;
        return this.lists[topIndex];
    }
    push(element){
        this.lists.push(element);
        return true;
    }
    shift(){
        return this.lists.shift();
    }
    clear(){
        this.lists = [];
        return true;
    }
    toString(){
        let result = "";
        this.lists.forEach(value=>{
            result = result + ""+value;
        });
        return result;
    }
}
ES5 队列结构代码

通过ES5把功能函数可以绑定在对象的实例上,也可以把功能函数加在函数的原型链上

function Queue(){
    this.lists = [];
}
Queue.prototype.push = function(element){
    this.lists.push(element);
    return true;
}
Queue.prototype.shift = function(){
    return this.lists.shift();
}
Queue.prototype.clear = function(){
    this.lists = [];
    return true;
}
// 返回队头元素
Queue.prototype.peek = function(){
    return this.lists[0];
}
Queue.prototype.size = function(){
    return this.lists.length;
}
Queue.prototype.isEmpty = function(){
    return this.lists.length === 0;
}
Queue.prototype.bottom = function(){
    var topIndex = this.size() -1;
    return this.lists[topIndex];
}
Queue.prototype.toString = function(){
    var result = "";
    for(var i=0;i<this.lists.length;i++){
        result = result + '' +this.lists[i];
    }
    return result;
}
实现优先队列结构的功能

上面实现的是普通队列情况,在日常生活中总遇到需要紧急处理的情况,例如银行VIP客户,急诊室危急病人,紧急文件。这时候需要优先处理这种情况。

优先队列和普通队列的不同主要在优先队列的每一个元素都具有一个权值,代表该元素的优先权大小。还有就是根据权值大小插入队列之中。

prority.png
ES6 最大优先队列结构代码
class Node{
    constructor(element,prority){
        this.element = element;
        this.prority = prority;
    }
}
class Queue{
    constructor(){
        this.lists = [];
    }
    size(){
        return this.lists.length;
    }
    isEmpty(){
        return this.lists.length === 0;
    }
    peek(){
        return this.list[0];
    }
    bottom(){
        const topIndex = this.size() -1;
        return this.lists[topIndex];
    }
    //插入队列
    append(node){
        //当队列为空时
        if(this.lists.length == 0){
            this.lists.push(node);
            return true;
        }else{
            this.lists.forEach((val,index)=>{
                          if(node.prority > val["prority"]){
                              this.lists.splice(index,0,node);
                            return true;
                          }
                          if(index == this.lists.length){
                              this.lists.push(node);
                              return true;
                          }
                      });
        }
    }
    shift(){
        return this.lists.shift();
    }
    clear(){
        this.lists = [];
        return true;
    }
    toString(){
        let result = "";
        this.lists.forEach(value=>{
            result = result + ""+value;
        });
        return result;
    }
}
ES5 最大优先队列结构代码

通过ES5把功能函数可以绑定在对象的实例上,也可以把功能函数加在函数的原型链上

function Node(element,prority){
    this.element = element;
    this.prority = prority;
}
function Queue(){
    this.lists = [];
}
Queue.prototype.append = function(node){
    //当队列为空时
    if(this.lists.length == 0){
        this.lists.push(node);
        return true;
    }
    
    for(var i=0;i<this.lists.length;i++){
        if(node.prority > this.lists[i]["prority"]){
          this.lists.splice(i,0,node);
          return true;
        }
        if(i == this.lists.length){
            this.lists.push(node);
            return true;
        }
    }
    
}
Queue.prototype.shift = function(){
    return this.lists.shift();
}
Queue.prototype.clear = function(){
    this.lists = [];
    return true;
}
// 返回队头元素
Queue.prototype.peek = function(){
    return this.lists[0];
}
Queue.prototype.size = function(){
    return this.lists.length;
}
Queue.prototype.isEmpty = function(){
    return this.lists.length === 0;
}
Queue.prototype.bottom = function(){
    var topIndex = this.size() -1;
    return this.lists[topIndex];
}
Queue.prototype.toString = function(){
    var result = "";
    for(var i=0;i<this.lists.length;i++){
        result = result + '' +this.lists[i];
    }
    return result;
}
循环队列结构图

循环队列就是把队头元素出队列后,再入队列。击鼓传花就是用到了循环队列的原理

image.png image.png
循环队列代码

循环队列主要实现代码如下

 class SqQueue {
    constructor(length) {
        this.queue = new Array(length + 1)
        // 队头
        this.first = 0
        // 队尾
        this.last = 0
        // 当前队列大小
        this.size = 0
    }
    enQueue(item) {
        // 判断队尾 + 1 是否为队头
        // 如果是就代表需要扩容数组
        // % this.queue.length 是为了防止数组越界
        if (this.first === (this.last + 1) % this.queue.length) {
            this.resize(this.getLength() * 2 + 1)
        }
        this.queue[this.last] = item
        this.size++
        this.last = (this.last + 1) % this.queue.length
    }
    deQueue() {
        if (this.isEmpty()) {
            throw Error('Queue is empty')
        }
        let r = this.queue[this.first]
        this.queue[this.first] = null
        this.first = (this.first + 1) % this.queue.length
        this.size--
        // 判断当前队列大小是否过小
        // 为了保证不浪费空间,在队列空间等于总长度四分之一时
        // 且不为 2 时缩小总长度为当前的一半
        if (this.size === this.getLength() / 4 && this.getLength() / 2 !== 0) {
            this.resize(this.getLength() / 2)
        }
        return r
    }
    getHeader() {
        if (this.isEmpty()) {
            throw Error('Queue is empty')
        }
        return this.queue[this.first]
    }
    getLength() {
        return this.queue.length - 1
    }
    isEmpty() {
        return this.first === this.last
    }
    resize(length) {
        let q = new Array(length)
        for (let i = 0; i < length; i++) {
            q[i] = this.queue[(i + this.first) % this.queue.length]
        }
        this.queue = q
        this.first = 0
        this.last = this.size
    }
}

完成数据结构与算法队列篇。

相关文章

  • 数据结构与算法 (队列实现篇)

    数据结构与算法 (队列实现篇) 在数据结构与算法中,队列(queue)是一种受限的线性储存结构,特殊之处在于它只允...

  • 【数据结构与算法 - Swift实现】10 - 优先队列 (Pr

    在【数据结构与算法 - Swift实现】04 - 队列 (Queue)文章里面,我们已经讲过队列,采用先进先出的规...

  • 链式队列的定义,ios基础知识篇!

    数据结构与算法-链式队列 链式队列的定义 链式队列是用链表来实现的队列,不存在队满的情况。链式队列也包里队列的特点...

  • 剑指Offer--(6)用两个栈实现队列

    title: 剑指Offer--(6)用两个栈实现队列 categories: 算法与数据结构 tags: 数据结...

  • 数据结构与算法-目录

    数据结构与算法-目录 C语言篇 数据结构和算法-C语言篇1-绪论数据结构和算法-C语言篇2-初识算法数据结构与算法...

  • 排序算法

    什么是算法 书籍推荐 《数据结构与算法分析》 表、栈和队列 树 散列(hash) 优先队列(堆) 排序 定义 问题...

  • 数据结构与算法 (栈实现篇)

    数据结构与算法 (栈实现篇) 在数据结构与算法中,栈(stack)又名堆栈,栈是一种受限的线性储存结构,只允许在一...

  • Java实现队列

    队列是一种先进先出的数据结构,和栈刚好相反,队列在算法中也应用广泛。本文,我们主要探讨Java实现队列。 队列 队...

  • Hash算法

    数据结构与算法分析:大纲数据结构:数组算法:hash算法算法:排序算法Java实现 1 Hash算法? 将任意长度...

  • 集合相关数据结构与算法

    队列 栈数据结构 比较算法 Collections Collection与Collections的区别?Colle...

网友评论

      本文标题:数据结构与算法 (队列实现篇)

      本文链接:https://www.haomeiwen.com/subject/ctkgaqtx.html