在各种教材中,数据以及数据类型都是首先要讲的。在我看来数据以及数据类型是对问题的基本建模单元。
前端JavaScript基本数据类型:Undefined、Null、String、Number、Boolean。
然后是复合数据类型:Object。
前端乃至其他语言的数据结构:栈、队列、链表、散列、集合、字典、二叉树、图等。
在实际开发中,如果没有专门的数据结构学习。是有一些拍脑袋去解决问题的意思的,甚至说为了解决问题而解决问题。而数据结构的另一层意义是将问题的解决规范化、系统化。
鉴于我的开发经历以及对身边同学的了解,我认为系统学习数据结构非常有必要。
本篇讲一下数据结构队列的定义和使用。
// 队列是一种先入先出的数据结构
function Queue() {
// 数组缓存数据
this.dataStore = []
this.enqueue = function (element) {
this.dataStore.push(element)
}
this.dequeue = function () {
return this.dataStore.shift()
}
this.front = function () {
return this.dataStore[0]
}
this.back = function () {
return this.dataStore[this.dataStore.length - 1]
}
this.toString = function () {
let retStr = ''
for (let i = 0; i < this.dataStore.length; ++i) {
retStr += this.dataStore[i] + '
'
}
return retStr
}
this.getLength = function () {
return this.dataStore.length;
}
this.empty = function () {
return this.dataStore.length === 0
}
}
如果允许两端添加和删除元素就变成了双向队列。类增加以下两个方法。
this.addFront = function (element) {
this.dataStore.unshift(element)
}
this.removeBack = function () {
return this.dataStore.pop()
}
举两个使用队列的案例。
约瑟夫环:把0-99依次插入队列,然后从0开始每隔2个数删除一个数,到对尾时再返回到对头重新开始,判断最后一个元素是哪个。
function circle() {
var q = new Queue();
for (var i = 0; i < 100; i++) {
q.enqueue(i);
}
var index = 0;
while (q.getLength() > 1) {
var item = q.dequeue()
index++;
if (index % 3 !== 0) { //如果队列的下标不是3的倍数,就把它重新插入队尾
q.enqueue(item)
}
}
return q
}
(好吧这提为啥这么处理我还有疑问)
利用双向队列判断字符串是否为回文
function palindromeChecker(aString) {
if (!aString || typeof aString !== 'string' || !aString.trim().length) {
return false
}
const queue = new Queue()
const lowerString = aString.toLowerCase().split(' ').join('')
// 加入队列
for (let i = 0; i < lowerString.length; i++) {
queue.enqueue(lowerString[i])
}
let isEqual = true
let firstChar = ''
let lastChar = ''
console.log(queue, 'dd', aString)
while (queue.getLength() > 1 && isEqual) {
firstChar = queue.dequeue()
lastChar = queue.removeBack()
if (firstChar !== lastChar) {
isEqual = false
}
}
return isEqual
}
总结一下:大体上利用队列解决问题的,都是建立队列模型,然后主逻辑是遍历,然后分支逻辑是利用方法做一些判断。