Created
January 23, 2016 04:53
-
-
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 :)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| "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