第五章 队列与双端队列

自我测试

本篇文章的测试用例及调试方法见前言

说明

队列是遵循先进先出(FIFO,也称为先来先服务)原则的一组有序的项.队列在尾部添加新元素,并从顶部移除元素.最新添加的元素必须排在队列的末尾.

使用

当我们在浏览器打开新标签时,就会创建一个任务队列.这是因为每个标签都是一个单线程处理所有任务,称为事件循环.浏览器要赋值多个任务,如渲染HTML,执行JavaScript代码,处理用户交互(用户输入,鼠标点击等),执行和处理异步请求.
更多事件循环

队列

简单图解

队列和栈不同,就像排队买票,先排上队的先开始买票,所以是一个先进先出(FIFO)的数据结构

一个队列的基本方法

  • enqueue(element(s)) : 向队列尾部添加一个(或多个)新的项
  • dequeue() :移除队列的第一项(即排在队列最前面的项)并返回被移除的元素
  • peek() : 返回队列中的第一个元素---最先被添加上,也将最先被移除的元素.队列不做任何变动(不移除元素,只返回信息),该方法在其他语言中也可以叫作front
  • isEmpty() : 如果队列中不包含任何元素,返回true,否则返回false
  • clear() : 清除所有元素
  • size() : 返回队列包含的元素个数, 与数组的length属性类似
export default class Queue<T> {
    // 队列数据集
    private queueList: any;
    // 队列的个数
    private beforeIndex: number;
    // 队列当前最后一个的位置
    private lastIndex: number;

    constructor() {
        this.queueList = {};
        this.lastIndex = 1;
        this.beforeIndex = 1;
    }

    //插入
    enqueue(...items: Array<T>): void {
        let newIndex = this.lastIndex;
        for (let i = 0, len = items.length; i < len; i++) {
            this.queueList[newIndex++] = items[i];
        }
        this.lastIndex = newIndex;
    }

    //移除
    dequeue(): (T | undefined) {
        if (this.isEmpty()) {
            return undefined;
        }
        let result = this.queueList[this.beforeIndex];
        delete this.queueList[this.beforeIndex];
        this.beforeIndex++;
        return result;
    }

    //队列最前一个数
    peek(): (T | undefined) {
        return this.queueList[this.beforeIndex];
    }

    //队列中是否有数据
    isEmpty(): boolean {
        return this.size() === 0;
    }

    //队列里的数据个数
    size(): number {
        return this.lastIndex - this.beforeIndex;
    }

    //清理数据
    clear(): void {
        this.beforeIndex = 0;
        this.lastIndex = 0;
        this.queueList = {};
    }
}

双端队列

简单图解

双端队列与队列的不同点在于,队列是先进先出,所以是一端出口,一端进口,而双端队列,就是两边都可以进也都可以出. 这就像你和你女朋友去外面玩,看到一个烤串店排了老长的队,但是又不知道有什么好吃的,所以你女朋友叫你去后面排队(后端插入数据),她去前面看看菜品(前端插入数据),然后你女票去前面看了,发现很多好吃的,但是这个时候她不太想吃这些!所以她又退了回来(移除前端数据),然后告诉你,我们以后再来吃吧!你们就一起走了(你退出队列,尾部移除)

一个双端队列的基本方法

  • addFront(element(s)) : 在双端队列前端添加新的元素
  • addBack() :该方法在双端队列后端添加新的元素
  • removeFront() : 该方法会从双端队列前端移除第一个元素
  • removeBack() : 该方法会从双端队列后端移除第一个元素
  • peekFront() : 该方法会返回双端队列前端第一个元素
  • peekBack() : 该方法会返回双端队列后端第一个元素
export default class Deque<T> {
    //数据源
    private dequeList: any;
    //起始位置
    private startIndex: number;
    //结束指针的后一个
    private endIndex: number;

    constructor() {
        this.dequeList = {};
        this.startIndex = 0;
        this.endIndex = 0;
    }

