mirror of
				https://github.com/krahets/hello-algo.git
				synced 2025-11-04 14:18:20 +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:
		
							
								
								
									
										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"
 | 
			
		||||
 | 
			
		||||
    ```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 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"
 | 
			
		||||
@ -393,13 +457,255 @@ comments: true
 | 
			
		||||
=== "JavaScript"
 | 
			
		||||
 | 
			
		||||
    ```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 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"
 | 
			
		||||
 | 
			
		||||
		Reference in New Issue
	
	Block a user