受限的线性结构
1.其中一种栈结构,这种受限的数据结构对于解决某些特定问题,会有特别的效果.
队列
- 它是一种受限的线性表,先进先出(FIFO First In First Out)
- 受限之处在于它只允许在表的前端(front)进行删除操作
- 而在表的后端(rear)进行插入操作
举例
- 打印队列:
- 有五份文档需要打印,这些文档会按照次序放入到打印队列中
- 打印机会依次从队列中取出文档,优先放入的文档,优先被取出,并且对该文档进行打印
- 以此类推,直到队列中不再有新的文档.
- 线程队列:
- 在开发中,为了让任务可以并行处理,通常会开启多个线程口
- 但是,我们不能让大量的线程同时运行处理任务.(占用过多的资源)
- 这个时候,如果有需要开启线程处理任务的情况,我们就会使用线程队列
- 线程队列会依照次序来启动线程,并且处理对应的任务
队列类的创建
- 队列的实现和栈一样,有两种方案:
- 基于数组实现
- 基于链表实现
队列的常见操作
- 队列有哪些常见的操作呢?
- enqueue(element) : 向队列尾部添加一个( 或多个 )新的项。
- dequeue(): 移除队列的第一( 即排在队列最前面的 )项,并返回被移除的元素.
- front(): 返回队列中第一个元素一最先被添加,也将是最先被移除的元素。队列不做任何变动( 不移除元素只返回元素信息一与Stack类的peek方法非常类似 )。
- isEmpty0 :如果队列中不包含任何元素,返回true,否则返回false。
- size( : 返回队列包含的元素个数,与数组的length属性类似。
- toString0:将队列中的内容, 转成字符串形式
<script>
function Queue() {
this.arr = []
//将元素加入到队列中
Stack.prototype.push = function (ele) {
this.arr.push(ele)
}
//从队列中删除前端数据
Stack.prototype.dequeue = function () {
return this.arr.shift() //返会的就是最后一个元素
}
//查看前端的元素
Stack.prototype.front = function () {
return this.arr[0]
}
//查看队列是否为空
Stack.prototype.isEmpty = function () {
return this.arr.length == 0
}
//查看队列中的元素的个数
Stack.prototype.size = function () {
return this.arr.length
}
//toString()方法
Stack.prototype.toString = function () {
var objstring = ''
for (let i = 0; i < this.arr.length; i++) {
objstring += this.arr[i] + ' '
}
return objstring
}
}
let a = new Queue()
a.enqueue('abc')
a.enqueue('cbd')
a.enqueue('nmf')
alert(a) //添加
a.dequeue() //删除第一个进入栈的元素
//front方法
alert(a.front())
//验证其他方法
alert(a.isEmpty())
alert(a.size())
</script>
常见的击鼓传花面试题
- 击鼓传花是一个常见的面试算法题.使用队列可以非常方便的实现最终的结果
- 原游戏规则:
- 班级中玩一个游戏,所有学生围成一圈,从某位同学手里开始向旁边的同学传一束花
- 这个时候某个人(比如班长),在击鼓,鼓声停下的一颗,花落在谁手里,谁就出来表演节目
- 修改游戏规则:
- 我们来修改一下这个游戏规则
- 几个朋友一起玩一个游戏,围成一圈,开始数数,数到某个数字的人自动淘汰
- 最后剩下的这个人会获得胜利, 请问最后剩下的是原来在哪一个位置上的人?
- 封装一个基于队列的函数
- 参数: 所有参与人的姓名,基于的数字
- 结果: 最终剩下的一人的姓名
//面试题:击鼓传花
function passGame(nameList, num) {
//1. 创建一个队列结构
var queue = new Queue()
//2. 将所有人加入到队列中
for (let i = 0; i < nameList.length; i++) {
queue.enqueue(nameList[i])
}
//3. 开始数数字
while (queue.size() > 1) {
//不熟num的时候,重新加入到队列的末尾
//是num这个数字的时候,将其从队列中删除
//3.1.num数字之前的人重新放入到队列的末尾
for (let i = 0; i < num - 1; i++) {
queue.enqueue(queue.dequeue())
}
//3.2.num对应这个人,直接从队列中删除掉
queue.dequeue()
}
//4.获取剩下的那个人
alert(queue.size())
var endName = queue.front()
alert('最终剩下的人:' + endName)
return nameList.indexOf(endName)
}
//测试
names=['ony','tom','why','lilel','lily']
alert(passGame(names,3)