1. 认识队列
-
队列结构
- 是一种常见的线性结构
- 其限制为今允许在表的一端进行插入操作,在表的另一端进行删除操作.
- 进行插入的一段称为队尾
- 进行删除的一段称为对头或队首
- 简单的一个队列结构如下图所示:
-
队列的特点
- 向队列中插入新的元素称为进队或入队,元素进队之后成为新的队尾元素
- 删除队列中的元素称为出队或离队,元素出队后,后继的元素直接成为队首元素
- 由于队列的掺入和删除操作分别在个子的一端进行,每个元素必然按照进入的次序出队,所以队列又叫先进先出表
-
生活中类似队列的案例
- 若干个人走过一个独木桥,先上桥的就会先下桥,这里的独木桥就是一个队列
- 排队买票的时候,先排队的人就会先买到票离开
2. 队列结构的实现
常见队列
首先封装一个类,来表示我们自己的队列
function Queue() {
this.items = []
//下面定义队列的常用方法
}
说明:
- 创建了一个
queue
构造函数,用来创建队列 - 在构造函数中定义了一个数组类型的变量,这个变量中用来存储当前队列中的所有元素
- 之后的关于列队的删除添加操作,都在这个数组中完成
队列的常用方法
enqueue(element)
:向队列尾部添加一个(或多个)新的项。dequeue()
:移除队列的第一(即排在队列最前面的)项,并返回被移除的元素。front()
:返回队列中第一个元素——最先被添加,也将是最先被移除的元素。队列不做任何变动(不移除元素,只返回元素信息——与Stack类的peek方法非常类似)。isEmpty()
:如果队列中不包含任何元素,返回true,否则返回false。size()
:返回队列包含的元素个数,与数组的length属性类似。toString()
: 将队列中的内容转成字符串形式
然后开始实现这些方法:
enqueue(element)
:向队列尾部添加一个(或多个)新的项。
Queue.prototype.enqueue = function(el) {
this.items.push(el);
}
dequeue()
:移除队列的第一(即排在队列最前面的)项,并返回被移除的元素。
Queue.prototype.dequeue = function() {
return this.items.shift();
}
– front()
:返回队列中第一个元素——最先被添加,也将是最先被移除的元素。队列不做任何变动(不移除元素,只返回元素信息——与Stack类的peek方法非常类似)。
Queue.prototype.font = function() {
return this.items[0]
}
isEmpty()
:如果队列中不包含任何元素,返回true,否则返回false。
Queue.prototype.isEmpty = function() {
return this.items.length === 0
}
size()
:返回队列包含的元素个数,与数组的length属性类似。
Queue.prototype.size = function() {
return this.items.length;
}
toString()
: 将队列中的内容转成字符串形式
Queue.prototype.toString = function() {
let res = '';
for(let i = 0 ; i < this.items.length ; i++) {
res += this.items[i] + ''
}
return res;
}
封装方法测试
//新建队列
var queue = new Queue();
//插入元素
queue.enqueue(1);
queue.enqueue(2);
queue.enqueue(3);
console.log(queue); //[1,2,3]
//删除队尾的元素
queue.dequeue();
console.log(queue); [2,3]
//查看队首元素
var a = queue.font()
console.log(a) //[2]
//判断队列是否为空
var b = queue.isEmpty()
console.log(b); //fasle
//查看队列长度
var c = queue.size();
console.log(c); //2
//转字符串
var d = queue.toString();
console.log(d) //'23'
3. 队列的笔试题
击鼓传花的规则
- 原游戏规则:
- 班级中玩一个游戏, 所有学生围成一圈, 从某位同学手里开始向旁边的同学传一束花.
- 这个时候某个人(比如班长), 在击鼓, 鼓声停下的一颗, 花落在谁手里, 谁就出来表演节目.
- 修改游戏规则:
- 几个朋友一起玩一个游戏, 围成一圈, 开始数数, 数到某个数字的人自动淘汰.
- 最后剩下的这个人会获得胜利, 请问最后剩下的是原来在哪一个位置上的人?
整个过程大致如下所示(名字红色的人被淘汰
):
大致思路:
- 函数需要两个参数,一个是名字的数组,另外一个就是一个确定的数字num
- 最后队列中只会剩下一个人
- 所以当队列的长度大于1的时候进行循环
- 从0到num开始循环队列中的元素,如果小于num,从队首删除,移入队尾
- 如果等于num,则删除该元素
- 重复上面的循环,直至队列长度为1
大致代码如下:
//函数接受两个参数,姓名的数组和数字num
function playGames(nameList,num) {
//创建一个队列
var queue = new Queue();
//将所有人的名字放在列表当中
for(var i = 0 ; i < nameList.length ; i++) {
queue.enqueue(nameList[i]);
}
//队列长度大于1开始循环
while(queue.size() > 1) {
//从0到num开始循环,如果不等于num,从队首删除,移入队尾
for(let i = 0 ; i < num ; i++) {
//删除队首
var a = queue.dequeue();
//队首元素进入队尾
queue.enqueue(a);
}
//等于num之后,删除该元素
queue.dequeue()
}
//检查队列长度
console.log(queue.size());
//查看最后剩下的人
var endName = queue.font();
return endName
}
调用函数,查看最后的结果:
var name = playGames( ['荣','贵','生','欢','宇','彭'],4);
console.log(name); //荣
输出的结果为荣
,和我们之前的分析结果一致