1 // Copyright Jerome Benoit. 2023. All Rights Reserved.
6 * @typeParam T - Type of node data.
14 public constructor (data
: T
) {
21 * Implemented with a doubly linked list.
23 * @typeParam T - Type of deque data.
26 export class Deque
<T
> {
27 private head
?: Node
<T
>
28 private tail
?: Node
<T
>
29 /** The size of the deque. */
31 /** The maximum size of the deque. */
32 public maxSize
!: number
34 public constructor () {
39 * Appends data to the deque.
41 * @param data - Data to append.
42 * @returns The new size of the queue.
44 public push (data
: T
): number {
45 const node
= new Node(data
)
46 if (this.tail
== null) {
47 this.head
= this.tail
= node
50 this.tail
= this.tail
.next
= node
52 return this.incrementSize()
56 * Prepends data to the deque.
58 * @param data - Data to prepend.
59 * @returns The new size of the queue.
61 public unshift (data
: T
): number {
62 const node
= new Node(data
)
63 if (this.head
== null) {
64 this.head
= this.tail
= node
67 this.head
= this.head
.prev
= node
69 return this.incrementSize()
73 * Pops data from the deque.
75 * @returns The popped data or `undefined` if the deque is empty.
77 public pop (): T
| undefined {
78 if (this.head
== null) {
81 const tail
= this.tail
82 // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
83 this.tail
= this.tail
!.prev
84 if (this.tail
== null) {
94 * Shifts data from the deque.
96 * @returns The shifted data or `undefined` if the deque is empty.
98 public shift (): T
| undefined {
99 if (this.head
== null) {
102 const head
= this.head
103 this.head
= this.head
.next
104 if (this.head
== null) {
107 delete this.head
.prev
114 * Peeks at the first data.
115 * @returns The first data or `undefined` if the deque is empty.
117 public peekFirst (): T
| undefined {
118 return this.head
?.data
122 * Peeks at the last data.
123 * @returns The last data or `undefined` if the deque is empty.
125 public peekLast (): T
| undefined {
126 return this.tail
?.data
132 public clear (): void {
140 * Returns an iterator for the deque.
142 * @returns An iterator for the deque.
143 * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Iteration_protocols
145 [Symbol
.iterator
] (): Iterator
<T
> {
159 // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
167 * Returns an backward iterator for the deque.
169 * @returns An backward iterator for the deque.
170 * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Iteration_protocols
172 backward (): Iterable
<T
> {
174 [Symbol
.iterator
]: (): Iterator
<T
> => {
188 // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
197 private incrementSize (): number {
199 if (this.size
> this.maxSize
) {
200 this.maxSize
= this.size