队列是遵循FIFO(First In First Out,先进先出,也称为先来先服务)原则的一组有序的项。 队列在尾部添加新元素,并从顶部移除元素。最新添加的元素必须排在队列的末尾。
举个栗子:
队列的创建
function Queue(){//首先创建一个类
var item = [];
this.addToQueue = function(){//在队列尾部添加一个或多个新项
var i = 0;
while(i < arguments.length){
console.log(arguments[i]);
item.push(arguments[i]);
i++;
}
return;
}
this.delQueue = function(){//移出头部(第一项)
return item.shift();
}
this.head = function(){//返回最先被添加的元素,对数组不做任何操作
return item[0];
}
this.isEmpty = function(){//判断队列是否为空
return !(item.length);
}
this.size = function(){//返回队列长度
return item.length;
}
this.clear = function(){//清空队列内元素
item = [];
}
this.print = function(){//输出队列元素
console.log(item.toString());
}
}
队列的基本使用
var queue = new Queue();
console.log(queue.isEmpty()); //true
queue.addToQueue('a','b','c');
queue.addToQueue('d');
queue.print(); //a,b,c,d
console.log(queue.head()); //a
console.log(queue.size()); //4
queue.delQueue();
queue.delQueue();
console.log(queue.isEmpty()); //false
queue.clear();
console.log(queue.isEmpty()); //true
优先队列
当泰坦尼克沉没的时候,然们组织让女人孩子先上救生船,最后才是男士,这就是优先;当普通客户排队等候的时候,这个时候,杀出一个VIP,工作人员会先处理VIP业务,这就是优先……
实现优先队列主要是改变入队操作,以及输出方式
function priorityQueue(){//优先队列
var item = [];
var queueElement = function(element,priority){
this.element = element;
this.priority = priority;
}
this.addToQueue = function(element,priority){
var qelement = new queueElement(element,priority);
//判断优先级后添加在正确的位置
if(this.isEmpty()){
item.push(qelement);
}else{
for (var i = 0; i < item.length; i++) {
if(qelement.priority < item[i].priority){//假设数字越小优先级越高
item.splice(i,0,qelement);
break;
}
}
if(i === item.length){
item.push(qelement);
}
}
}
this.delQueue = function(){//移出头部(第一项)
return item.shift();
}
this.head = function(){//返回最先被添加的元素,对数组不做任何操作
return item[0];
}
this.isEmpty = function(){//判断队列是否为空
return !(item.length);
}
this.size = function(){//返回队列长度
return item.length;
}
this.clear = function(){//清空栈内元素
item = [];
}
this.print = function(){//输出队列元素,修改输出方式
var str = '';
item.forEach(function(v,i,a){
str += a[i].element + ' ' + a[i].priority + ',';
})
console.log(str);
}
}
//使用优先队列
var queue = new priorityQueue();
console.log(queue.isEmpty());
queue.addToQueue('a',3);
queue.addToQueue('b',2);
queue.addToQueue('c',1);
queue.addToQueue('d',2);
queue.print();
console.log(queue.head());
console.log(queue.size());
queue.delQueue();
queue.delQueue();
console.log(queue.isEmpty());
queue.clear();
console.log(queue.isEmpty());
控制台输出显示:
循环队列
就类似于击鼓传花,鼓声一停,拿花的人挂掉,剩下的人继续,直到剩下最后一个,你就是王者。
function loopQueue(mumberList/*人员名单*/,num/*规定时间内安全通过的人数*/){
var queue = new Queue();
//人员进入房间
for(var i = 0; i<mumberList.length; i++){
queue.addToQueue(mumberList[i]);
}
//定义一个容器装名字
var container = '';
//开始传花
while(queue.size() > 1){
for(var i = 0; i<num; i++){
queue.addToQueue(queue.delQueue());//循环入队出队,模拟圆圈
}
container = queue.delQueue(); //此人已死,留名
console.log(container + '挂掉出局');
}
return queue.head(); //返回最后一个,王者
}
var mumberList = ['赵某','钱某','孙某','李某','周某','吴某','郑某','王某'];
var king = loopQueue(mumberList,3);
console.log(king + '为本场王者!');
控制台结果输出:
应用——使用队列循环队列处理任务
现有名称为name[i]且处理时间为time[i]的n个任务按顺序排成一排,CPU通过循环调度法逐一处理这些任务,每个任务最多处理q ms(这个时间称为时间片)。如果q ms之后任务尚未处理完毕,那么该任务将被移动至队列最末尾,CPU开始执行下一个任务。按时间输出各任务及任务结束时间
举个栗子,假设q为100,执行一下队列
A(150)-B(80)-C(200)-D(200),执行过程为:
注意点
在传参的过程中需要判断参数是节点还是节点的参数;
可以知道,我们只需要判断队列的第一个元素并进行操作就可以了;
对函数中this的指向要熟悉(闭包);
代码如下:
function waitingQueue(){
var item = [];
var waitingNode = function(name,time){
this.name = name;
this.time = time;
}
this.addToQueue = function(){
if(arguments.length > 1){
var waitingnode = new waitingNode(arguments[0],arguments[1]);
item.push(waitingnode);
}else{
var waitingnode = new waitingNode(arguments[0].name,arguments[0].time);
item.push(waitingnode);
}
}
this.delQueue = function(){//移出头部(第一项)
var name = item[0].name;
var time = item[0].time;
item.shift();
return {name,time};
}
this.head = function(){//返回最先被添加的元素,对数组不做任何操作
return item[0];
}
this.isEmpty = function(){//判断队列是否为空
return !(item.length);
}
this.size = function(){//返回队列长度
return item.length;
}
this.clear = function(){//清空栈内元素
item = [];
}
this.print = function(){//输出队列元素
var str = '';
item.forEach(function(v,i,a){
str += a[i].name + ' ' + a[i].time + ',';
})
console.log(str);
}
this.run = function(frequency){
var totalTime = 0;
while(!this.isEmpty()){
totalTime += frequency;
item[0].time -= frequency;
if(item[0].time <= 0){
totalTime += item[0].time;
console.log(item[0].name +' ' + totalTime);
this.delQueue();
}
else{
this.addToQueue(this.delQueue());
}
}
}
}
var waitingqueue = new waitingQueue();
waitingqueue.addToQueue('p1',150);
waitingqueue.addToQueue('p2',80);
waitingqueue.addToQueue('p3',200);
waitingqueue.addToQueue('p4',350);
waitingqueue.addToQueue('p5',20);
waitingqueue.run(100);
控制台输出如下: