队列是一种先进先出(FIFO)的数据结构,数据只能在队尾插入或者在队首删除。队列用在很多地方,比如提交操作系统的一系列进程,打印任务池等,一些仿真系统用队列模拟银行或杂货店排队的顾客。
接下来,将从3个方面来深入理解和使用栈这种数据结构。
抽象数据类型定义队列的JS实现解决实际问题使用构造器调用模式,这是一套类似类的对象构建语法,通过在函数前面加上new调用,同时this会绑定到这个新对象上。
//Queue.js //Queue对象定义 function Queue(){ this.dataStore = []; this.enqueue = enqueue; this.dequeue = dequeue; this.empty = empty; this.front = front; this.back = back; this.count = count; this.toString = toString;//显示队列元素 } function enqueue(element){ this.dataStore.push(element);//直接使用数组方法 } function dequeue(){ return this.dataStore.shift();//直接使用数组方法 } function empty(){ if(this.dataStore.length == 0) return true; else return false; } function clear(){ this.dataStore.length = 0; } function front(){ return this.dataStore[0]; } function back(){ return this.dataStore[this.dataStore.length - 1]; } function count(){ return this.dataStore.length; } function toString(){ var str = ""; for(var i=0; i<this.dataStore.length; i++) { str += this.dataStore[i]+"\n" } return str; } //实例化Queue对象 var oneQueue = new Queue();问题描述:当男男女女来到舞池,他们按照性别排成两队。当舞池有地方空出来时,选择两个队伍中第一个人组成舞伴。他们身后的人各自向前移动一位。
//app.js var males = new Queue(); var females = new Queue(); function getDancers() { //读取依次进来的人 var content = document.getElementById("dancers_content").firstChild.nodeValue; var names = content.split("\n"); //将人们按照性别分成两队 for(var j=0; j<names.length; j++) { var dancer = names[j].split(" "); var dancer_name = dancer[1]; var dancer_sex = dancer[0]; if(dancer_sex=="F") { females.enqueue(new Dancer(dancer_name,dancer_sex)); } else { males.enqueue(new Dancer(dancer_name,dancer_sex)); } } } function goDance() { var name = document.getElementById("dancers_name"); name.innerHTML = "";//将结果显示在网页上 while(!males.empty() && !females.empty()) { name.innerHTML += "Female dancer is "+females.dequeue().name +"; Male dancer is "+males.dequeue().name+".\n"; } if(males.empty()) { name.innerHTML += females.count() +" female dancers are waiting." } if(females.empty()) { name.innerHTML += males.count() +" male dancers are waiting." } }基数排序具体原理可以参考百度百科。
//app.js //生成含有12个元素的初始数组,待排序 var startNums = []; function beforeSort(){ for(var i=0; i<12; i++) { startNums[i] = Math.floor(Math.random()*101+1); } //将生成的数组显示在网页上 var originalNums = document.getElementById("original_nums"); originalNums.value = ""; for(var i=0; i<startNums.length; i++) { originalNums.value += startNums[i]+" "; } } //有10个队列,编号分别为0-9 var globalQueues = []; for(var i=0; i<10; i++) { globalQueues[i] = new Queue(); } //根据数组中每个数字十位或者个位的数值,将数字分配到对应队列 function distribute(nums, queues, n, digit){ for(var i=0; i<n; i++) { if(digit == 1) { queues[nums[i]%10].enqueue(nums[i]); } else { queues[Math.floor(nums[i]/10)].enqueue(nums[i]); } } } //从队列中收集数字 function collect(queues, nums) { var i = 0; for(var digit = 0; digit <10; digit++) { while(!queues[digit].empty()) { nums[i++] = queues[digit].dequeue(); } } } //开始排序,先个位,再十位 function sort(){ distribute(startNums, globalQueues, startNums.length, 1); collect(globalQueues, startNums); distribute(startNums, globalQueues, startNums.length, 10); collect(globalQueues, startNums); //将排序结果显示在网页上 var sortedNums = document.getElementById("sorted_nums"); sortedNums.value = ""; for(var i=0; i<startNums.length; i++) { sortedNums.value += startNums[i]+" "; } }优先队列:在优先队列中删除元素时,需要考虑优先级的限制。
//app.js //模拟医院急诊室,当病人进入门诊时,会根据病情严重情况,获得优先级排序。高优先级的患者先于低优先级的患者就医。 //构建病人对象,code为优先级,1为最高优先级 function Patient(name, code) { this.name = name; this.code = code; } //优先队列只有出列操作不同于普通队列,需要先比较优先级 function pridequeue(){ var entry = 0; for(var i=1; i<this.dataStore.length; i++) { if(this.dataStore[entry].code > this.dataStore[i].code) entry = i; } return this.dataStore.splice(entry, 1); } //模拟创建急诊病人的优先队列 var pri = new Queue(); pri.enqueue(new Patient("Fehrenback", 6)); pri.enqueue(new Patient("Jones", 4)); pri.enqueue(new Patient("Smith", 5)); pri.enqueue(new Patient("Brown", 1)); pri.enqueue(new Patient("Ingram", 1)); function showPri(){ var firstP = pri.pridequeue(); var secondP = pri.pridequeue(); var thirdP = pri.pridequeue(); //将优先出列的病人名字显示在网页上 var priPatients = document.getElementById("pri_patients"); priPatients.value = "1."+ firstP[0].name + " 2."+ secondP[0].name + " 3."+ thirdP[0].name; }