数据结构——队列(JavaScript)

队列是遵循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);

控制台输出如下:
这里写图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值