队列是一种先进先出的数据结构,只能从队列的尾部插入元素,首部删除元素。队列这一数据结构在很多地方被用到,比如提交操作系统执行的一些列进程、打印任务池等。以下是用JavaScript实现队列。
<script>
function Queue() {
this.dataStore=[];
this.enqueue=enqueue;
this.dequeue=dequeue;
this.dequeue2=dequeue2;//优先级队列
this.front=front;
this.back=back;
this.toString=toString;
this.toStringObj=toStringObj;//打印元素是对象的队列
this.empty=empty;
this.count=count;
}
function enqueue(element) {
this.dataStore.push(element);
}
function dequeue() {
return this.dataStore.shift();
}
function dequeue2() {
var priority=0;
for(var i=1;i<this.dataStore.length;i++){
if(this.dataStore[i].code<this.dataStore[priority].code){
priority=i;
}
}
return this.dataStore.splice(priority,1);
}
function front() {
return this.dataStore[0];
}
function back() {
return this.dataStore[this.dataStore.length-1];
}
function toString() {
var retStr="";
for(var i=0;i<this.dataStore.length;++i){
retStr+=this.dataStore[i]+"\n";
}
return retStr;
}
function toStringObj() {
var retStr="";
for(var i=0;i<this.dataStore.length;i++){
retStr+="name:"+this.dataStore[i].name+",code:"+this.dataStore[i].code+"\n";
}
return retStr;
}
function count() {
return this.dataStore.length;
}
function empty() {
if(this.dataStore.length===0){
return true;
}else{
return false;
}
}
// 测试队列
var q = new Queue();
q.enqueue("a");
q.enqueue("b");
q.enqueue("c");
console.log(q.toString());
q.dequeue();
console.log(q.toString());
console.log("Front of queue: " + q.front());
console.log("Back of queue: " + q.back());
</script>
在一般情况下, 从队列中删除的元素, 一定是率先入队的元素。 但是也有一些使用队列的
应用, 在删除元素时不必遵守先进先出的约定。 这种应用, 需要使用一个叫做优先队列的
数据结构来进行模拟。
//测试优先级队列
function infoObj(name,code) {
this.name=name;
this.code=code;//优先级,数值越小,优先级越高
}
var queues2=new Queue();
var info1=new infoObj("a",5);
queues2.enqueue(info1);
var info2=new infoObj("b",4);
queues2.enqueue(info2);
var info3=new infoObj("c",6);
queues2.enqueue(info3);
queues2.enqueue(new infoObj("d",1));
queues2.enqueue(new infoObj("e",1));
console.log(queues2.toStringObj());
console.log("第一次出队后");
queues2.dequeue2();
console.log(queues2.toStringObj());
console.log("第二次出队后");
queues2.dequeue2();
console.log(queues2.toStringObj());
console.log("第三次出队后");
queues2.dequeue2();
console.log(queues2.toStringObj());
console.log("第四次出队后");
queues2.dequeue2();
console.log(queues2.toStringObj());
结果如下:
使用队列,还可以实现基数排序,代码如下
//将要排序的数字按照个位数或者十位数插入队列中
function distribute(nums,digit,queuesArr,n) {
if(digit===1){
for(var i=0;i<n;i++){
queuesArr[nums[i]%10].enqueue(nums[i]);
}
}else{
for(var j=0;j<n;j++){
queuesArr[Math.floor(nums[j]/10)].enqueue(nums[j]);
}
}
}
//收集队列数组中的数字
function collectNum(queuesArr,nums) {
var i=0;
for(var j=0;j<10;j++){
while(!queuesArr[j].empty()){
nums[i++]=queuesArr[j].dequeue();
}
}
}
//打印数组
function displayArr(arr) {
for(var i=0;i<arr.length;i++){
console.log(arr[i]);
}
}
var queuesArr=[];
var n=5;//待排序数字个数
for(var i=0;i<10;i++){
queuesArr[i]=new Queue();
}
var nums=[];
for (var i = 0; i < n; ++i) {
nums[i] = Math.floor(Math.floor(Math.random() * 101));
}
console.log("Before radix sort: ");
displayArr(nums);
distribute(nums,1,queuesArr,n);
collectNum(queuesArr,nums);
distribute(nums,10,queuesArr,n);
collectNum(queuesArr,nums);
console.log("\n\nAfter radix sort: ");
displayArr(nums);
结果如下:
还有一个应用是模拟跳方块舞的人。当
男男女女来到舞池, 他们按照自己的性别排成两队。 当舞池中有地方空出来时, 选两个队
列中的第一个人组成舞伴。 他们身后的人各自向前移动一位, 变成新的队首。 当一对舞伴
迈入舞池时, 主持人会大声喊出他们的名字。 当一对舞伴走出舞池, 且两排队伍中有任意
一队没人时, 主持人也会把这个情况告诉大家。实现代码如下:
//模拟方块舞
//舞者信息
var dancerInfo=["F AA","M BB","F CC","M DD","F EE","M FF","M GG"];
//将舞者信息存储在对象中,并将对象存入队列中
function Dancer(name,sex){
this.name=name;
this.sex=sex;
}
function getDancer(maleDancers,femaleDancers) {
for(var i=0;i<dancerInfo.length;++i){
var info=dancerInfo[i].split(" ");
var sex=info[0];
var name=info[1];
if(sex=='F'){
femaleDancers.enqueue(new Dancer(name,sex));
}else{
maleDancers.enqueue(new Dancer(name,sex));
}
}
}
//分配舞伴
function dance(males,females){
// console.log(males);
// console.log(females);
console.log("The dance partners are: \n");
while(!males.empty() && !females.empty()){
var fperson=females.dequeue();
console.log("Female dancer is: " + fperson.name);
var mperson = males.dequeue();
console.log("and the male dancer is: " + mperson.name);
}
}
//测试
var maleDancer=new Queue();
var femaleDancer=new Queue();
getDancer(maleDancer,femaleDancer);
dance(maleDancer,femaleDancer);
if(!femaleDancer.empty()){
console.log(femaleDancer.front().name+" is waiting to dance.");
}
if (!maleDancer.empty()) {
console.log(maleDancer.front().name + " is waiting to dance.");
}
结果如下: