队列是一种特殊的线性表,特殊之处在于它只允许在表的前端(front)进行删除操作,而在表的后端(rear)进行插入操作,和栈一样,队列是一种操作受限制的线性表。进行插入操作的端称为队尾,进行删除操作的端称为队头。队列中没有元素时,称为空队列。
队列的数据元素又称为队列元素。在队列中插入一个队列元素称为入队,从队列中删除一个队列元素称为出队。因为队列只允许在一端插入,在另一端删除,所以只有最早进入队列的元素才能最先从队列中删除,故队列又称为先进先出(FIFO—first in first out)线性表。
在我们生活中有很多像队列的例子,比如说排队等等。
使用js封装队列
<script>
function Queue() {
//属性
this.items = [];
//方法
//向队列尾部添加一个或多个项
Queue.prototype.enqueue = function (ele) {
this.items.push(ele);
};
//移除队列中的第一项
Queue.prototype.dequeue = function () {
return this.items.shift()
};
//返回队列前端的元素
Queue.prototype.front = function () {
return this.items[0];
};
//判断队列是否为空
Queue.prototype.isEmpty = function () {
return this.items.length === 0;
};
//返回队列中的元素个数
Queue.prototype.size = function () {
return this.items.length;
};
//将队列中的内容转换成字符串形式
Queue.prototype.toString = function () {
let resultString = '';
for(let i=0;i<this.items.length;i++){
resultString += this.items[i] + " ";
}
return resultString;
}
}
let queue = new Queue();
queue.enqueue('abc');
queue.enqueue('nba');
queue.enqueue('cd');
console.log(queue);
</script>
封装队列与封装栈的不同方法在于移除首项和返回首项,因为栈是先进后出,而队列是先进先出,在栈中移除的是栈顶元素,也就是最后进入栈的一项,而在队列中移除是移除第一项,返回第一项。
使用队列解决约瑟夫环问题
约瑟夫斯环的规则是:有n个人,围在一起,规定一个具体的数字num,从1开始数数,数到num的人被淘汰,再从下一个继续从1开始数,数到num的人淘汰,以此循环,直到只剩下最后一个人时,游戏结束;
那么用队列如何解决这个问题呢?
现在有张,李,王,罗,陈五个人,首先规定一个数字3,数到3的人淘汰,从张开始数,不等于3的人就放到队列的后面,‘王’数到了3将其删除,下面从‘罗’开始继续从1开始数,以此循环,我们不难发现它的规律,只要将不等于num的数字从队列删除再放入队列尾部,等于num就直接从队列里面删除。
代码实现:
function passGame(nameList,num) {
//1.创建一个队列结构
let queue = new Queue();
//2.将数组里面的元素依次放入队列
for(let i=0;i<nameList.length;i++){
queue.enqueue(nameList[i]);
}
while (queue.size()>1){ //3.3当队列中不只有一个人的时候,要重复进行下面的操作
//3.1当数到的数字不为num时删除这些人,再将这些人放到队列的末尾,重新再进行数数
for (let j=0;j<num-1;j++){
queue.enqueue(queue.dequeue());
}
//3.2数到num时的人,从队列里面删除
queue.dequeue();
}
//取出最后一个人
let endName = queue.front();
alert("最终剩下的人:" + endName);
return nameList.indexOf(endName);
}
names = ['张','李','王','罗','陈'];
console.log(passGame(names, 3));
输出结果: