javascript data structure and algorithms one-way and two-way Chain lists

Keywords: Javascript

Linear table (List): A finite sequence of zero or more data elements.A linear table is a sequence with a one-to-one relationship, not a one-to-many relationship.Linear tables require limitations and the same data type.
This paper mainly refers to the principle of telephone data structure to understand, and uses Javascript to implement related operations on linear tables.

Create a one-way chain table:

//Create Node
class Node{
    constructor(element){
        this.element = element;//Data Domain
        this.next = undefined;//Pointer field
    }
};
//To determine if the incoming object is equal to the elements of the chain table, use indexOf() later, write it here first
function(a,b){
    return a == b;
}; 
//Create Chain List
class LinkedList {
  constructor(equalsFn = defaultEquals) {
    this.equalsFn = equalsFn;
    this.count = 0;
    this.head = undefined;
    }
};

Query operation

Determine if one-way table is empty

isEmpty() {
    return this.size() === 0;
  }

Calculating the Length of a One-way Chain List

size() {
    return this.count;
  }

Query the location of an element in a list of chains

indexOf(element) {
    let current = this.head;
    for (let i = 0; i < this.size() && current != null; i++) {
      if (this.equalsFn(element, current.element)) {
        return i;
      }
      current = current.next;
    }
    return -1;
  }

Get the first element

getHead() {
    return this.head;
  }

Get Element Action

getElementAt(index) {
    if (index >= 0 && index <= this.count) {
      let node = this.head;
      for (let i = 0; i < index && node != null; i++) {
        node = node.next;
      }
      return node;
    }
    return undefined;
  }

Insert operation

Tail interpolation

push(element) {
    const node = new Node(element);
    let current;
    if (this.head == null) {
      // catches null && undefined
      this.head = node;
    } else {
      current = this.head;
      while (current.next != null) {
        current = current.next;
      }
      current.next = node;
    }
    this.count++;
  }

Insert elements anywhere

insert(element, index) {
    if (index >= 0 && index <= this.count) {
      const node = new Node(element);
      if (index === 0) {
        const current = this.head;
        node.next = current;
        this.head = node;
      } else {
        const previous = this.getElementAt(index - 1);
        node.next = previous.next;
        previous.next = node;
      }
      this.count++;
      return true;
    }
    return false;
  }

Delete operation

Delete elements at specific locations

removeAt(index) {
    if (index >= 0 && index < this.count) {
      let current = this.head;
      if (index === 0) {
        this.head = current.next;
      } else {
        const previous = this.getElementAt(index - 1);
        current = previous.next;
        previous.next = current.next;
      }
      this.count--;
      return current.element;
    }
    return undefined;
  }

Delete an element of the list directly

remove(element) {
    const index = this.indexOf(element);
    return this.removeAt(index);
  }

Modify Action

One-way list converted to string

toString() {
    if (this.head == null) {
      return '';
    }
    let objString = `${this.head.element}`;
    let current = this.head.next;
    for (let i = 1; i < this.size() && current != null; i++) {
      objString = `${objString},${current.element}`;
      current = current.next;
    }
    return objString;
  }
}

Empty One-way Chain List

clear() {
    this.head = undefined;
    this.count = 0;
  }

These are the common operations for one-way chained lists.

Since a one-way chain table can only be traversed from beginning to end, if the query is for the next node, the one-way table time complexity is O(1), but if the query is for the previous node, then the time complexity is O(n).If the list can also be traversed in both directions, then the time complexity of the query operation is O(1), then our predecessors have proposed the bi-directional list of chains.Since the two-way chain table is an extension of the one-way chain table, but there is only one more pointer, which is not helpful for query operation, so the implementation method is the same as the one-way chain table, which is not discussed here.

Create a two-way chain table

//Create Node
class DoublyNode extends Node {
  constructor(element, next, prev) {
    super(element, next);//inherit
    this.prev = prev;//Add Forward Pointer
  }
};
//Initialize Bi-directional Chain List
class DoublyLinkedList extends LinkedList {
  constructor(equalsFn = defaultEquals) {
    super(equalsFn);
    this.tail = undefined;//Reference to the last element of the list
  }

Insert operation

Tail interpolation

push(element) {
    const node = new DoublyNode(element);
    if (this.head == null) {
      this.head = node;
      this.tail = node; // NEW
    } else {
      // attach to the tail node // NEW
      this.tail.next = node;
      node.prev = this.tail;
      this.tail = node;
    }
    this.count++;
  }

Add elements anywhere

insert(element, index) {
    if (index >= 0 && index <= this.count) {
      const node = new DoublyNode(element);
      let current = this.head;
      if (index === 0) {
        if (this.head == null) { // NEW
          this.head = node;
          this.tail = node; // NEW
        } else {
          node.next = this.head;
          this.head.prev = node; // NEW
          this.head = node;
        }
      } else if (index === this.count) { // last item NEW
        current = this.tail;
        current.next = node;
        node.prev = current;
        this.tail = node;
      } else {
        const previous = this.getElementAt(index - 1);
        current = previous.next;
        node.next = current;
        previous.next = node;
        current.prev = node; // NEW
        node.prev = previous; // NEW
      }
      this.count++;
      return true;
    }
    return false;
  }

Delete operation

Delete elements at specific locations

removeAt(index) {
    if (index >= 0 && index < this.count) {
      let current = this.head;
      if (index === 0) {
        this.head = this.head.next;
        // if there is only one item, then we update tail as well //NEW
        if (this.count === 1) {
          // {2}
          this.tail = undefined;
        } else {
          this.head.prev = undefined;
        }
      } else if (index === this.count - 1) {
        // last item //NEW
        current = this.tail;
        this.tail = current.prev;
        this.tail.next = undefined;
      } else {
        current = this.getElementAt(index);
        const previous = current.prev;
        // link previous with current's next - skip it to remove
        previous.next = current.next;
        current.next.prev = previous; // NEW
      }
      this.count--;
      return current.element;
    }
    return undefined;
  }

Query operation

Location of query elements

indexOf(element) {
    let current = this.head;
    let index = 0;
    while (current != null) {
      if (this.equalsFn(element, current.element)) {
        return index;
      }
      index++;
      current = current.next;
    }
    return -1;
  }

Query tail element

getTail() {
    return this.tail;
  }

Modify Action

Empty Two-way Chain List

clear() {
    super.clear();
    this.tail = undefined;
  }

Bidirectional Link Table Object to String

inverseToString() {
    if (this.tail == null) {
      return '';
    }
    let objString = `${this.tail.element}`;
    let previous = this.tail.prev;
    while (previous != null) {
      objString = `${objString},${previous.element}`;
      previous = previous.prev;
    }
    return objString;
  }
}

Posted by buddhi225 on Thu, 15 Aug 2019 09:03:53 -0700