>[success] # 实现一个双端队列
~~~
1.双端队列(deque,或称 double-ended queue)是一种允许我们同时从前端和后端添加和移除
元素的特殊队列
2.由于双端队列同时遵守了先进先出和后进先出原则,可以说它是把队列和栈相结合的一种数据结构
~~~
* 图解
![](https://img.kancloud.cn/15/de/15de4e4c094f2ec9fc34f0f1cc870cc6_675x167.png)
>[danger] ##### 双端队列封装需要的方法
~~~
1.addFront(element):该方法在双端队列前端添加新的元素。
2.addBack(element):该方法在双端队列后端添加新的元素(实现方法和 Queue 类中的enqueue 方法相同)。
3.removeFront():该方法会从双端队列前端移除第一个元素(实现方法和 Queue 类中的dequeue 方法相同)。
4.removeBack():该方法会从双端队列后端移除第一个元素(实现方法和 Stack 类中的pop 方法一样)。
5.peekFront():该方法返回双端队列前端的第一个元素(实现方法和 Queue 类中的 peek方法一样)。
6.peekBack():该方法返回双端队列后端的第一个元素(实现方法和 Stack 类中的 peek方法一样)。
~~~
>[danger] ##### 代码实现
~~~
// 需要两个标记符号 记录队头 和 队伍尾
// 需要可以有增删改查
class Deque{
constructor(){
this.items = {}
this.count = 0 // 记录末尾
this.lowestCount = 0 // 记录头部
}
size(){
return this.count - this.lowestCount
}
isEmpty(){
return this.size === 0
}
/*
向头部添加有三种情况
1.当数据为空的时候相当于是在尾部添加
2.当头部数据索引元素大于0时候 正常向头部添加重新记录头部位置
3.当头部数据索引为0的时候就需要移动元素留出0索引
*/
addFront(ele){
if(this.isEmpty()){
this.addBack(ele)
}else if(this.lowestCount>0){
// 先-- 往当前的lowestCount 标记的前一位加
this.lowestCount --
this.items[this.lowestCount] = ele
}else{
// 反向循环
for(let i = this.count;i>0;i--){
this.items[i] = this.items[i-1]
}
// 移位后要更新新的尾部指针
this.count++
this.items[0] = ele
}
}
// 向末尾添加数据
addBack(ele){
this.items[this.count] = ele
this.count ++
}
// 移除队伍头部元素
removeFront(){
if(this.isEmpty()){
return undefined
}
const res = this.items[this.lowestCount]
delete this.items[this.lowestCount]
this.lowestCount ++
return res
}
// 移除队伍尾部
removeBack() {
if (this.isEmpty()) {
return undefined;
}
this.count--;
const result = this.items[this.count];
delete this.items[this.count];
return result;
}
// 返回头部元素
peekFront() {
if (this.isEmpty()) {
return undefined;
}
return this.items[this.lowestCount];
}
// 返回尾部元素
peekBack() {
if (this.isEmpty()) {
return undefined;
}
return this.items[this.count - 1];
}
// 重置
clear() {
this.items = {};
this.count = 0;
this.lowestCount = 0;
}
toString() {
if (this.isEmpty()) {
return '';
}
let objString = `${this.items[this.lowestCount]}`;
for (let i = this.lowestCount + 1; i < this.count; i++) {
objString = `${objString},${this.items[i]}`;
}
return objString;
}
}
~~~
* 使用
~~~
const deque = new Deque();
deque.addBack('John');
deque.addBack('Jack');
deque.removeFront();
deque.removeBack();
deque.addFront('wang');
deque.addFront('wang');
// 打印结果:
{0: "wang", 1: "wang"}
~~~
>[info] ## 回文检查
~~~
1.利用双端队列首位都可以进出的原则
~~~
>[danger] ##### 代码
~~~
export function palindromeChecker(aString) {
if (
aString === undefined
|| aString === null
|| (aString !== null && aString.length === 0)
) {
return false;
}
const deque = new Deque();
const lowerString = aString.toLocaleLowerCase().split(' ').join('');
let firstChar;
let lastChar;
for (let i = 0; i < lowerString.length; i++) {
deque.addBack(lowerString.charAt(i));
}
while (deque.size() > 1) {
firstChar = deque.removeFront();
lastChar = deque.removeBack();
if (firstChar !== lastChar) {
return false;
}
}
return true;
}
~~~
* 运行 下面打印都为true
~~~
console.log('a', palindromeChecker('a'));
console.log('aa', palindromeChecker('aa'));
console.log('kayak', palindromeChecker('kayak'));
console.log('level', palindromeChecker('level'));
console.log('Was it a car or a cat I saw', palindromeChecker('Was it a car
or a cat I saw'));
console.log('Step on no pets', palindromeChecker('Step on no pets'));
~~~
>[danger] ##### 总结
~~~
1.也可以用已知的api 来做这道题
~~~
~~~
var isPalindrome = function(x) {
if ( x < 0 ) return false
let str = '' + x // 转成字符串类型
return Array.from(str).reverse().join('') === str
};
~~~
- 接触数据结构和算法
- 数据结构与算法 -- 大O复杂度表示法
- 数据结构与算法 -- 时间复杂度分析
- 最好、最坏、平均、均摊时间复杂度
- 基础数据结构和算法
- 线性表和非线性表
- 结构 -- 数组
- JS -- 数组
- 结构 -- 栈
- JS -- 栈
- JS -- 栈有效圆括号
- JS -- 汉诺塔
- 结构 -- 队列
- JS -- 队列
- JS -- 双端队列
- JS -- 循环队列
- 结构 -- 链表
- JS -- 链表
- JS -- 双向链表
- JS -- 循环链表
- JS -- 有序链表
- 结构 -- JS 字典
- 结构 -- 散列表
- 结构 -- js 散列表
- 结构 -- js分离链表
- 结构 -- js开放寻址法
- 结构 -- 递归
- 结构 -- js递归经典问题
- 结构 -- 树
- 结构 -- js 二搜索树
- 结构 -- 红黑树
- 结构 -- 堆
- 结构 -- js 堆
- 结构 -- js 堆排序
- 结构 -- 排序
- js -- 冒泡排序
- js -- 选择排序
- js -- 插入排序
- js -- 归并排序
- js -- 快速排序
- js -- 计数排序
- js -- 桶排序
- js -- 基数排序
- 结构 -- 算法
- 搜索算法
- 二分搜索
- 内插搜索
- 随机算法
- 简单
- 第一题 两数之和
- 第七题 反转整数
- 第九题 回文数
- 第十三题 罗马数字转整数
- 常见一些需求
- 把原始 list 转换成树形结构