    // 前面添加的时候,startIndex位置有元素
    addFront(...elements: Array<T>): void {
        //没有元素的情况下,我会将这个添加交给后置添加
        if (this.isEmpty()) {
            this.addBack(...elements);
            return;
        }
        let index = this.startIndex;
        for (let i = elements.length - 1; i >= 0; i--) {
            // 因为startIndex有元素,所以先减后赋值
            this.dequeList[--index] = elements[i];
        }
        this.startIndex = index;
    }

    // 后面添加的时候,endIndex位置没有元素
    addBack(...elements: Array<T>): void {
        let index = this.endIndex;
        elements.forEach(item => {
            //因为规定endIndex位置没有元素,所以先赋值再++
            this.dequeList[index++] = item;
        })
        this.endIndex = index;
    }

    // 前面移除一个元素
    removeFront(): (T | undefined) {
        if (this.isEmpty()) {
            return undefined;
        }
        let result = this.dequeList[this.startIndex];
        delete this.dequeList[this.startIndex];
        this.startIndex++;
        return result;
    }

    //后面移除一个元素
    removeBack(): (T | undefined) {
        if (this.isEmpty()) {
            return undefined;
        }
        //endIndex这个时候是没有值的
        this.endIndex--;
        let result = this.dequeList[this.endIndex];
        delete this.dequeList[this.endIndex];
        return result;
    }

    peekFront(): T {
        return this.dequeList[this.startIndex];
    }

    peekBack(): T {
        return this.dequeList[this.endIndex - 1];
    }

    isEmpty() {
        return this.size() === 0;
    }

    size() {
        return this.endIndex - this.startIndex;
    }

    clear() {
        this.dequeList = {};
        this.startIndex = 0;
        this.endIndex = 0;
    }

    toString() {
        if (this.isEmpty()) {
            return '';
        }
        let objString = `${this.dequeList[this.startIndex]}`;
        for (let i = this.startIndex + 1; i < this.endIndex - 1; i++) {
            objString = `${objString},${this.dequeList[i]}`;
        }
        return objString;
    }
}

书中代码

队列

export default class Queue<T> {
  private count: number;
  private lowestCount: number;
  private items: any;

  constructor() {
    this.count = 0;
    this.lowestCount = 0;
    this.items = {};
  }

  enqueue(element: T) {
    this.items[this.count] = element;
    this.count++;
  }

  dequeue() {
    if (this.isEmpty()) {
      return undefined;
    }
    const result = this.items[this.lowestCount];
    delete this.items[this.lowestCount];
    this.lowestCount++;
    return result;
  }

  peek() {
    if (this.isEmpty()) {
      return undefined;
    }
    return this.items[this.lowestCount];
  }

  isEmpty() {
    return this.size() === 0;
  }

  clear() {
    this.items = {};
    this.count = 0;
    this.lowestCount = 0;
  }

  size() {
    return this.count - this.lowestCount;
  }

  toString() {
    if (this.isEmpty()) {
      return '';
    }
    let objString = `${this.items[this.lowestCount]}`;
    for (let i = this.lowestCount + 1; i < this.count; i++) {
      objString = `${objString},${this.items[i]}`;
    }
    return objString;
  }
}

双端队列

export default class Deque<T> {
  private count: number;
  private lowestCount: number;
  private items: any;

  constructor() {
    this.count = 0;
    this.lowestCount = 0;
    this.items = {};
  }

  addFront(element: T) {
    if (this.isEmpty()) {
      this.addBack(element);
    } else if (this.lowestCount > 0) {
      this.lowestCount--;
      this.items[this.lowestCount] = element;
    } else {
      for (let i = this.count; i > 0; i--) {
        this.items[i] = this.items[i - 1];
      }
      this.count++;
      this.items[0] = element;
    }
  }

  addBack(element: T) {
    this.items[this.count] = element;
    this.count++;
  }

  removeFront() {
    if (this.isEmpty()) {
      return undefined;
    }
    const result = this.items[this.lowestCount];
    delete this.items[this.lowestCount];
    this.lowestCount++;
    return result;
  }

  removeBack() {
    if (this.isEmpty()) {
      return undefined;
    }
    this.count--;
    const result = this.items[this.count];
    delete this.items[this.count];
    return result;
  }

  peekFront() {
    if (this.isEmpty()) {
      return undefined;
    }
    return this.items[this.lowestCount];
  }

