What is a linked list?
A data structure that contains a head, tail and length property.
Linked lists consist of nodes, and each node has a value and a pointer to another node or null.
Everything is about node, and how to set .next to some value..!
class Node{
constructor(val){
this.val = val;
this.next = null;
}
}
class SinglyLinkedList{
constructor(){
this.length = 0;
this.head = null;
this.tail = null;
}
push(val){
let newNode = new Node(val);
if(!this.head){
this.head = newNode;
this.tail = this.head;
} else {
this.tail.next = newNode; // 먼저 현재 테일 다음위치에 newNode 지정하고
this.tail = newNode; // 테일을 그 녀석으로 바꿈
}
this.length++;
return this;
}
pop(){
if(!this.head) return undefined;
let current = this.head;
let newTail = current;
while(current.next){
newTail = current;
currnet = current.next;
}
this.tail = newTail;
this.tail.next = null;
this.legnth--;
return current;
}
// pop은 current, newTail 두개를 가지고 작동시킨다.
shift(){
if(!this.head) return undefined;
let currentHead = this.head;
this.head = currentHead.next;
this.length--;
return currentHead;
}
unshift(val){
let newNode = new Node(val);
if(!this.head) {
this.head = newNode;
this.tail = this.head;
} else {
newNode.next = this.head;
this.head = newNode;
}
this.length++;
return this;
}
/* Get : Retrieving a node by it's position*/
get(index){
if(index < 0 || index >= this.length) return null;
let counter = 0;
let current = this.head;
while(counter !== index){
current = current.next;
counter++;
}
return current;
}
/* Set : Changing the value of a node based on
it's position in the Linked List */
set(index, val){
let foundNode = this.get(index);
if(foundNode) {
foundNode.val = val;
return true;
}
return false;
}
/* Insert : Adding a node to the Linked List
at a specific position */
insert(index, val){
if(index < 0 || index > this.length) retrun false;
if(index === this.length) return this.push(val);
if(index === 0) return this.unshift(val);
let newNode = new Node(val);
let prev = this.get(index - 1);
let temp = prev;
prev.next = newNode;
newNode.next = temp;
this.length++;
return true;
}
/* Remove : Removing a node from the Linked List at a
specific position */
remove(index) {
if(index < 0 || index > this.length) return undefiend;
if(index === this.length - 1 ) return this.pop();
if(index == 0) return this.shift();
let previousNode = this.get(index-1);
let removed = previousNode.next;
previousNode.next = removed.next;
this.length--;
return removed;
}
/* Reverse : Reversing the Linked List */
reverse(){
let node = this.head;
this.head = this.tail;
this.tail = node;
let next;
let prev = null;
for(let i = 0; i < this.length; i++) {
next = node.next;
node.next = prev; // 여기가 제일 중요, 나머지는 변수 재설정 급
prev = node;
node = next;
}
return this;
}
}
Big O of Singly Linked List
Insertion at the begging or at the end O(1) : Take the current end, the tail, make a new node and just set the tail next to that new node // Same thing at the beginning, make a new node and its dot next to be the head, and then move the head.
Insertion general O(n) : Cause you have to get into that position
Removal, It depends O(1) or O(n) : From the beginning, its O(1), take the current head and set its dot next to be the next head, and take out the old head. // From the end, we need to find item right before the tail, and that involves iterating the entire list.
Searching O(n), Accessing O(n) : we need to check every single node, as the numbers growth, so does the number of operation there.