这是第二周的练习题,这里补充下咯,五一节马上就要到了,自己的计划先安排上了,开发一个有趣的玩意儿。

下面是之前分享的链接:

欢迎关注我的 个人主页 && 个人博客 && 个人知识库 && 微信公众号“前端自习课”

本周练习内容:数据结构与算法 —— Queue

这些都是数据结构与算法,一部分方法是团队其他成员实现的,一部分我自己做的,有什么其他实现方法或错误,欢迎各位大佬指点,感谢。

一、队列有什么特点,生活中有什么例子?


解题:

1.概念介绍

队列,又称为伫列(queue),是先进先出(FIFO, First-In-First-Out)的线性表。在具体应用中通常用链表或者数组来实现。队列只允许在后端(称为rear)进行插入操作,在前端(称为front)进行删除操作。 ——《维基百科》

队列特点:先进先出操作。

生活中的案例:常见的排队,在电影院也好,排队结账也是,排在第一位的人会先接受服务。

2.与堆栈区别

队列的操作方式和堆栈类似,唯一的区别在于队列只允许新数据在后端进行添加。

二、请实现一个队列,并实现以下方法:

  • enqueue(element):向队列尾部添加一个新的项。
  • dequeue():移除队列的第一项,并返回被移除的元素。
  • front():返回队列中第一个元素 —— 最先被添加,也将是最先被移除的元素。队列不做任何变动 (不移除元素,只返回元素信息 —— 与 Stack 类的 peek 方法类似)。
  • tail():返回队列中的最后一个元素,队列不做任何变动。
  • isEmpty():如果栈没有任何元素就返回 true,否则返回 false
  • size():返回队列包含的的元素个数,与数组的 length 属性类似。
  • print():打印队列中的元素。

提示:Web 端优先使用 ES6 以上的语法实现。


解题:

  1. /**
  2. * 2. 实现一个队列
  3. */
  4. class Queue {
  5. constructor (){
  6. this.items = []
  7. }
  8. // enqueue(element):向队列尾部添加一个新的项。
  9. enqueue( element ){
  10. this.items.push(element)
  11. }
  12. // dequeue():移除队列的第一项,并返回被移除的元素。
  13. dequeue (){
  14. return this.items.shift()
  15. }
  16. // front():返回队列中第一个元素 —— 最先被添加,也将是最先被移除的元素。队列不做任何变动 (不移除元素,只返回元素信息 —— 与 Stack 类的 peek 方法类似)。
  17. front (){
  18. return this.items[0]
  19. }
  20. // tail():返回队列中的最后一个元素,队列不做任何变动。
  21. tail (){
  22. return this.items[this.items.length]
  23. }
  24. // isEmpty():如果栈没有任何元素就返回 true,否则返回 false。
  25. isEmpty (){
  26. return this.items.length === 0
  27. }
  28. // size():返回队列包含的的元素个数,与数组的 length 属性类似。
  29. size (){
  30. return this.items.length
  31. }
  32. // print():打印队列中的元素。
  33. print (){
  34. console.log(this.items.toString())
  35. }
  36. }

三、使用队列计算斐波那契数列的第 n 项。

斐波那契数列(Fibonacci sequence),又称黄金分割数列、因数学家列昂纳多·斐波那契(Leonardoda Fibonacci)以兔子繁殖为例子而引入,故又称为“兔子数列”,指的是这样一个数列:

  1. 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233377610...

