Singly Linked Lists - rohit120582sharma/Documentation GitHub Wiki

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.

Singly Linked Lists are an excellent alternative to arrays when insertion and deletion at the beginning are frequently required

Arrays contain a built in index whereas Linked Lists do not

The idea of a list data structure that consists of nodes is the foundation for other data structures like Stacks and Queues

Comparisons with Arrays

  • Lists
    • Do not have indexes!
    • Connected via nodes with a next pointer
    • Random access is not allowed
  • Arrays
    • Indexed in order!
    • Insertion and deletion can be expensive
    • Can quickly be accessed at a specific index

Big O

  • Insertion - O(1)
  • Removal - It depends.... O(1) or O(N)
  • Searching - O(N)
  • Access - O(N)


Pushing

  • Adding a new node to the end of the Linked List!
  • Pseudocode
    • This function should accept a value
    • Create a new node using the value passed to the function
    • If there is no head property on the list, set the head and tail to be the newly created node
    • Otherwise set the next property on the tail to be the new node and set the tail property on the list to be the newly created node
    • Increment the length by one
    • Return the linked list
class Node {
	constructor(value){
		this.value = value;
		this.next = null;
	}
}
class SinglyLinkedList {
	constructor(){
		this.head = null;
		this.tail = null;
		this.length = 0;
	}
	push(value){
		var newNode = new Node(value);
		if(!this.head){
			this.head = newNode;
			this.tail = newNode;
		}else{
			this.tail.next = newNode;
			this.tail = newNode;
		}
		this.length++;
		return this;
	}
}

Popping

  • Removing a node from the end of the Linked List!
  • Pseudocode
    • If there are no nodes in the list, return undefined
    • Loop through the list until you reach the tail
    • Set the next property of the 2nd to last node to be null
    • Set the tail to be the 2nd to last node
    • Decrement the length of the list by 1
    • Return the value of the node removed
pop(){
	if(!this.head){
		return undefined;
	}
	var current = this.head;
	var newTail = this.head;
	while(current.next){
		newTail = current;
		current = current.next;
	}
	this.tail = newTail;
	this.tail.next = null;
	this.length--;
	if(this.length === 0){
		this.head = null;
		this.tail = null;
	}
	return current;
}

Shifting

  • Removing a new node from the beginning of the Linked List!
  • Pseudocode
    • If there are no nodes, return undefined
    • Store the current head property in a variable
    • Set the head property to be the current head's next property
    • Decrement the length by 1
    • Return the value of the node removed
shift(){
	if(!this.head){
		return undefined;
	}
	var currentHead = this.head;
	this.head = currentHead.next;
	this.length--;
	if(this.length === 0){
		this.head = null;
		this.tail = null;
	}
	return currentHead;
}

Unshifting

  • Adding a new node to the beginning of the Linked List!
  • Pseudocode
    • This function should accept a value
    • Create a new node using the value passed to the function
    • If there is no head property on the list, set the head and tail to be the newly created node
    • Otherwise set the newly created node's next property to be the current head property on the list
    • Set the head property on the list to be that newly created node
    • Increment the length of the list by 1
    • Return the linked list
unshift(value){
	var newNode = new Node(value);
	if(!this.head){
		this.head = newNode;
		this.tail = newNode;
	}else{
		newNode.next = this.head;
		this.head = newNode;
	}
	this.length++;
	return this;
}

Get

  • Retrieving a node by it's position in the Linked List!
  • Pseudocode
    • This function should accept an index
    • If the index is less than zero or greater than or equal to the length of the list, return null
    • Loop through the list until you reach the index and return the node at that specific index
get(index){
	if(index < 0 || index >= this.length){
		return null;
	}
	var counter = 0;
	var 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
  • Pseudocode
    • This function should accept a value and an index
    • Use your get function to find the specific node
    • If the node is not found, return false
    • If the node is found, set the value of that node to be the value passed to the function and return true
set(index, value){
	var foundNode = this.get(index);
	if(foundNode){
		foundNode.value = value;
		return true;
	}
	return false;
}

Insert

  • Adding a node to the Linked List at a specific position
  • Pseudocode
    • If the index is less than zero or greater than the length, return false
    • If the index is the same as the length, push a new node to the end of the list
    • If the index is 0, unshift a new node to the start of the list
    • Otherwise, using the get method, access the node at the index - 1
    • Set the next property on that node to be the new node
    • Set the next property on the new node to be the previous next
    • Increment the length
    • Return true
insert(index, value){
	if(index < 0 || index > this.length){
		return false;
	}
	if(index === 0){
		this.unshift(value);
		return true;
	}
	if(index === this.length){
		this.push(value);
		return true;
	}
	var newNode = new Node(value);
	var prevNode = this.get(index-1);
	newNode.next = prevNode.next;
	prevNode.next = newNode;
	this.length++;
	return true;
}

Remove

  • Removing a node from the Linked List at a specific position
  • Pseudocode
    • If the index is less than zero or greater than the length, return undefined
    • If the index is the same as the length - 1, pop
    • If the index is 0, shift
    • Otherwise, using the get method, access the node at the index - 1
    • Set the next property on that node to be the next of the next node
    • Decrement the length
    • Return the value of the node removed
remove(index){
	if(index < 0 || index >= this.length){
		return undefined;
	}
	if(index === 0){
		return this.shift();
	}
	if(index === this.length - 1){
		return this.pop();
	}
	var prevNode = this.get(index-1);
	var nextNode = prevNode.next;
	prevNode.next = nextNode.next;
	this.length--;
	return nextNode;
}

Reverse

  • Reversing the Linked List in place!
  • Pseudocode
    • Swap the head and tail
    • Create a variable called next
    • Create a variable called prev
    • Create a variable called node and initialise it to the head property
    • Loop through the list
    • Set next to be the next property on whatever node is
    • Set the next property on the node to be whatever prev is
    • Set prev to be the value of the node variable
    • Set the node variable to be the value of the next variable
    • Once you have finished looping, return the list
reverse(){
	if(!this.head){
		return undefined;
	}
	var next;
	var prev = null;
	let node = this.head;

	this.head = this.tail;
	this.tail = node;
	
	for(let i = 0; i < this.length; i++){
		next = node.next;
		node.next = prev;
		prev = node;
		node = next;
	}
	return this;
}
⚠️ **GitHub.com Fallback** ⚠️