mirror of
https://github.com/krahets/hello-algo.git
synced 2024-12-26 13:26:29 +08:00
Add linkedlist_deque for typescript and javascript (#326)
* add linkedlist_deque for typescript and javascript * update typescript and javascript examples for the deque.md * keep the same name * update the doc * Update deque.md --------- Co-authored-by: steak-zhuo <zhuoqinyue@gmail.com> Co-authored-by: Yudong Jin <krahets@163.com>
This commit is contained in:
parent
bc88e52955
commit
c4b510038c
3 changed files with 640 additions and 2 deletions
166
codes/javascript/chapter_stack_and_queue/linkedlist_deque.js
Normal file
166
codes/javascript/chapter_stack_and_queue/linkedlist_deque.js
Normal file
|
@ -0,0 +1,166 @@
|
||||||
|
/**
|
||||||
|
* File: linkedlist_deque.js
|
||||||
|
* Created Time: 2023-02-04
|
||||||
|
* Author: Zhuo Qinyue (1403450829@qq.com)
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* 双向链表结点 */
|
||||||
|
class ListNode {
|
||||||
|
prev; // 前驱结点引用 (指针)
|
||||||
|
next; // 后继结点引用 (指针)
|
||||||
|
val; // 结点值
|
||||||
|
|
||||||
|
constructor(val) {
|
||||||
|
this.val = val;
|
||||||
|
this.next = null;
|
||||||
|
this.prev = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 基于双向链表实现的双向队列 */
|
||||||
|
class LinkedListDeque {
|
||||||
|
front; // 头结点 front
|
||||||
|
rear; // 尾结点 rear
|
||||||
|
len; // 双向队列的长度
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
this.front = null;
|
||||||
|
this.rear = null;
|
||||||
|
this.len = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 队尾入队操作 */
|
||||||
|
pushLast(val) {
|
||||||
|
const node = new ListNode(val);
|
||||||
|
// 若链表为空,则令 front, rear 都指向 node
|
||||||
|
if (this.len === 0) {
|
||||||
|
this.front = node;
|
||||||
|
this.rear = node;
|
||||||
|
} else {
|
||||||
|
// 将 node 添加至链表尾部
|
||||||
|
this.rear.next = node;
|
||||||
|
node.prev = this.rear;
|
||||||
|
this.rear = node; // 更新尾结点
|
||||||
|
}
|
||||||
|
this.len++;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 队首入队操作 */
|
||||||
|
pushFirst(val) {
|
||||||
|
const node = new ListNode(val);
|
||||||
|
// 若链表为空,则令 front, rear 都指向 node
|
||||||
|
if (this.len === 0) {
|
||||||
|
this.front = node;
|
||||||
|
this.rear = node;
|
||||||
|
} else {
|
||||||
|
// 将 node 添加至链表头部
|
||||||
|
this.front.prev = node;
|
||||||
|
node.next = this.front;
|
||||||
|
this.front = node; // 更新头结点
|
||||||
|
}
|
||||||
|
this.len++;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 队尾出队操作 */
|
||||||
|
pollLast() {
|
||||||
|
if (this.len === 0) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
const value = this.rear.val; // 存储尾结点值
|
||||||
|
// 删除尾结点
|
||||||
|
let temp = this.rear.prev;
|
||||||
|
if (temp !== null) {
|
||||||
|
temp.next = null;
|
||||||
|
this.rear.prev = null;
|
||||||
|
}
|
||||||
|
this.rear = temp; // 更新尾结点
|
||||||
|
this.len--;
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 队首出队操作 */
|
||||||
|
pollFirst() {
|
||||||
|
if (this.len === 0) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
const value = this.front.val; // 存储尾结点值
|
||||||
|
// 删除头结点
|
||||||
|
let temp = this.front.next;
|
||||||
|
if (temp !== null) {
|
||||||
|
temp.prev = null;
|
||||||
|
this.front.next = null;
|
||||||
|
}
|
||||||
|
this.front = temp; // 更新头结点
|
||||||
|
this.len--;
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 访问队尾元素 */
|
||||||
|
peekLast() {
|
||||||
|
return this.len === 0 ? null : this.rear.val;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 访问队首元素 */
|
||||||
|
peekFirst() {
|
||||||
|
return this.len === 0 ? null : this.front.val;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 获取双向队列的长度 */
|
||||||
|
size() {
|
||||||
|
return this.len;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 判断双向队列是否为空 */
|
||||||
|
isEmpty() {
|
||||||
|
return this.len === 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 打印双向队列 */
|
||||||
|
print() {
|
||||||
|
const arr = [];
|
||||||
|
let temp = this.front;
|
||||||
|
while (temp !== null) {
|
||||||
|
arr.push(temp.val);
|
||||||
|
temp = temp.next;
|
||||||
|
}
|
||||||
|
console.log("[" + arr.join(", ") + "]");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 初始化双向队列 */
|
||||||
|
const linkedListDeque = new LinkedListDeque();
|
||||||
|
linkedListDeque.pushLast(3);
|
||||||
|
linkedListDeque.pushLast(2);
|
||||||
|
linkedListDeque.pushLast(5);
|
||||||
|
console.log("双向队列 linkedListDeque = ");
|
||||||
|
linkedListDeque.print();
|
||||||
|
|
||||||
|
/* 访问元素 */
|
||||||
|
const peekFirst = linkedListDeque.peekFirst();
|
||||||
|
console.log("队首元素 peekFirst = " + peekFirst);
|
||||||
|
const peekLast = linkedListDeque.peekLast();
|
||||||
|
console.log("队尾元素 peekLast = " + peekLast);
|
||||||
|
|
||||||
|
/* 元素入队 */
|
||||||
|
linkedListDeque.pushLast(4);
|
||||||
|
console.log("元素 4 队尾入队后 linkedListDeque = ");
|
||||||
|
linkedListDeque.print();
|
||||||
|
linkedListDeque.pushFirst(1);
|
||||||
|
console.log("元素 1 队首入队后 linkedListDeque = ");
|
||||||
|
linkedListDeque.print();
|
||||||
|
|
||||||
|
/* 元素出队 */
|
||||||
|
const pollLast = linkedListDeque.pollLast();
|
||||||
|
console.log("队尾出队元素 = " + pollLast + ",队尾出队后 linkedListDeque = ");
|
||||||
|
linkedListDeque.print();
|
||||||
|
const pollFirst = linkedListDeque.pollFirst();
|
||||||
|
console.log("队首出队元素 = " + pollFirst + ",队首出队后 linkedListDeque = ");
|
||||||
|
linkedListDeque.print();
|
||||||
|
|
||||||
|
/* 获取双向队列的长度 */
|
||||||
|
const size = linkedListDeque.size();
|
||||||
|
console.log("双向队列长度 size = " + size);
|
||||||
|
|
||||||
|
/* 判断双向队列是否为空 */
|
||||||
|
const isEmpty = linkedListDeque.isEmpty();
|
||||||
|
console.log("双向队列是否为空 = " + isEmpty);
|
166
codes/typescript/chapter_stack_and_queue/linkedlist_deque.ts
Normal file
166
codes/typescript/chapter_stack_and_queue/linkedlist_deque.ts
Normal file
|
@ -0,0 +1,166 @@
|
||||||
|
/**
|
||||||
|
* File: linkedlist_deque.ts
|
||||||
|
* Created Time: 2023-02-04
|
||||||
|
* Author: Zhuo Qinyue (1403450829@qq.com)
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* 双向链表结点 */
|
||||||
|
class ListNode {
|
||||||
|
prev: ListNode; // 前驱结点引用 (指针)
|
||||||
|
next: ListNode; // 后继结点引用 (指针)
|
||||||
|
val: number; // 结点值
|
||||||
|
|
||||||
|
constructor(val: number) {
|
||||||
|
this.val = val;
|
||||||
|
this.next = null;
|
||||||
|
this.prev = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 基于双向链表实现的双向队列 */
|
||||||
|
class LinkedListDeque {
|
||||||
|
front: ListNode; // 头结点 front
|
||||||
|
rear: ListNode; // 尾结点 rear
|
||||||
|
len: number; // 双向队列的长度
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
this.front = null;
|
||||||
|
this.rear = null;
|
||||||
|
this.len = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 队尾入队操作 */
|
||||||
|
pushLast(val: number): void {
|
||||||
|
const node: ListNode = new ListNode(val);
|
||||||
|
// 若链表为空,则令 front, rear 都指向 node
|
||||||
|
if (this.len === 0) {
|
||||||
|
this.front = node;
|
||||||
|
this.rear = node;
|
||||||
|
} else {
|
||||||
|
// 将 node 添加至链表尾部
|
||||||
|
this.rear.next = node;
|
||||||
|
node.prev = this.rear;
|
||||||
|
this.rear = node; // 更新尾结点
|
||||||
|
}
|
||||||
|
this.len++;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 队首入队操作 */
|
||||||
|
pushFirst(val: number): void {
|
||||||
|
const node: ListNode = new ListNode(val);
|
||||||
|
// 若链表为空,则令 front, rear 都指向 node
|
||||||
|
if (this.len === 0) {
|
||||||
|
this.front = node;
|
||||||
|
this.rear = node;
|
||||||
|
} else {
|
||||||
|
// 将 node 添加至链表头部
|
||||||
|
this.front.prev = node;
|
||||||
|
node.next = this.front;
|
||||||
|
this.front = node; // 更新头结点
|
||||||
|
}
|
||||||
|
this.len++;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 队尾出队操作 */
|
||||||
|
pollLast(): number {
|
||||||
|
if (this.len === 0) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
const value: number = this.rear.val; // 存储尾结点值
|
||||||
|
// 删除尾结点
|
||||||
|
let temp: ListNode = this.rear.prev;
|
||||||
|
if (temp !== null) {
|
||||||
|
temp.next = null;
|
||||||
|
this.rear.prev = null;
|
||||||
|
}
|
||||||
|
this.rear = temp; // 更新尾结点
|
||||||
|
this.len--;
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 队首出队操作 */
|
||||||
|
pollFirst(): number {
|
||||||
|
if (this.len === 0) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
const value: number = this.front.val; // 存储尾结点值
|
||||||
|
// 删除头结点
|
||||||
|
let temp: ListNode = this.front.next;
|
||||||
|
if (temp !== null) {
|
||||||
|
temp.prev = null;
|
||||||
|
this.front.next = null;
|
||||||
|
}
|
||||||
|
this.front = temp; // 更新头结点
|
||||||
|
this.len--;
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 访问队尾元素 */
|
||||||
|
peekLast(): number {
|
||||||
|
return this.len === 0 ? null : this.rear.val;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 访问队首元素 */
|
||||||
|
peekFirst(): number {
|
||||||
|
return this.len === 0 ? null : this.front.val;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 获取双向队列的长度 */
|
||||||
|
size(): number {
|
||||||
|
return this.len;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 判断双向队列是否为空 */
|
||||||
|
isEmpty(): boolean {
|
||||||
|
return this.len === 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 打印双向队列 */
|
||||||
|
print(): void {
|
||||||
|
const arr: number[] = [];
|
||||||
|
let temp: ListNode = this.front;
|
||||||
|
while (temp !== null) {
|
||||||
|
arr.push(temp.val);
|
||||||
|
temp = temp.next;
|
||||||
|
}
|
||||||
|
console.log("[" + arr.join(", ") + "]");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 初始化双向队列 */
|
||||||
|
const linkedListDeque: LinkedListDeque = new LinkedListDeque();
|
||||||
|
linkedListDeque.pushLast(3);
|
||||||
|
linkedListDeque.pushLast(2);
|
||||||
|
linkedListDeque.pushLast(5);
|
||||||
|
console.log("双向队列 linkedListDeque = ");
|
||||||
|
linkedListDeque.print();
|
||||||
|
|
||||||
|
/* 访问元素 */
|
||||||
|
const peekFirst: number = linkedListDeque.peekFirst();
|
||||||
|
console.log("队首元素 peekFirst = " + peekFirst);
|
||||||
|
const peekLast: number = linkedListDeque.peekLast();
|
||||||
|
console.log("队尾元素 peekLast = " + peekLast);
|
||||||
|
|
||||||
|
/* 元素入队 */
|
||||||
|
linkedListDeque.pushLast(4);
|
||||||
|
console.log("元素 4 队尾入队后 linkedListDeque = ");
|
||||||
|
linkedListDeque.print();
|
||||||
|
linkedListDeque.pushFirst(1);
|
||||||
|
console.log("元素 1 队首入队后 linkedListDeque = ");
|
||||||
|
linkedListDeque.print();
|
||||||
|
|
||||||
|
/* 元素出队 */
|
||||||
|
const pollLast: number = linkedListDeque.pollLast();
|
||||||
|
console.log("队尾出队元素 = " + pollLast + ",队尾出队后 linkedListDeque = ");
|
||||||
|
linkedListDeque.print();
|
||||||
|
const pollFirst: number = linkedListDeque.pollFirst();
|
||||||
|
console.log("队首出队元素 = " + pollFirst + ",队首出队后 linkedListDeque = ");
|
||||||
|
linkedListDeque.print();
|
||||||
|
|
||||||
|
/* 获取双向队列的长度 */
|
||||||
|
const size: number = linkedListDeque.size();
|
||||||
|
console.log("双向队列长度 size = " + size);
|
||||||
|
|
||||||
|
/* 判断双向队列是否为空 */
|
||||||
|
const isEmpty: boolean = linkedListDeque.isEmpty();
|
||||||
|
console.log("双向队列是否为空 = " + isEmpty);
|
|
@ -149,13 +149,77 @@ comments: true
|
||||||
=== "JavaScript"
|
=== "JavaScript"
|
||||||
|
|
||||||
```js title="deque.js"
|
```js title="deque.js"
|
||||||
|
/* 初始化双向队列 */
|
||||||
|
// JavaScript 没有内置的双端队列,只能把 Array 当作双端队列来使用
|
||||||
|
const deque = [];
|
||||||
|
|
||||||
|
/* 元素入队 */
|
||||||
|
deque.push(2);
|
||||||
|
deque.push(5);
|
||||||
|
deque.push(4);
|
||||||
|
// 请注意,由于是数组,unshift() 方法的时间复杂度为 O(n)
|
||||||
|
deque.unshift(3);
|
||||||
|
deque.unshift(1);
|
||||||
|
console.log("双向队列 deque = ", deque);
|
||||||
|
|
||||||
|
/* 访问元素 */
|
||||||
|
const peekFirst = deque[0];
|
||||||
|
console.log("队首元素 peekFirst = " + peekFirst);
|
||||||
|
const peekLast = deque[deque.length - 1];
|
||||||
|
console.log("队尾元素 peekLast = " + peekLast);
|
||||||
|
|
||||||
|
/* 元素出队 */
|
||||||
|
// 请注意,由于是数组,shift() 方法的时间复杂度为 O(n)
|
||||||
|
const popFront = deque.shift();
|
||||||
|
console.log("队首出队元素 popFront = " + popFront + ",队首出队后 deque = " + deque);
|
||||||
|
const popBack = deque.pop();
|
||||||
|
console.log("队尾出队元素 popBack = " + popBack + ",队尾出队后 deque = " + deque);
|
||||||
|
|
||||||
|
/* 获取双向队列的长度 */
|
||||||
|
const size = deque.length;
|
||||||
|
console.log("双向队列长度 size = " + size);
|
||||||
|
|
||||||
|
/* 判断双向队列是否为空 */
|
||||||
|
const isEmpty = size === 0;
|
||||||
|
console.log("双向队列是否为空 = " + isEmpty);
|
||||||
```
|
```
|
||||||
|
|
||||||
=== "TypeScript"
|
=== "TypeScript"
|
||||||
|
|
||||||
```typescript title="deque.ts"
|
```typescript title="deque.ts"
|
||||||
|
/* 初始化双向队列 */
|
||||||
|
// TypeScript 没有内置的双端队列,只能把 Array 当作双端队列来使用
|
||||||
|
const deque: number[] = [];
|
||||||
|
|
||||||
|
/* 元素入队 */
|
||||||
|
deque.push(2);
|
||||||
|
deque.push(5);
|
||||||
|
deque.push(4);
|
||||||
|
// 请注意,由于是数组,unshift() 方法的时间复杂度为 O(n)
|
||||||
|
deque.unshift(3);
|
||||||
|
deque.unshift(1);
|
||||||
|
console.log("双向队列 deque = ", deque);
|
||||||
|
|
||||||
|
/* 访问元素 */
|
||||||
|
const peekFirst: number = deque[0];
|
||||||
|
console.log("队首元素 peekFirst = " + peekFirst);
|
||||||
|
const peekLast: number = deque[deque.length - 1];
|
||||||
|
console.log("队尾元素 peekLast = " + peekLast);
|
||||||
|
|
||||||
|
/* 元素出队 */
|
||||||
|
// 请注意,由于是数组,shift() 方法的时间复杂度为 O(n)
|
||||||
|
const popFront: number = deque.shift() as number;
|
||||||
|
console.log("队首出队元素 popFront = " + popFront + ",队首出队后 deque = " + deque);
|
||||||
|
const popBack: number = deque.pop() as number;
|
||||||
|
console.log("队尾出队元素 popBack = " + popBack + ",队尾出队后 deque = " + deque);
|
||||||
|
|
||||||
|
/* 获取双向队列的长度 */
|
||||||
|
const size: number = deque.length;
|
||||||
|
console.log("双向队列长度 size = " + size);
|
||||||
|
|
||||||
|
/* 判断双向队列是否为空 */
|
||||||
|
const isEmpty: boolean = size === 0;
|
||||||
|
console.log("双向队列是否为空 = " + isEmpty);
|
||||||
```
|
```
|
||||||
|
|
||||||
=== "C"
|
=== "C"
|
||||||
|
@ -393,13 +457,255 @@ comments: true
|
||||||
=== "JavaScript"
|
=== "JavaScript"
|
||||||
|
|
||||||
```js title="linkedlist_deque.js"
|
```js title="linkedlist_deque.js"
|
||||||
|
/* 双向链表结点 */
|
||||||
|
class ListNode {
|
||||||
|
prev; // 前驱结点引用 (指针)
|
||||||
|
next; // 后继结点引用 (指针)
|
||||||
|
val; // 结点值
|
||||||
|
|
||||||
|
constructor(val) {
|
||||||
|
this.val = val;
|
||||||
|
this.next = null;
|
||||||
|
this.prev = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 基于双向链表实现的双向队列 */
|
||||||
|
class LinkedListDeque {
|
||||||
|
front; // 头结点 front
|
||||||
|
rear; // 尾结点 rear
|
||||||
|
len; // 双向队列的长度
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
this.front = null;
|
||||||
|
this.rear = null;
|
||||||
|
this.len = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 队尾入队操作 */
|
||||||
|
pushLast(val) {
|
||||||
|
const node = new ListNode(val);
|
||||||
|
// 若链表为空,则令 front, rear 都指向 node
|
||||||
|
if (this.len === 0) {
|
||||||
|
this.front = node;
|
||||||
|
this.rear = node;
|
||||||
|
} else {
|
||||||
|
// 将 node 添加至链表尾部
|
||||||
|
this.rear.next = node;
|
||||||
|
node.prev = this.rear;
|
||||||
|
this.rear = node; // 更新尾结点
|
||||||
|
}
|
||||||
|
this.len++;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 队首入队操作 */
|
||||||
|
pushFirst(val) {
|
||||||
|
const node = new ListNode(val);
|
||||||
|
// 若链表为空,则令 front, rear 都指向 node
|
||||||
|
if (this.len === 0) {
|
||||||
|
this.front = node;
|
||||||
|
this.rear = node;
|
||||||
|
} else {
|
||||||
|
// 将 node 添加至链表头部
|
||||||
|
this.front.prev = node;
|
||||||
|
node.next = this.front;
|
||||||
|
this.front = node; // 更新头结点
|
||||||
|
}
|
||||||
|
this.len++;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 队尾出队操作 */
|
||||||
|
pollLast() {
|
||||||
|
if (this.len === 0) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
const value = this.rear.val; // 存储尾结点值
|
||||||
|
// 删除尾结点
|
||||||
|
let temp = this.rear.prev;
|
||||||
|
if (temp !== null) {
|
||||||
|
temp.next = null;
|
||||||
|
this.rear.prev = null;
|
||||||
|
}
|
||||||
|
this.rear = temp; // 更新尾结点
|
||||||
|
this.len--;
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 队首出队操作 */
|
||||||
|
pollFirst() {
|
||||||
|
if (this.len === 0) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
const value = this.front.val; // 存储尾结点值
|
||||||
|
// 删除头结点
|
||||||
|
let temp = this.front.next;
|
||||||
|
if (temp !== null) {
|
||||||
|
temp.prev = null;
|
||||||
|
this.front.next = null;
|
||||||
|
}
|
||||||
|
this.front = temp; // 更新头结点
|
||||||
|
this.len--;
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 访问队尾元素 */
|
||||||
|
peekLast() {
|
||||||
|
return this.len === 0 ? null : this.rear.val;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 访问队首元素 */
|
||||||
|
peekFirst() {
|
||||||
|
return this.len === 0 ? null : this.front.val;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 获取双向队列的长度 */
|
||||||
|
size() {
|
||||||
|
return this.len;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 判断双向队列是否为空 */
|
||||||
|
isEmpty() {
|
||||||
|
return this.len === 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 打印双向队列 */
|
||||||
|
print() {
|
||||||
|
const arr = [];
|
||||||
|
let temp = this.front;
|
||||||
|
while (temp !== null) {
|
||||||
|
arr.push(temp.val);
|
||||||
|
temp = temp.next;
|
||||||
|
}
|
||||||
|
console.log("[" + arr.join(", ") + "]");
|
||||||
|
}
|
||||||
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
=== "TypeScript"
|
=== "TypeScript"
|
||||||
|
|
||||||
```typescript title="linkedlist_deque.ts"
|
```typescript title="linkedlist_deque.ts"
|
||||||
|
/* 双向链表结点 */
|
||||||
|
class ListNode {
|
||||||
|
prev: ListNode; // 前驱结点引用 (指针)
|
||||||
|
next: ListNode; // 后继结点引用 (指针)
|
||||||
|
val: number; // 结点值
|
||||||
|
|
||||||
|
constructor(val: number) {
|
||||||
|
this.val = val;
|
||||||
|
this.next = null;
|
||||||
|
this.prev = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 基于双向链表实现的双向队列 */
|
||||||
|
class LinkedListDeque {
|
||||||
|
front: ListNode; // 头结点 front
|
||||||
|
rear: ListNode; // 尾结点 rear
|
||||||
|
len: number; // 双向队列的长度
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
this.front = null;
|
||||||
|
this.rear = null;
|
||||||
|
this.len = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 队尾入队操作 */
|
||||||
|
pushLast(val: number): void {
|
||||||
|
const node: ListNode = new ListNode(val);
|
||||||
|
// 若链表为空,则令 front, rear 都指向 node
|
||||||
|
if (this.len === 0) {
|
||||||
|
this.front = node;
|
||||||
|
this.rear = node;
|
||||||
|
} else {
|
||||||
|
// 将 node 添加至链表尾部
|
||||||
|
this.rear.next = node;
|
||||||
|
node.prev = this.rear;
|
||||||
|
this.rear = node; // 更新尾结点
|
||||||
|
}
|
||||||
|
this.len++;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 队首入队操作 */
|
||||||
|
pushFirst(val: number): void {
|
||||||
|
const node: ListNode = new ListNode(val);
|
||||||
|
// 若链表为空,则令 front, rear 都指向 node
|
||||||
|
if (this.len === 0) {
|
||||||
|
this.front = node;
|
||||||
|
this.rear = node;
|
||||||
|
} else {
|
||||||
|
// 将 node 添加至链表头部
|
||||||
|
this.front.prev = node;
|
||||||
|
node.next = this.front;
|
||||||
|
this.front = node; // 更新头结点
|
||||||
|
}
|
||||||
|
this.len++;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 队尾出队操作 */
|
||||||
|
pollLast(): number {
|
||||||
|
if (this.len === 0) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
const value: number = this.rear.val; // 存储尾结点值
|
||||||
|
// 删除尾结点
|
||||||
|
let temp: ListNode = this.rear.prev;
|
||||||
|
if (temp !== null) {
|
||||||
|
temp.next = null;
|
||||||
|
this.rear.prev = null;
|
||||||
|
}
|
||||||
|
this.rear = temp; // 更新尾结点
|
||||||
|
this.len--;
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 队首出队操作 */
|
||||||
|
pollFirst(): number {
|
||||||
|
if (this.len === 0) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
const value: number = this.front.val; // 存储尾结点值
|
||||||
|
// 删除头结点
|
||||||
|
let temp: ListNode = this.front.next;
|
||||||
|
if (temp !== null) {
|
||||||
|
temp.prev = null;
|
||||||
|
this.front.next = null;
|
||||||
|
}
|
||||||
|
this.front = temp; // 更新头结点
|
||||||
|
this.len--;
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 访问队尾元素 */
|
||||||
|
peekLast(): number {
|
||||||
|
return this.len === 0 ? null : this.rear.val;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 访问队首元素 */
|
||||||
|
peekFirst(): number {
|
||||||
|
return this.len === 0 ? null : this.front.val;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 获取双向队列的长度 */
|
||||||
|
size(): number {
|
||||||
|
return this.len;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 判断双向队列是否为空 */
|
||||||
|
isEmpty(): boolean {
|
||||||
|
return this.len === 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 打印双向队列 */
|
||||||
|
print(): void {
|
||||||
|
const arr: number[] = [];
|
||||||
|
let temp: ListNode = this.front;
|
||||||
|
while (temp !== null) {
|
||||||
|
arr.push(temp.val);
|
||||||
|
temp = temp.next;
|
||||||
|
}
|
||||||
|
console.log("[" + arr.join(", ") + "]");
|
||||||
|
}
|
||||||
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
=== "C"
|
=== "C"
|
||||||
|
|
Loading…
Reference in a new issue