File: Datastructures/DoublyLinkedList.ts
- /**
- * The DoublyLinkedList class provides the main functionality of a doubly linked list.
- *
- * @class DoublyLinkedList
- */
- class DoublyLinkedList {
- /**
- * Count of elements in list
- *
- * @property _length
- * @type number
- * @private
- */
- private _length = 0;
- /**
- * Iteration pointer
- *
- * @property _key
- * @type number
- * @private
- */
- private _key = 0;
- /**
- * Reference to head(first) element in list
- *
- * @property _head
- * @type DoublyLinkedListNode
- * @private
- */
- private _head:DoublyLinkedListNode = null;
- /**
- * Reference to tail(last) element in list
- *
- * @property _tail
- * @type DoublyLinkedListNode
- * @private
- */
- private _tail:DoublyLinkedListNode = null;
- /**
- * Reference to iterated element in list
- *
- * @property _current
- * @type DoublyLinkedListNode
- * @private
- */
- private _current:DoublyLinkedListNode = null;
- /**
- * Insert a new value at the specified index
- *
- * @method add
- * @param index The index where the new value is to be inserted.
- * @param value The new value for the index.
- * @return void
- */
- public add(index:any, value:any):void {
- // TODO:
- }
- /**
- * Pops a node from the end of the doubly linked list
- *
- * @method pop
- * @return any The value of the popped node.
- */
- public pop():any {
- if (this._length === 0) {
- throw new Error("Can't pop from an empty data structure");
- }
- var value = this._tail.value;
- this._tail = this._tail.prev;
- if (this._tail) {
- delete this._tail.next;
- this._tail.next = null;
- }
- this._length--;
- return value;
- }
- /**
- * Shifts a node from the beginning of the doubly linked list
- *
- * @method shift
- * @return any The value of the shifted node.
- */
- public shift():any {
- if (this._length === 0) {
- throw new Error("Can't shift from an empty data structure");
- }
- var value = this._head.value;
- this._head = this._head.next;
- if (this._head) {
- delete this._head.prev;
- this._head.prev = null;
- }
- this._length--;
- return value;
- }
- /**
- * Pushes an element at the end of the doubly linked list
- *
- * @method push
- * @param value The value to push.
- * @return void
- */
- public push(value:any):void {
- // allocate new node
- var node:DoublyLinkedListNode = {
- value: value,
- prev: this._tail,
- next: null
- };
- if (this._length === 0) {
- this._head = this._tail = node;
- } else {
- this._tail.next = node;
- this._tail = this._tail.next;
- }
- this._length++;
- }
- /**
- * Prepends the doubly linked list with an element
- *
- * @method unshift
- * @param value The value to unshift.
- * @return void
- */
- public unshift(value:any):void {
- // allocate new node
- var node:DoublyLinkedListNode = {
- value: value,
- prev: null,
- next: this._head
- };
- if (this._length === 0) {
- this._head = this._tail = node;
- } else {
- this._head.prev = node;
- this._head = this._head.prev;
- }
- this._length++;
- }
- /**
- * Peeks at the node from the end of the doubly linked list
- *
- * @method top
- * @return any The value of the last node.
- */
- public top():any {
- return this._tail.value;
- }
- /**
- * Peeks at the node from the beginning of the doubly linked list
- *
- * @method bottom
- * @return any The value of the first node.
- */
- public bottom():any {
- return this._head.value;
- }
- /**
- * Counts the number of elements in the doubly linked list
- *
- * @method count
- * @return number the number of elements in the doubly linked list.
- */
- public count():number {
- return this._length;
- }
- /**
- * Checks whether the doubly linked list is empty
- *
- * @method isEmpty
- * @return boolean whether the doubly linked list is empty.
- */
- public isEmpty():boolean {
- return (this._length === 0);
- }
- /**
- * Rewind iterator back to the start
- *
- * @method rewind
- * @return void
- */
- public rewind():void {
- this._key = 0;
- this._current = this._head;
- }
- /**
- * Return current list entry
- *
- * @method current
- * @return any The current node value.
- */
- public current():any {
- if (this._current) {
- return this._current.value;
- }
- return null;
- }
- /**
- * Return current node index
- *
- * @method key
- * @return any The current node index.
- */
- public key():any {
- return this._key;
- }
- /**
- * Move to next entry
- *
- * @method next
- * @return void
- */
- public next():void {
- this._current = this._current.next;
- this._key++;
- }
- /**
- * Move to previous entry
- *
- * @method prev
- * @return void
- */
- public prev():void {
- this._current = this._current.prev;
- this._key--;
- }
- /**
- * Check whether the doubly linked list contains more nodes
- *
- * @method valid
- * @return boolean true if the doubly linked list contains any more nodes, false otherwise.
- */
- public valid():boolean {
- return (this._key >= 0 && this._key < this._length);
- }
- /**
- * Export the list to array
- *
- * @method toArray
- * @return Array The exported array
- */
- public toArray():Array<any> {
- var list = [];
- var current = this._head;
- while (current) {
- list.push(current.value);
- current = current.next;
- }
- return list;
- }
- /**
- * Serializes the list to string
- *
- * @method toString
- * @return string The serialized string.
- */
- public toString():string {
- return "{" + this.toArray().join("->") + "}";
- }
- }
- /**
- * DoublyLinkedList element
- */
- interface DoublyLinkedListNode {
- value:any;
- prev:DoublyLinkedListNode;
- next:DoublyLinkedListNode;
- }
- export = DoublyLinkedList;