0 队列
队列是遵循先进先出(First In First Out,也称为先来先服务)原则的一组有序的项。
- 队列在尾部添加新元素,并从顶部移除元素。
- 最新添加的元素必须排在队列的末尾。
现实中
地铁排队 银行排队
1 es5实现
定义:
//队列类
//特点:先进先出
function Queue(){
//存储队列中的元素
let items = [];
//队列的方法
//向队列尾部添加一个新的元素
this.enqueue = function ( ele ) {
items.push(ele);
}
// 移除队列的第一个元素,并返回被移除的元素
this.dequeue = function ( ) {
return items.shift();
}
//返回队列中第一个元素
this.front = function ( ) {
return items[0];
}
//判断队列是否有元素,没有元素,返回true,有元素,返回false
this.isEmpty = function ( ) {
return items.length==0;
}
//返回队列中元素的个数
this.size = function ( ) {
return items.length;
}
//打印队列里的元素
this.print = function ( ) {
console.log ( items.toString () );
}
}
验证:
//实例化一个队列
let queue1 = new Queue();
console.log ( queue1.isEmpty () );//开始队列是空的,输出true
//向队列中添加三个元素
queue1.enqueue("John");
queue1.enqueue("jack");
queue1.enqueue("Aimer");
//打印队列的元素
queue1.print();//John,jack,Aimer
console.log ( queue1.size () );//3
console.log ( queue1.isEmpty () );//false
queue1.dequeue();//移除队列的第一个元素John
queue1.dequeue();//移除队列的第一个元素jack
queue1.print();//Aimer
2 es6实现
定义:
//用ECMAScript6语法实现的Queue类
let Queue2 = (function ( ) {
//WeakMap可以存储键值对,其中键是对象,值可以是任意数据类型
const items = new WeakMap();
class Queue2 {
constructor (){
items.set(this,[]);
}
enqueue(ele){
let q = items.get(this);
q.push(ele);
}
dequeue(){
let q = items.get(this);
return q.shift();
}
front () {
let q = items.get(this);
return q[0];
}
isEmpty(){
let q = items.get(this);
return q.length==0;
}
size(){
let q = items.get(this);
return q.length;
}
print(){
let q = items.get(this);
console.log ( q.toString () );
}
}
return Queue2;
}());
验证:
let queue2 = new Queue2();
console.log ( queue2.isEmpty () );//开始队列是空的,输出true
//向队列中添加三个元素
queue2.enqueue("John");
queue2.enqueue("jack");
queue2.enqueue("Aimer");
// //打印队列的元素
queue2.print();//John,jack,Aimer
console.log ( queue2.size () );//3
console.log ( queue2.isEmpty () );//false
queue2.dequeue();//移除队列的第一个元素John
queue2.dequeue();//移除队列的第一个元素jack
queue2.print();//Aimer
3 优先队列
优先队列:元素的添加和移除是基于优先级的。 一个现实的例子就是机场登机的顺序。头等舱和商务舱乘客的优先级要高于经济舱乘客
实现方法::添加的元素时,设置优先级,然后在正确的位置添加元素 规定:优先级顺序由大到小,对应数字1,2,3,..........., 其中1的优先级最大,数字越大,优先级越小
3.1 最小优先队列
优先级的值越小,优先级别越高,放到队列的最前面
//以下为最小优先队列,因为优先级的值较小的元素被放置在队列最前面(1代表更高的优先级)
function PriorityQueue ( ) {
let items = [];
function QueueElement (element,priority ) {
this.element = element;
this.priority = priority;
}
this.enqueue = function ( element,priority ) {
let queueEle = new QueueElement(element,priority);
let isAdd = false;
for ( let i = 0 ;i<items.length;i++ ) {
//找到优先数字比当前元素大的(优先级比当前元素低),就将当前元素插入该元素前面
if(queueEle.priority<items[i].priority){
items.splice(i,0,queueEle);
isAdd = true;
break;
}
}
//如果所有元素都比当前元素优先级高,当前元素就添加到末尾
if(isAdd==false){
items.push(queueEle);
}
}
this.print = function(){
for (let i=0; i<items.length; i++){
// for(let key in items[i]){
// console.log ( key+"="+ items[i][key] );
// }
console.log(items[i].element+","+items[i].priority);
}
};
// 移除队列的第一个元素,并返回被移除的元素
this.dequeue = function ( ) {
return items.shift();
}
//返回队列中第一个元素
this.front = function ( ) {
return items[0];
}
//判断队列是否有元素,没有元素,返回true,有元素,返回false
this.isEmpty = function ( ) {
return items.length==0;
}
//返回队列中元素的个数
this.size = function ( ) {
return items.length;
}
}
验证:
let pQueue2 = new PriorityQueue();
console.log ( pQueue2.isEmpty () );//开始队列是空的,输出true
//向队列中添加三个元素
pQueue2.enqueue("John",2);
pQueue2.enqueue("jack",3);
pQueue2.enqueue("ccc",3);
pQueue2.enqueue("Aimer",1);
// //打印队列的元素
pQueue2.print();//John,jack,Aimer
console.log ( pQueue2.size () );//3
console.log ( pQueue2.isEmpty () );//false
pQueue2.dequeue();//移除队列的第一个元素 Aimer
pQueue2.dequeue();//移除队列的第一个元素k John
pQueue2.print();//jack,3
例子:循环队列-击鼓传花
循环队列
-
得到一份名单,把里面的名字全都加入队列
-
给定一个数字,然后迭代队列。从队列开头移除一项,再将其添加到队列末尾 2.1 模拟击鼓传花(如果你把花传给了旁边的人,你被淘汰的威胁立刻就解除了)。 一旦传递次数达到给定的数字,拿着花的那个人就被淘汰了(从队列中移除)
-
最后只剩下一个人的时候,这个人就是胜者
过程图示:
击鼓传花实现:
function hotPotato(nameList,num){
let queue = new Queue();
// 1.得到一份名单,把里面的名字全都加入队列
for ( let i = 0 ;i<nameList.length;i++ ) {
queue.enqueue(nameList[i]);
}
let taotai = "";//存储淘汰者
//队列的元素个数大于1个,一直运行游戏
while ( queue.size()>1 ){
// //模拟击鼓传花
// 2.给定一个数字,然后迭代队列。从队列开头移除一项,再将其添加到队列末尾
for ( let i = 0 ;i<num;i++ ) {
queue.enqueue(queue.dequeue());
}
//被淘汰者
taotai = queue.dequeue();
console.log ( taotai + "被淘汰,从队伍中移除" );
}
//返回获胜者
return queue.dequeue();
}
//验证:
let names = ['John','Jack','Camila','Ingrid','Carl'];
let winner = hotPotato(names, 2);
console.log('The winner is: ' + winner);
使用到队列类:
//队列类
//特点:先进先出
function Queue(){
//存储队列中的元素
let items = [];
//队列的方法
//向队列尾部添加一个新的元素
this.enqueue = function ( ele ) {
items.push(ele);
}
// 移除队列的第一个元素,并返回被移除的元素
this.dequeue = function ( ) {
return items.shift();
}
//返回队列中第一个元素
this.front = function ( ) {
return items[0];
}
//判断队列是否有元素,没有元素,返回true,有元素,返回false
this.isEmpty = function ( ) {
return items.length==0;
}
//返回队列中元素的个数
this.size = function ( ) {
return items.length;
}
//打印队列里的元素
this.print = function ( ) {
console.log ( items.toString () );
}
}