众所周知,队列在我们的生活中很是常见,比如餐厅排队打饭,医院排队打疫苗等等;正是因为队列在生活中无处不在,所以我们也有必要去了解一下队列在我们前端领域的应用,这样我们才能利用队列去解决生活中常见的问题,下面让我们一起来探讨一下队列吧!
所谓队列,其遵循先进先出,后进后出的原则,即FIFO(first in first out)。
以上为数据入队出队的整个过程,由此可见,第一个入对的元素在出队时也是第一个出队的,既然图已经画出来了,那么我们可以很轻松的根据图解来手写实现一下队列的整个实现过程。
这里我们还用数组来实现队列,首先队列也是分情况的,它可以分为正常队列和优先级队列。
说到这里我想先问一下大家---为什么要把构造函数的方法放到原型对象上,直接在函数内部声明不行吗?
我们知道,函数上自带【prototype】属性,prototype上的【方法、属性】可被构造函数实例共享;对象上自带【__proto__】属性,指向其构造函数prototype,但在对象上找【属性、方法】找不到时,会通过__proto__继续,一级级往上找,直到找到或__proto__指向是null为止
1.每次通过new 关键字创建一个实例对象时,会return一个全新的【相互独立】对象,即其构造函数上定义属性和方法,在每个实例对象深拷贝一份,放在不同内存空间;
2.实际上很多时候,我们只需要实例对象属性是独立,方法是共享;
3.如果相同方法在每个实例对象上都重新定义一次,太浪费内存。所以把共享部分提出来,只定义一次,放在共享空间,而每个实例对象只需要一个指针指向共享空间。这个指针就是每个对象上的__proto__,共享空间就是对象的构造函数上的prototype上的属性方法占用的内存空间
明白了吗?明白之后下面正式进入正题
1.正常队列:
代码实现
// 创建一个队列函数
function Queue() {
// 用一个数组来存储队列元素
this.items = []
// 入队
Queue.prototype.enqueue = function (val) {
this.items.push(val)
}
// 出队
Queue.prototype.dequeue = function () {
return this.items.shift()
}
// 当前队列的大小
Queue.prototype.size = function () {
return this.items.length
}
// 当前队列是否为空
Queue.prototype.isEmpty = function () {
return this.items.length === 0
}
// 遍历队列中的元素
Queue.prototype.toString = function () {
return this.items.join(' ')
}
}
使用队列:
//创建实例
var queue = new Queue()
// 入队五个元素
queue.enqueue(1)
queue.enqueue(2)
queue.enqueue(3)
queue.enqueue(4)
queue.enqueue(5)
queue.enqueue(6)
// 当前队列的大小
console.log(queue.size()); //6
// 当前队列是否为空
console.log(queue.isEmpty()); //false
// 遍历队列中的元素
console.log(queue.toString()); //1 2 3 4 5 6
// 出队
console.log(queue.dequeue(1)); //1 ==>1 出队
console.log(queue.dequeue(2)); //2 ==>2 出队
console.log(queue.dequeue(3)); //3 ==>3 出队
// 遍历队列中的元素
console.log(queue.toString()); //4 5 6
2.优先级队列:
代码实现
// 声明一个优先级队列函数
function PriorityQueue() {
// 用一个数组来存储队列元素
this.items = []
// 声明一个函数用于存储值和优先级
function PriorityItems(element, priority) {
this.element = element
this.priority = priority
}
// 入队
PriorityQueue.prototype.enqueue = function (element, priority) {
var enqueueItem = new PriorityItems(element, priority)
if (this.isEmpty()) {
this.items.push(enqueueItem)
} else {
var flag = false
for (var i = 0; i < this.size(); i++) {
// 优先级越小的越排在前面
if (this.items[i].priority > enqueueItem.priority) {
this.items.splice(i, 0, enqueueItem)
flag = true
break
}
}
// 如果队列没有改变说明该值最大,直接插入到后面
if (!flag) this.items.push(enqueueItem)
}
}
// 出队
PriorityQueue.prototype.dequeue = function () {
return this.items.shift()
}
// 当前队列的大小
PriorityQueue.prototype.size = function () {
return this.items.length
}
// 当前队列是否为空
PriorityQueue.prototype.isEmpty = function () {
return this.items.length === 0
}
// 遍历队列中的元素
PriorityQueue.prototype.toString = function () {
var strResult = ''
for (var i = 0; i < this.size(); i++) {
strResult += this.items[i].element + ' '
}
return strResult
}
}
使用优先级队列:
// 创建函数实例
var priorityQueue = new PriorityQueue()
// 入队
priorityQueue.enqueue('kobe', 100)
priorityQueue.enqueue('John', 50)
priorityQueue.enqueue('Tom', 200)
priorityQueue.enqueue('Sam', 300)
// 当前队列的大小
console.log(priorityQueue.size()); //4
// 当前队列是否为空
console.log(priorityQueue.isEmpty()); //false
// 遍历队列中的元素
console.log(priorityQueue.toString()); //John kobe Tom Sam
// 出队
console.log(priorityQueue.dequeue('John', 50)); //PriorityItems {element: 'John', priority: 50}
console.log(priorityQueue.dequeue('Tom', 200)); //PriorityItems {element: 'kobe', priority: 100}
// 遍历队列中的元素
console.log(priorityQueue.toString()); //Tom Sam
以上就是队列的简单实现过程,你学废了吗?