  peekBack() {
    if (this.isEmpty()) {
      return undefined;
    }
    return this.items[this.count - 1];
  }

  isEmpty() {
    return this.size() === 0;
  }

  clear() {
    this.items = {};
    this.count = 0;
    this.lowestCount = 0;
  }

  size() {
    return this.count - this.lowestCount;
  }

  toString() {
    if (this.isEmpty()) {
      return '';
    }
    let objString = `${this.items[this.lowestCount]}`;
    for (let i = this.lowestCount + 1; i < this.count; i++) {
      objString = `${objString},${this.items[i]}`;
    }
    return objString;
  }
}

leetcode对应训练

(0)

相关推荐

  • 使用javaScript实现一个队列

    使用javaScript实现一个队列

  • Java队列篇之实现数组模拟队列及可复用环形队列详解

    像栈一样,队列(queue)也是一种线性表,它的特性是先进先出,插入在一端,删除在另一端.就像排队一样,刚来的人入队(push)要排在队尾(rear),每次出队(pop)的都是队首(front)的人队 ...

  • 第五节实战辩证双阴出入(第六章完)

    第五节实战辩证双阴出入(国恒铁路) 双阴出货与双阴入货,是辩证的,一旦处理不好,将会错失良机. 这里有一个真实的.惊险的故事,它发生在2012年5月23日(周三).有位同学按照他学过的阴线战法,于同年 ...

  • 诗人样本||安徽江双乐:流 的 畅 想(五章)

    诗人简介: 江双乐,安徽芜湖人.籍贯桐城.研究生学历,文学学士,执业医师,大型公立医院高管.芜湖市作协会员,镜湖区作协副主席.业余时间写作.1984年在芜湖<芜湖日报>副刊发表散文诗< ...

  • R15 双五 高增长 永续经营=高端养老股

    高端养老股养成记: 什么是养老股?我们知道,一般来说养老股大概有如下几个要求或特征:有可观现金流(股息率).稳健确定性.永续经营性. 那么什么是高端养老股?它就是在如上基础上再加上一个要求:在未来一段 ...

  • 第二百六十五章缺士怕车防守难,一步多用防双攻

    第二百六十五章 车马炮主攻,双士象主守.缺象怕炮,少士怕车.在没有士的情形下,将帅很难防守双車.没有士的斜线支援,战斗防守起来万分困难.当对方可以两个子力甚至多个子力进行将军攻击时候,我方不能确定对方 ...

  • 發端曰言 第五章 天圆地方(单渔泉)

    第五节 天圆地方 圆生玄,玄生勾股. 如何作一个线段,使其长度等于一个已知圆的周长,这个看似简单的问题却至今无解. 圆的周长(S)= 圆周率(π)×直径(r),这是小学生都知道的公式.可问题出在了圆周 ...

  • (小说连载)人市 第五章 || 田国彬(河北藁城)

    第 五 章       我们来到一座冷库,院里亮着大灯泡,门口有两棵小杨树,汽车停的地方离门口远了点.    哥们乱喊一气:"离门口这么远,我们不干."    "这得费多 ...

  • 刀神传说第六十五章沐诗瑶篇(12)

    [作者:高依弟] 李孝明忽满脸欣慰,连皱纹似乎都少了,说:"成家了就好!"然后把缺角的玉交给沐诗瑶. 李孝明转身要回第四间房子,小芳扶他进去. 沐诗瑶说:"走吧!&quo ...

  • 『糖尿病饮食与防治』第五章 糖尿病自然治疗与辅助措施

    一.饮食疗法 饮食疗法是各型糖尿病的基础治疗,不论病情轻重,也不论是否应用药物治疗,均应长期坚持和严格执行,糖尿病饮食疗法的目的在于摄入仅够维持机体正常需要的糖类,减轻胰岛β细胞的负担,促进空腹血糖. ...

  • 『中医偏方精品』第五章 血液系统疾病

    第五章  血液系统疾病 一.再生障碍性贫血 本症系属于红骨髓显著减少,造血功能衰竭而引起的一组综合病症,临床表现主要为进行性贫血.乏力.体表及内脏出血以及反复感染等. 急性型:发病缓急不一,但进展迅速 ...