栈和队列

133 阅读2分钟

栈和队列

栈是一种运算受限的线性表,先进后出。

应用:函数调用栈

例如:A->B->C->D 函数A调用函数B,函数B调用函数C,函数C调用函数D。

A函数开始执行,将函数A压入栈中,然后函数A调用了函数B,将函数B压入栈中,函数B调用函数C,将函数C压入栈中,函数C调用函数D,将函数D压入栈中。

  1. 函数D执行完后弹出函数栈,
  2. 函数C执行完后弹出函数栈,
  3. 函数B执行完后弹出函数栈,
  4. 函数A执行完后弹出函数栈。

栈结构实现:

 class Stack {
     constructor() {
         //创建栈
         this.items = [];
     }
     //入栈
     push(ele) {
        return this.items.push(ele);
     }
     //出栈
     pop() {
        return this.items.pop();
     }
     //查看栈顶
     peak() {
         return this.items[this.items.length - 1];
     }
     //栈的长度
     size() {
         return this.items.length;
     }
     //栈是否为空
     isEmpty() {
         return this.items.length == 0;
     }
 }

队列

队列是一种受限的线性结构,符合先进先出规则(FIFO) frist in first out

受限之处在于它只允许在表的前端(front)进行删除操作,而在表的后端(rear)进行插入操作

队列实现:

 //队列
 class Queue {
     constructor() {
             this.items = [];
         }
         //尾部添加元素
     enqueue(ele) {
             return this.items.push(ele);
         }
         //头部删除元素
     dequeue() {
             return this.items.shift();
         }
         //查看队列头元素
     front() {
             return this.items[0];
         }
         //队列长度
     size() {
             return this.items.length;
         }
         //队列是否为空
     isEmpty() {
         return this.items.length == 0;
     }
 }

击鼓传花游戏规则:几个朋友一起玩一个游戏, 围成一圈, 开始数数, 数到某个数字的人自动淘汰

代码实现:

 //队列实现 :击鼓传花
 function passGame(nameList, num) {
     //创建队列结构
     let q = new Queue();
     //将所有的人添加到队列当中
     for (let i = 0; i < nameList.length; i++) {
         q.enqueue(nameList[i]);
     }
 ​
     //开始数数字
     //进行多轮,直到只剩下一个人结束游戏
     while (q.size() > 1) {
         for (let i = 0; i < num - 1; i++) {
             //如果小于num,将此元素再从队列尾部入队
             q.enqueue(q.dequeue());
         }
         //数到num的人,移除队列,被淘汰
         q.dequeue();
     }
     //返回获胜的人
     console.log(q.items);
     console.log(q.size());
     console.log(q.front());
     // return q.front();
 }

优先级队列

优先级队列不会向普通队列一样直接在队列的尾部添加元素,而是通过比较优先级类添加元素到适当的位置。

应用实例为线程队列,每一个线程都有优先级,优先级高的线程会被计算机优先执行。

实现优先级队列:

 //封装优先级队列
 class priorityQueue {
   constructor() {
     this.items = [];
   }
   //传入值和优先级
   enQueue(element, priority) {
     //创建一个对象,用于保存值和优先级
     let queueElement = {element: element, priority: priority};
     //判断队列是否为空
     if (this.items.length == 0) {
       this.items.push(queueElement);
     } else {
       //定义done,用于判断是否插入到队列中去了
       let done = false;
       //如果不为空,遍历队列中的元素,比较优先级,然后插入到合适的位置
       for (let i = 0; i < this.items.length; i++) {
         if (queueElement.priority < this.items[i].priority) {
           this.items.splice(i, 0, queueElement);
           done = true;
           break;
         }
       }
       //如果没有插入队列
       if (!done) {
         this.items.push(queueElement);
       }
     }
   }
   //头部删除元素
   dequeue() {
     return this.items.shift();
   }
   //查看队列头元素
   front() {
     return this.items[0];
   }
   //队列长度
   size() {
     return this.items.length;
   }
   //队列是否为空
   isEmpty() {
     return this.items.length == 0;
   }
 ​
   toString() {
     let resultString = "";
     for (let i = 0; i < this.items.length; i++) {
       resultString +=
         this.items[i].element + "-" + this.items[i].priority + ";";
     }
     return resultString;
   }
 }
 ​
 let q = new priorityQueue();
 q.enQueue("a", 10);
 q.enQueue("b", 1);
 q.enQueue("c", 6);
 q.enQueue("f", 13);
 q.enQueue("d", 19);
 ​
 console.log(q.toString());
 ​