在数学上,斐波那契数列以如下被以递推的方法定义:F(1)=1,F(2)=1, F(n)=F(n-1)+F(n-2)(n>=3,n∈N,即前两项固定为 1*,后面的项为前两项之和,依次向后。在现代物理、准晶体结构、化学等领域,斐波纳契数列都有直接的应用。

使用示例如下:

  1. fibonacci(5); --> 5
  2. fibonacci(9); --> 34
  3. fibonacci(14); --> 377

解题:

解题方法1:

  1. /**
  2. * 3. 使用队列计算斐波那契数列的第 n 项。
  3. * 前两项固定为 1,后面的项为前两项之和,依次向后。
  4. * @param {Number} num
  5. */
  6. function fibonacci (num){
  7. if(isNaN(num) || num < 0 || num === 0) return 0
  8. // // 1. 直接
  9. // let n1 = 1, n2 = 1, sum
  10. // for(let i = 3; i <= num; i++){
  11. // sum = n1 + n2
  12. // n1 = n2
  13. // n2 = sum
  14. // }
  15. // // 2. 队列 考虑小于等于2
  16. // let arr = [], sum
  17. // num === 1 && (arr = [1])
  18. // num >= 2 && (arr = [1, 1])
  19. // for(let i = 3; i <= num; i ++){
  20. // sum = arr[i-2] + arr[i-3]
  21. // arr.push(sum)
  22. // }
  23. // // 3.队列 进出队列
  24. let queue = [], sum;
  25. for(let i = 1; i <= num; i ++){
  26. if(i <=2 ){
  27. queue.push(1)
  28. }else{
  29. sum = queue[0] + queue[1]
  30. queue.push(sum)
  31. queue.shift()
  32. }
  33. }
  34. return sum
  35. }

解题方法2:

  1. function fibonacci(n) {
  2. const queue = new Queue();
  3. queue.enqueue(1);
  4. queue.enqueue(1);
  5. let index = 0;
  6. while(index < n - 2) {
  7. index += 1;
  8. // 出队列一个元素
  9. const delItem = queue.dequeue();
  10. // 获取头部值
  11. const headItem = queue.front();
  12. const nextItem = delItem + headItem;
  13. queue.enqueue(nextItem);
  14. }
  15. return queue.tail();
  16. }
  17. console.log(fibonacci(9)); // 34

四、实现优先队列 PriorityQueue。

现实中优先队列的例子很多,比如机场登机的顺序,头等舱和商务舱乘客优先级高于经济舱乘客。又如在银行中办理业务时,VIP 客户的优先级高于普通客户。要实现一个优先队列,有两种方式:

  1. 设置优先级,然后在正确的位置添加元素。
  2. 用入列操作添加元素,然后按照优先级移除它们。

本题要求使用第一种方式来实现优先队列,数值越小优先级越高,若优先级相同时,先入队的元素,排在前面。

使用示例如下:

  1. let priorityQueue = new PriorityQueue();
  2. priorityQueue.enqueue("leo", 2);
  3. priorityQueue.enqueue("pingan", 1);
  4. priorityQueue.enqueue("robin", 1);
  5. priorityQueue.print();
  6. // pingan - 1
  7. // robin - 1
  8. // leo - 2

解题:

解题方法1:

  1. class PriorityQueue {
  2. constructor() {
  3. this._items = [];
  4. }
  5. enqueue(element, priority) {
  6. let queueElement = {
  7. element
  8. priority
  9. };
  10. if (this.isEmpty()) {
  11. this._items.push(queueElement);
  12. } else {
  13. let added = false;
  14. for (var i = 0; i < this.size(); i++) {
  15. if (queueElement.priority < this._items[i].priority) {
  16. this.items.splice(i, 0, queueElement);
  17. added = true;
  18. break ;
  19. }
  20. }
  21. if (!added) {
  22. this._items.push(queueElement);
  23. }
  24. }
  25. }
  26. print() {
  27. var strArr = [];
  28. strArr = this._items.map(function (item) {
  29. return `${item.element}->${item.priority}`;
  30. });
  31. console.log(strArr.toString());
  32. }
  33. }

解题方法2:

  1. /**
  2. * 4. 实现优先队列
  3. */
  4. class PriorityQueue {
  5. constructor (){
  6. this.items = []
  7. }
  8. enqueue (element, priority){
  9. let ele = {element, priority}
  10. let isAdded = false
  11. for(let i = 0; i < this.items.length; i++){
  12. if(ele.priority < this.items[i].priority){
  13. this.items.splice(i, 0, ele)
  14. isAdded = true
  15. break
  16. }
  17. }
  18. !isAdded && this.items.push(ele)
  19. }
  20. print (){
  21. for(let i = 0; i < this.items.length; i++){
  22. let {element, priority} = this.items[i]
  23. console.log(`${element} - ${priority}`)
  24. }
  25. }
  26. }
  27. let leo = new PriorityQueue()
  28. leo.enqueue("leo", 2);
  29. leo.enqueue("leo1", 1);
  30. leo.enqueue("leo2", 1);
  31. console.log(leo)

五、用队列实现栈。

利用两个队列实现栈,栈的特点是后进先出,可以让元素入队 q1,留下队尾元素让其他元素出队,暂存到 q2 中,再让 q1 中剩下的元素出队,即最后进的最先出来。

提示:入栈和出栈都在 q1 中完成,q2 只作为临时中转空间。


解题:

  1. /**
  2. * 5. 队列实现栈
  3. */
  4. class Myqueue {
  5. constructor (){
  6. this.items = []
  7. }
  8. enqueue (element){
  9. this.items.push(element)
  10. }
  11. dequeue (){
  12. return this.items.shift()
  13. }
  14. }
  15. class Mystack {
  16. constructor (){
  17. this.q1 = new myQueue()
  18. this.q2 = new myQueue()
  19. }
  20. push (element){
  21. this.q1.enqueue(element)
  22. this.q2.items = []
  23. let len = this.q1.items.length
  24. while(len > 0){
  25. this.q2.enqueue(this.q1.items[len-1])
  26. len --
  27. }
  28. }
  29. pop (){
  30. let result = this.q2.dequeue()
  31. let len = this.q2.items.length
  32. this.q1.items = []
  33. while(len > 0){
  34. this.q1.enqueue(this.q2.items[len-1])
  35. len --
  36. }
  37. return result
  38. }
  39. print (){
  40. console.log(this.q1.items.toString())
  41. }
  42. }

这里也可以直接使用第二题定义的Queue来实现:

  1. class QueueStack {
  2. constructor() {
  3. this.queue = new Queue();
  4. }
  5. push(item) {
  6. this.queue.enqueue(item);
  7. }
  8. pop() {
  9. // 向队列末尾追加 队列长度-1 次,后弹出队列头部
  10. for(let i = 1; i < this.queue.size(); i += 1) {
  11. this.queue.enqueue(this.queue.dequeue());
  12. }
  13. return this.queue.dequeue();
  14. }
  15. peek() {
  16. return this.queue.tail();
  17. }
  18. }

下周预告

下周将练习集合(Set) 的题目,五一要到咯,也要好好做自己一个项目了。

每周一练 之 数据结构与算法(Queue)的更多相关文章

  1. 每周一练 之 数据结构与算法(Set)

    这是第四周的练习题,五一放假结束,该收拾好状态啦. 下面是之前分享的链接: 1.每周一练 之 数据结构与算法(Stack) 2.每周一练 之 数据结构与算法(LinkedList) 2.每周一练 之 ...

  2. 每周一练 之 数据结构与算法(Tree)

    这是第六周的练习题,最近加班比较多,上周主要完成一篇 GraphQL入门教程 ,有兴趣的小伙伴可以看下哈. 下面是之前分享的链接: 1.每周一练 之 数据结构与算法(Stack) 2.每周一练 之 数 ...

  3. 每周一练 之 数据结构与算法(Dictionary 和 HashTable)

    这是第五周的练习题,上周忘记发啦,这周是复习 Dictionary 和 HashTable. 下面是之前分享的链接: 1.每周一练 之 数据结构与算法(Stack) 2.每周一练 之 数据结构与算法( ...

  4. 每周一练 之 数据结构与算法(LinkedList)

    这是第三周的练习题,原本应该先发第二周的,因为周末的时候,我的母亲大人来看望她的宝贝儿子,哈哈,我得带她看看厦门这座美丽的城市呀. 这两天我抓紧整理下第二周的题目和答案,下面我把之前的也列出来: 1. ...

  5. 每周一练 之 数据结构与算法(Stack)

    最近公司内部在开始做前端技术的技术分享,每周一个主题的 每周一练,以基础知识为主,感觉挺棒的,跟着团队的大佬们学习和复习一些知识,新人也可以多学习一些知识,也把团队内部学习氛围营造起来. 我接下来会开 ...

  6. 【算法】273-每周一练 之 数据结构与算法(Tree)

    这是第六周的练习题,最近加班比较多. 下面是之前分享的链接: [算法]200-每周一练 之 数据结构与算法(Stack) [算法]213-每周一练 之 数据结构与算法(LinkedList) [算法] ...

  7. 【算法】272-每周一练 之 数据结构与算法(Dictionary 和 HashTable)

    这是第五周的练习题,上周忘记发啦,这周是复习 Dictionary 和 HashTable. 下面是之前分享的链接: [算法]200-每周一练 之 数据结构与算法(Stack) [算法]213-每周一 ...

  8. 数据结构与算法-queue

    队列和stack类似,stack是先进后出,而queue的先进先出,也是一种特殊的线性表 基本概念 概念 队列是一种特殊的线性表 队列仅在线性表的两端进行操作 队头(Front):取出数据元素的一端 ...

  9. 【Java数据结构学习笔记之二】Java数据结构与算法之队列(Queue)实现

      本篇是数据结构与算法的第三篇,本篇我们将来了解一下知识点: 队列的抽象数据类型 顺序队列的设计与实现 链式队列的设计与实现 队列应用的简单举例 优先队列的设置与实现双链表实现 队列的抽象数据类型 ...

随机推荐

  1. 领扣(LeetCode)二叉树的所有路径 个人题解

    给定一个二叉树,返回所有从根节点到叶子节点的路径. 说明: 叶子节点是指没有子节点的节点. 示例: 输入: 1 / \ 2 3 \ 5 输出: ["1->2->5", ...

  2. 领扣(LeetCode)最长公共前缀 个人题解

    编写一个函数来查找字符串数组中的最长公共前缀. 如果不存在公共前缀,返回空字符串 "". 示例 1: 输入: ["flower","flow" ...

  3. web前端面试经常遇得到的题型

    1.position的值, relative和absolute分别是相对于谁进行定位的? § absolute :生成绝对定位的元素, 相对于最近一级的 定位不是 static 的父元素来进行定位. ...

  4. Java内存模型与volatile关键字

    Java内存模型与volatile关键字 一).并发程序开发 并行程序的开发要涉及多线程.多任务间的协作和数据共享问题. 常用的并发控制:内部锁.重入锁.读写锁.信号量. 二).线程的特点 线程的特点 ...

  5. LMS自适应天线阵列设计 MATLAB

    在自适应天线课上刚刚学了LMS自适应阵,先出一个抢先版贴一下结果,抢先某个小朋友一步. 关于LMS的具体介绍,直接看wiki里的吧,解释的比书上简明:传送门:https://en.wikipedia. ...

  6. day 28 网络基础相关的知识

    1.网络基础相关的知识 架构 C/S 架构:  client 客户端  server服务器端 优势: 能充分发挥PC机的性能 B/S 架构: browser 浏览器 server服务器       隶 ...

  7. Theano中的导数

    计算梯度 现在让我们使用Theano来完成一个稍微复杂的任务:创建一个函数,该函数计算相对于其参数x的某个表达式y的导数.为此,我们将使用宏T.grad.例如,我们可以计算相对于的梯度 import ...

  8. hybrid app初体验,和react-native一起飞

    第一次启动了react-native的示例,今天主要把其中遇到的坑与解决的办法分享给大家.如有疏漏.错误还望指正. 首先还是要从hybrid app这个概念说起(如果对于这个过程不感兴趣的同学,可以直 ...

  9. TestNG系列(二)TestNG注解

    前言 TetsNG提供了很多注解,允许测试人员灵活地组织测试用例 一.@Test @Tets是TestNG的核心注解,被注解的方法,表示为一个测试方法. description属性 @Test(des ...

  10. Python如何爬取实时变化的WebSocket数据【华为云技术分享】

    一.前言 作为一名爬虫工程师,在工作中常常会遇到爬取实时数据的需求,比如体育赛事实时数据.股市实时数据或币圈实时变化的数据.如下图: Web 领域中,用于实现数据'实时'更新的手段有轮询和 WebSo ...