Deque 双端队列结构
双端队列(Double-Ended Queue)是一种具有队列和栈的性质的数据结构。双端队列中的元素可以从头尾两端进行操作(入队和出队)
WARNING
特点:可以看作是两个 Stack 结构组成的 Queue 结构
封装思路
head =>出队 操作时与Queue操作相同,入队 操作时需要判断:
1.为空则等同于在尾部入队;
2.#head>0则#head-1后插入;
3.若都不满足则需要把所有元素的key值+1,再在头部插入元素
1.为空则等同于在尾部入队;
2.#head>0则#head-1后插入;
3.若都不满足则需要把所有元素的key值+1,再在头部插入元素
last =>入队 操作时与Queue操作相同,出队 操作时#last-1即可
js
class Deque {
#items;
#head = 0;
#last = 0;
constructor(items = {}) {
this.#items = items;
}
// 与Queue相同
removeFront() {
if (this.isEmpty()) return;
const val = this.#items[this.#head];
delete this.#items[this.#head];
this.#head++;
return val;
}
removeEnd() {
if (this.isEmpty()) return;
this.#last--;
const val = this.#items[this.#last];
delete this.#items[this.#last];
return val;
}
addFront(data) {
// 1.如果队列为空
if (this.isEmpty()) {
this.addEnd(data);
return;
}
// 2.如果刚从队头删除完元素(即 #head > 0),则可在删除的位置加入
if (this.#head > 0) {
this.#head--;
this.#items[this.#head] = data;
return;
}
// 3.如果没有进行任何删除操作,则需要把所有元素往后移一位
for (let i = this.#last; i > 0; i--) {
this.#items[i] = this.#items[i - 1];
}
this.#items[this.#head] = data;
this.#last++;
}
// 与Queue相同
addEnd(data) {
this.#items[this.#last] = data;
this.#last++;
}
peekFront() {
return this.#items[this.#head];
}
peekEnd() {
return this.#items[this.#last - 1];
}
isEmpty() {
return this.size() === 0;
}
size() {
return this.#last - this.#head;
}
clear() {
this.#items = {};
}
toString() {
let str = "";
Object.keys(this.#items).forEach((item) => {
str += this.#items[item];
});
return str;
}
}
class Deque {
#items;
#head = 0;
#last = 0;
constructor(items = {}) {
this.#items = items;
}
// 与Queue相同
removeFront() {
if (this.isEmpty()) return;
const val = this.#items[this.#head];
delete this.#items[this.#head];
this.#head++;
return val;
}
removeEnd() {
if (this.isEmpty()) return;
this.#last--;
const val = this.#items[this.#last];
delete this.#items[this.#last];
return val;
}
addFront(data) {
// 1.如果队列为空
if (this.isEmpty()) {
this.addEnd(data);
return;
}
// 2.如果刚从队头删除完元素(即 #head > 0),则可在删除的位置加入
if (this.#head > 0) {
this.#head--;
this.#items[this.#head] = data;
return;
}
// 3.如果没有进行任何删除操作,则需要把所有元素往后移一位
for (let i = this.#last; i > 0; i--) {
this.#items[i] = this.#items[i - 1];
}
this.#items[this.#head] = data;
this.#last++;
}
// 与Queue相同
addEnd(data) {
this.#items[this.#last] = data;
this.#last++;
}
peekFront() {
return this.#items[this.#head];
}
peekEnd() {
return this.#items[this.#last - 1];
}
isEmpty() {
return this.size() === 0;
}
size() {
return this.#last - this.#head;
}
clear() {
this.#items = {};
}
toString() {
let str = "";
Object.keys(this.#items).forEach((item) => {
str += this.#items[item];
});
return str;
}
}
举例:判断回文
js
/**
* @param {String} str:要判断的字符串
*/
function check(str) {
const formatStr = str.toLowerCase().split(" ").join("");
const deque = new Deque();
Array.from(formatStr).forEach((str) => {
deque.addEnd(str);
});
let isEuqal = true;
while (deque.size() > 1) {
if (deque.removeFront() !== deque.removeEnd()) {
isEuqal = false;
break;
}
}
return isEuqal;
}
/**
* @param {String} str:要判断的字符串
*/
function check(str) {
const formatStr = str.toLowerCase().split(" ").join("");
const deque = new Deque();
Array.from(formatStr).forEach((str) => {
deque.addEnd(str);
});
let isEuqal = true;
while (deque.size() > 1) {
if (deque.removeFront() !== deque.removeEnd()) {
isEuqal = false;
break;
}
}
return isEuqal;
}
TIP
尽管双端队列看起来似乎比栈和队列更灵活,但实际上在应用程序中远不及栈和队列有用