Skip to content

Instantly share code, notes, and snippets.

@taoalpha
Created January 23, 2016 04:53
Show Gist options
  • Select an option

  • Save taoalpha/9d11cb5f72e95d02e076 to your computer and use it in GitHub Desktop.

Select an option

Save taoalpha/9d11cb5f72e95d02e076 to your computer and use it in GitHub Desktop.
array-base list and linkedlist-base list, double linked list based list, three in one :)
"use strict"
/*
* Data Structure of Javascript
* 1. List
* 2. Stack
* 3. Queue
* 4. LinkedList
* 5. Dictionary
* 6. Hashing
* 7. Set
* 8. Tree
* 9. Graph
*/
class ListNode{
// single linked list node
constructor(val){
this.val = val;
this.next = null;
}
}
class DListNode{
// double linked list node
constructor(val){
this.val = val;
this.next = null;
this.prev = null;
}
}
/* List
* 1. void clear()
* 2. boolean insert(Object)
* 3. boolean append(Object)
* 4. Object remove(int)
* 5. boolean moveTo(pos)
* 6. int currPos()
* 7. int length()
* 8. void prev()
* 9. void next()
*/
class List{
constructor(type){
this.type = type;
this.init();
}
// initialize this list according the requested type
init(){
switch (this.type) {
case "single":
// linkedlist-based list
this.container = new ListNode(null);
this.tail = this.container;
break;
case "double":
// double-linkedlist-based list
this.container = new DListNode(null);
this.tail = this.container;
break;
default:
// array-based list
this.container = [];
}
// set the length and current position to 0
this.length = 0;
this.cur = 0;
}
// use re-initialize to clear the list
clear(){
this.init(this.type)
}
// append new element to the list
append(val){
var temp;
switch (this.type) {
case "single":
// linkedlist-based list
temp = new ListNode(val);
this.tail.next = temp;
this.tail = this.tail.next;
break;
case "double":
// double-linkedlist-based list
temp = new DListNode(val);
temp.prev = this.tail;
this.tail.next = temp;
this.tail = this.tail.next;
break;
default:
// array-based list
this.container.push(val)
}
this.length ++;
return true;
}
// insert new element to a specific position in the list
insert(val,pos){
if (pos >= this.length) {
this.append(val)
return true;
}
// insert into the middle of the list
var temp,idx = 0;
switch (this.type) {
case "single":
// linkedlist-based list
temp = this.container;
while(idx < pos){
temp = temp.next;
idx ++;
}
// now the temp is the previous position of node
var newNode = new ListNode(val);
newNode.next = temp.next;
temp.next = newNode;
break;
case "double":
// double-linkedlist-based list
idx = 0;
temp = this.container;
while(idx < pos){
temp = temp.next;
idx ++;
}
var newNode = new DListNode(val);
newNode.prev = temp;
temp.next.prev = newNode;
newNode.next = temp.next;
temp.next = newNode;
break;
default:
// array-based list
this.container.splice(pos,0,val)
}
this.length ++;
return true;
}
// get current pos
currPos(){
return this.cur;
}
// move current position to previous element
prev(){
if(this.cur == 0){
throw new Error("OutOfBound")
}
this.cur = this.cur - 1;
}
// move current position to previous element
next(){
if(this.cur == this.length-1){
throw new Error("OutOfBound")
}
this.cur = this.cur + 1;
}
// get current value of current position
getCur(){
var output,idx = 0,temp;
switch (this.type) {
case "single":
case "double":
temp = this.container;
while(idx < this.cur){
idx ++;
temp = temp.next;
}
output = temp.next ? temp.next.val : null;
break;
default:
output = this.container[this.cur];
}
return output;
}
// get current value of current position
getCurObject(){
var output,idx = 0,temp;
switch (this.type) {
case "single":
case "double":
temp = this.container;
while(idx < this.cur){
idx ++;
temp = temp.next;
}
output = temp == null ? null:temp.next;
break;
default:
output = this.container[this.cur];
}
return output;
}
// return the length
len(){
return this.length
}
// is at end ?
isAtEnd(){
return this.cur == this.length-1
}
// move to pos
moveTo(pos){
if (pos >= this.length || pos < 0) {
throw new Error("OutOfBound");
}
this.cur = pos;
}
// get the head of the list
getHead(){
var output;
switch (this.type) {
case "single":
case "double":
output = this.container.next ? this.container.next.val : null;
break;
default:
output = typeof this.container[0] == "undefined" ? null : this.container[0];
}
return output;
}
// get the tail of the this
getTail(){
var output;
switch (this.type) {
case "single":
case "double":
output = this.tail.val;
break;
default:
if (this.length <= 0) {
// for empty list
output = null
} else {
output = this.container[this.length-1];
}
}
return output;
}
// get value of given position
get(pos){
var temp_cur = this.cur,output;
this.moveTo(pos);
output = this.getCur();
this.cur = temp_cur; // reset current position back to origin value
return output
}
// remove element given position
remove(pos){
if(typeof pos == "undefined"){
throw new Error("NO POS")
}
if (this.length == 0){
throw new Error("EMPTY LIST")
}
if (pos <= this.cur) {
// put current position to next or prev
this.cur = this.cur - 1 <= 0 ? 0 : (this.cur - 1)
}
var tempPos = this.cur;
this.moveTo(pos);
var node = this.getCurObject();
switch (this.type) {
case "single":
// linkedlist-based list
if (pos == 0){
// head
this.container.next = node.next
}else if (pos == this.length-1) {
// tail
this.prev();
node = this.getCurObject();
node.next = null;
}else{
this.prev();
var temp = this.getCurObject();
temp.next = node.next;
}
break;
case "double":
// double-linkedlist-based list
if (node.prev){
// not in the head
node.prev.next = node.next;
} else {
this.container.next = node.next
}
if (node.next){
// not in the tail
node.next.prev = node.prev;
} else {
this.tail = node.prev;
this.tail.next = null;
}
break;
default:
// array-based list
this.container.splice(pos,1)
}
this.cur = tempPos;
this.length --;
}
// toString
toString(){
var temp,output=[];
switch (this.type) {
case "single":
case "double":
// linkedlist-based list
temp = this.container.next; // start from the head
while(temp){
output.push(temp.val);
temp = temp.next;
}
break;
default:
// array-based list
output = this.container
}
return output;
}
}
// Test
// var L = new List("single");
// var K = new List();
// var D = new List("double");
// //var L = new List();
// var idx = 0;
// while(idx < 18){
// L.append(idx);
// K.append(idx);
// D.append(idx);
// idx ++;
// }
// idx = 0;
// while(idx < 6){
// var number = Math.floor( Math.random()*5 );
// var i = Math.floor( Math.random() * 22 );
// L.insert(number,i);
// K.insert(number,i);
// D.insert(number,i);
// idx ++;
// }
// idx = 0
// while (idx<19) {
// K.next();
// idx ++;
// }
// idx = 0;
// while(idx < 6){
// var i = Math.floor( Math.random() * 17 );
// L.remove(i);
// K.remove(i);
// D.remove(i);
// idx ++;
// }
// console.log(K.len());
// console.log(K.toString());
// console.log(K.getCur());
// console.log(L.len());
// console.log(L.toString());
// console.log(L.getCur());
// console.log(D.len());
// console.log(D.toString());
// console.log(D.getCur());
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment