export interface DataNode { data: T; next: DataNode | null; } export interface QueueI { enqueue(data: T): void; dequeue(): T | null; peek(): T | null; size(): number; } export class Queue implements QueueI { private _size: number; private head: DataNode | null; private tail: DataNode | null; constructor() { this._size = 0; this.head = this.tail = null; } enqueue(data: T) { const node: DataNode = { data, next: null } if (this.head === null) { this.head = this.tail = node; } else { if (this.tail) { this.tail.next = node; this.tail = this.tail.next; } } ++this._size; } dequeue(): T | null { let item: T | null = null; if (this._size === 0) { return null; } if (this.head) { item = this.head.data; this.head = this.head.next; --this._size; if (!this._size) { this.tail = null; } } return item; } peek(): T | null { let item: T | null = null; if (this._size === 0) { return null; } if (this.head) { item = this.head.data; } return item; } size(): number { return this._size; } }