What is the time complexity of insertion at beginning and end of the element in the list?

Introduction to Singly Linked List

Singly Linked List is a variant of Linked List which allows only forward traversal of linked lists. This is a simple form, yet it is effective for several problems such as Big Integer calculations.

A singly linked list is made up of nodes where each node has two parts:

  • The first part contains the actual data of the node
  • The second part contains a link that points to the next node of the list that is the address of the next node.

The beginning of the node marked by a special pointer named START. The pointer points to the fist node of the list but the link part of the last node has no next node to point to.

The main difference from an array is:

  • Elements are not stored in contiguous memory locations.
  • Size of Linked List need not be known in advance. It can increase at runtime depending on number of elements dynamically without any overhead.

In Singly Linked List, only the pointer to the first node is stored. The other nodes are accessed one by one.

To get the address of ith node, we need to traverse all nodes before it because the address of ith node is stored with i-1th node and so on.

Insert N elements in a Linked List one after other at middle position

Given an array of N elements. The task is to insert the given elements at the middle position in the linked list one after another. Each insert operation should take O(1) time complexity.
Examples:

Input: arr[] = {1, 2, 3, 4, 5}
Output: 1 -> 3 -> 5 -> 4 -> 2 -> NULL
1 -> NULL
1 -> 2 -> NULL
1 -> 3 -> 2 -> NULL
1 -> 3 -> 4 -> 2 -> NULL
1 -> 3 -> 5 -> 4 -> 2 -> NULL
Input: arr[] = {5, 4, 1, 2}
Output: 5 -> 1 -> 2 -> 4 -> NULL

Recommended: Please try your approach on {IDE} first, before moving on to the solution.

Approach: There are two cases:

  1. Number of elements present in the list are less than 2.
  2. Number of elements present in the list are more than 2.
    • The number of elements already present are even say N then the new element is inserted in the middle position that is (N / 2) + 1.
    • The number of elements already present are odd then the new element is inserted next to the current middle element that is (N / 2) + 2.

We take one additional pointer ‘middle’ which stores the address of current middle element and a counter which counts the total number of elements.
If the elements already present in the linked list are less than 2 then middle will always point to the first position and we insert the new node after the current middle.
If the elements already present in the linked list are more than 2 then we insert the new node next to the current middle and increment the counter.
If there are an odd number of elements after insertion then the middle points to the newly inserted node else there is no change in the middle pointer.
Below is the implementation of the above approach:

C++




// C++ implementation of the approach
#include <iostream>
using namespace std;
// Node structure
struct Node {
int value;
struct Node* next;
};
// Class to represent a node
// of the linked list
class LinkedList {
private:
struct Node *head, *mid;
int count;
public:
LinkedList();
void insertAtMiddle(int);
void show();
};
LinkedList::LinkedList()
{
head = NULL;
mid = NULL;
count = 0;
}
// Function to insert a node in
// the middle of the linked list
void LinkedList::insertAtMiddle(int n)
{
struct Node* temp = new struct Node();
struct Node* temp1;
temp->next = NULL;
temp->value = n;
// If the number of elements
// already present are less than 2
if (count < 2) {
if (head == NULL) {
head = temp;
}
else {
temp1 = head;
temp1->next = temp;
}
count++;
// mid points to first element
mid = head;
}
// If the number of elements already present
// are greater than 2
else {
temp->next = mid->next;
mid->next = temp;
count++;
// If number of elements after insertion
// are odd
if (count % 2 != 0) {
// mid points to the newly
// inserted node
mid = mid->next;
}
}
}
// Function to print the nodes
// of the linked list
void LinkedList::show()
{
struct Node* temp;
temp = head;
// Initializing temp to head
// Iterating and printing till
// The end of linked list
// That is, till temp is null
while (temp != NULL) {
cout << temp->value << " -> ";
temp = temp->next;
}
cout << "NULL";
cout << endl;
}
// Driver code
int main()
{
// Elements to be inserted one after another
int arr[] = { 1, 2, 3, 4, 5 };
int n = sizeof(arr) / sizeof(arr[0]);
LinkedList L1;
// Insert the elements
for (int i = 0; i < n; i++)
L1.insertAtMiddle(arr[i]);
// Print the nodes of the linked list
L1.show();
return 0;
}
Java




// Java implementation of the approach
class GFG
{
// Node ure
static class Node
{
int value;
Node next;
};
// Class to represent a node
// of the linked list
static class LinkedList
{
Node head, mid;
int count;
LinkedList()
{
head = null;
mid = null;
count = 0;
}
// Function to insert a node in
// the middle of the linked list
void insertAtMiddle(int n)
{
Node temp = new Node();
Node temp1;
temp.next = null;
temp.value = n;
// If the number of elements
// already present are less than 2
if (count < 2)
{
if (head == null)
{
head = temp;
}
else
{
temp1 = head;
temp1.next = temp;
}
count++;
// mid points to first element
mid = head;
}
// If the number of elements already present
// are greater than 2
else
{
temp.next = mid.next;
mid.next = temp;
count++;
// If number of elements after insertion
// are odd
if (count % 2 != 0)
{
// mid points to the newly
// inserted node
mid = mid.next;
}
}
}
// Function to print the nodes
// of the linked list
void show()
{
Node temp;
temp = head;
// Initializing temp to head
// Iterating and printing till
// The end of linked list
// That is, till temp is null
while (temp != null)
{
System.out.print( temp.value + " -> ");
temp = temp.next;
}
System.out.print( "null");
System.out.println();
}
}
// Driver code
public static void main(String args[])
{
// Elements to be inserted one after another
int arr[] = { 1, 2, 3, 4, 5 };
int n = arr.length;
LinkedList L1=new LinkedList();
// Insert the elements
for (int i = 0; i < n; i++)
L1.insertAtMiddle(arr[i]);
// Print the nodes of the linked list
L1.show();
}
}
// This code is contributed by Arnab Kundu
Python3




# Python3 implementation of the approach
# Node ure
class Node:
def __init__(self):
self.value = 0
self.next = None
# Class to represent a node
# of the linked list
class LinkedList:
def __init__(self) :
self.head = None
self.mid = None
self.count = 0
# Function to insert a node in
# the middle of the linked list
def insertAtMiddle(self , n):
temp = Node()
temp1 = None
temp.next = None
temp.value = n
# If the number of elements
# already present are less than 2
if (self.count < 2):
if (self.head == None) :
self.head = temp
else:
temp1 = self.head
temp1.next = temp
self.count = self.count + 1
# mid points to first element
self.mid = self.head
# If the number of elements already present
# are greater than 2
else:
temp.next = self.mid.next
self.mid.next = temp
self.count = self.count + 1
# If number of elements after insertion
# are odd
if (self.count % 2 != 0):
# mid points to the newly
# inserted node
self.mid = self.mid.next
# Function to print the nodes
# of the linked list
def show(self):
temp = None
temp = self.head
# Initializing temp to self.head
# Iterating and printing till
# The end of linked list
# That is, till temp is None
while (temp != None) :
print( temp.value, end = " -> ")
temp = temp.next
print( "None")
# Driver code
# Elements to be inserted one after another
arr = [ 1, 2, 3, 4, 5]
n = len(arr)
L1 = LinkedList()
# Insert the elements
for i in range(n):
L1.insertAtMiddle(arr[i])
# Print the nodes of the linked list
L1.show()
# This code is contributed by Arnab Kundu
C#




// C# implementation of the approach
using System;
class GFG
{
// Node ure
public class Node
{
public int value;
public Node next;
};
// Class to represent a node
// of the linked list
public class LinkedList
{
public Node head, mid;
public int count;
public LinkedList()
{
head = null;
mid = null;
count = 0;
}
// Function to insert a node in
// the middle of the linked list
public void insertAtMiddle(int n)
{
Node temp = new Node();
Node temp1;
temp.next = null;
temp.value = n;
// If the number of elements
// already present are less than 2
if (count < 2)
{
if (head == null)
{
head = temp;
}
else
{
temp1 = head;
temp1.next = temp;
}
count++;
// mid points to first element
mid = head;
}
// If the number of elements already present
// are greater than 2
else
{
temp.next = mid.next;
mid.next = temp;
count++;
// If number of elements after insertion
// are odd
if (count % 2 != 0)
{
// mid points to the newly
// inserted node
mid = mid.next;
}
}
}
// Function to print the nodes
// of the linked list
public void show()
{
Node temp;
temp = head;
// Initializing temp to head
// Iterating and printing till
// The end of linked list
// That is, till temp is null
while (temp != null)
{
Console.Write( temp.value + " -> ");
temp = temp.next;
}
Console.Write( "null");
Console.WriteLine();
}
}
// Driver code
public static void Main(String []args)
{
// Elements to be inserted one after another
int []arr = { 1, 2, 3, 4, 5 };
int n = arr.Length;
LinkedList L1=new LinkedList();
// Insert the elements
for (int i = 0; i < n; i++)
L1.insertAtMiddle(arr[i]);
// Print the nodes of the linked list
L1.show();
}
}
// This code contributed by Rajput-Ji
Javascript




<script>
// JavaScript implementation of the approach
// Node ure
class Node {
constructor() {
this.value = 0;
this.next = null;
}
}
// Class to represent a node
// of the linked list
class LinkedList {
constructor() {
this.head = null;
this.mid = null;
this.count = 0;
}
// Function to insert a node in
// the middle of the linked list
insertAtMiddle(n) {
var temp = new Node();
var temp1;
temp.next = null;
temp.value = n;
// If the number of elements
// already present are less than 2
if (this.count < 2) {
if (this.head == null) {
this.head = temp;
} else {
temp1 = this.head;
temp1.next = temp;
}
this.count++;
// mid points to first element
this.mid = this.head;
}
// If the number of elements already present
// are greater than 2
else {
temp.next = this.mid.next;
this.mid.next = temp;
this.count++;
// If number of elements after insertion
// are odd
if (this.count % 2 != 0) {
// mid points to the newly
// inserted node
this.mid = this.mid.next;
}
}
}
// Function to print the nodes
// of the linked list
show() {
var temp;
temp = this.head;
// Initializing temp to head
// Iterating and printing till
// The end of linked list
// That is, till temp is null
while (temp != null) {
document.write(temp.value + " -> ");
temp = temp.next;
}
document.write("null");
document.write("<br>");
}
}
// Driver code
// Elements to be inserted one after another
var arr = [1, 2, 3, 4, 5];
var n = arr.length;
var L1 = new LinkedList();
// Insert the elements
for (var i = 0; i < n; i++) L1.insertAtMiddle(arr[i]);
// Print the nodes of the linked list
L1.show();
</script>
Output: 1 -> 3 -> 5 -> 4 -> 2 -> NULL

Time Complexity : O(N)
Auxiliary Space: O(1)




Article Tags :
Data Structures
Linked List
Mathematical
Practice Tags :
Data Structures
Linked List
Mathematical
Read Full Article

Implement a stack using singly linked list

To implement a stack using singly linked list concept , all the singly linked list operations are performed based on Stack operations LIFO(last in first out) and with the help of that knowledge we are going to implement a stack using single linked list. Using singly linked lists , we implement stack by storing the information in the form of nodes and we need to follow the stack rules and implement using singly linked list nodes . So we need to follow a simple rule in the implementation of a stack which is last in first out and all the operations can be performed with the help of a top variable .Let us learn how to perform Pop , Push , Peek ,Display operations in the following article .

A stack can be easily implemented using the linked list. In stack Implementation, a stack contains a top pointer. which is “head” of the stack where pushing and popping items happens at the head of the list. First node have null in link field and second node link have first node address in link field and so on and last node address in “top” pointer.
The main advantage of using linked list over an arrays is that it is possible to implement a stack that can shrink or grow as much as needed. In using array will put a restriction to the maximum capacity of the array which can lead to stack overflow. Here each new node will be dynamically allocate. so overflow is not possible.
Stack Operations:

  1. push() : Insert a new element into stack i.e just inserting a new element at the beginning of the linked list.
  2. pop() : Return top element of the Stack i.e simply deleting the first element from the linked list.
  3. peek(): Return the top element.
  4. display(): Print all elements in Stack.

Below is the implementation of the above approach:

C++




// C++ program to Implement a stack
//using singly linked list
#include <bits/stdc++.h>
using namespace std;
// Declare linked list node
struct Node
{
int data;
Node* link;
};
Node* top;
// Utility function to add an element
// data in the stack insert at the beginning
void push(int data)
{
// Create new node temp and allocate memory in heap
Node* temp = new Node();
// Check if stack (heap) is full.
// Then inserting an element would
// lead to stack overflow
if (!temp)
{
cout << "\nStack Overflow";
exit(1);
}
// Initialize data into temp data field
temp->data = data;
// Put top pointer reference into temp link
temp->link = top;
// Make temp as top of Stack
top = temp;
}
// Utility function to check if
// the stack is empty or not
int isEmpty()
{
//If top is NULL it means that
//there are no elements are in stack
return top == NULL;
}
// Utility function to return top element in a stack
int peek()
{
// If stack is not empty , return the top element
if (!isEmpty())
return top->data;
else
exit(1);
}
// Utility function to pop top
// element from the stack
void pop()
{
Node* temp;
// Check for stack underflow
if (top == NULL)
{
cout << "\nStack Underflow" << endl;
exit(1);
}
else
{
// Assign top to temp
temp = top;
// Assign second node to top
top = top->link;
//This will automatically destroy
//the link between first node and second node
// Release memory of top node
//i.e delete the node
free(temp);
}
}
// Function to print all the
// elements of the stack
void display()
{
Node* temp;
// Check for stack underflow
if (top == NULL)
{
cout << "\nStack Underflow";
exit(1);
}
else
{
temp = top;
while (temp != NULL)
{
// Print node data
cout << temp->data << "-> ";
// Assign temp link to temp
temp = temp->link;
}
}
}
// Driver Code
int main()
{
// Push the elements of stack
push(11);
push(22);
push(33);
push(44);
// Display stack elements
display();
// Print top element of stack
cout << "\nTop element is "
<< peek() << endl;
// Delete top elements of stack
pop();
pop();
// Display stack elements
display();
// Print top element of stack
cout << "\nTop element is "
<< peek() << endl;
return 0;
}
Java




// Java program to Implement a stack
// using singly linked list
// import package
import static java.lang.System.exit;
// Create Stack Using Linked list
class StackUsingLinkedlist {
// A linked list node
private class Node {
int data; // integer data
Node link; // reference variable Node type
}
// create global top reference variable global
Node top;
// Constructor
StackUsingLinkedlist()
{
this.top = null;
}
// Utility function to add an element x in the stack
public void push(int x) // insert at the beginning
{
// create new node temp and allocate memory
Node temp = new Node();
// check if stack (heap) is full. Then inserting an
// element would lead to stack overflow
if (temp == null) {
System.out.print("\nHeap Overflow");
return;
}
// initialize data into temp data field
temp.data = x;
// put top reference into temp link
temp.link = top;
// update top reference
top = temp;
}
// Utility function to check if the stack is empty or not
public boolean isEmpty()
{
return top == null;
}
// Utility function to return top element in a stack
public int peek()
{
// check for empty stack
if (!isEmpty()) {
return top.data;
}
else {
System.out.println("Stack is empty");
return -1;
}
}
// Utility function to pop top element from the stack
public void pop() // remove at the beginning
{
// check for stack underflow
if (top == null) {
System.out.print("\nStack Underflow");
return;
}
// update the top pointer to point to the next node
top = (top).link;
}
public void display()
{
// check for stack underflow
if (top == null) {
System.out.printf("\nStack Underflow");
exit(1);
}
else {
Node temp = top;
while (temp != null) {
// print node data
System.out.printf("%d->", temp.data);
// assign temp link to temp
temp = temp.link;
}
}
}
}
// main class
public class GFG {
public static void main(String[] args)
{
// create Object of Implementing class
StackUsingLinkedlist obj = new StackUsingLinkedlist();
// insert Stack value
obj.push(11);
obj.push(22);
obj.push(33);
obj.push(44);
// print Stack elements
obj.display();
// print Top element of Stack
System.out.printf("\nTop element is %d\n", obj.peek());
// Delete top element of Stack
obj.pop();
obj.pop();
// print Stack elements
obj.display();
// print Top element of Stack
System.out.printf("\nTop element is %d\n", obj.peek());
}
}
Python3




'''Python supports automatic garbage collection so deallocation of memory
is done implicitly. However to force it to deallocate each node after use,
add the following code:
import gc #added at the start of program
gc.collect() #to be added wherever memory is to be deallocated
'''
class Node:
# Class to create nodes of linked list
# constructor initializes node automatically
def __init__(self,data):
self.data = data
self.next = None
class Stack:
# head is default NULL
def __init__(self):
self.head = None
# Checks if stack is empty
def isempty(self):
if self.head == None:
return True
else:
return False
# Method to add data to the stack
# adds to the start of the stack
def push(self,data):
if self.head == None:
self.head=Node(data)
else:
newnode = Node(data)
newnode.next = self.head
self.head = newnode
# Remove element that is the current head (start of the stack)
def pop(self):
if self.isempty():
return None
else:
# Removes the head node and makes
#the preceding one the new head
poppednode = self.head
self.head = self.head.next
poppednode.next = None
return poppednode.data
# Returns the head node data
def peek(self):
if self.isempty():
return None
else:
return self.head.data
# Prints out the stack
def display(self):
iternode = self.head
if self.isempty():
print("Stack Underflow")
else:
while(iternode != None):
print(iternode.data,"->",end = " ")
iternode = iternode.next
return
# Driver code
MyStack = Stack()
MyStack.push(11)
MyStack.push(22)
MyStack.push(33)
MyStack.push(44)
# Display stack elements
MyStack.display()
# Print top element of stack
print("\nTop element is ",MyStack.peek())
# Delete top elements of stack
MyStack.pop()
MyStack.pop()
# Display stack elements
MyStack.display()
# Print top element of stack
print("\nTop element is ", MyStack.peek())
# This code is contributed by Mathew George
C#




// C# program to Implement a stack
// using singly linked list
// import package
using System;
// Create Stack Using Linked list
public class StackUsingLinkedlist
{
// A linked list node
private class Node
{
// integer data
public int data;
// reference variable Node type
public Node link;
}
// create global top reference variable
Node top;
// Constructor
public StackUsingLinkedlist()
{
this.top = null;
}
// Utility function to add
// an element x in the stack
// insert at the beginning
public void push(int x)
{
// create new node temp and allocate memory
Node temp = new Node();
// check if stack (heap) is full.
// Then inserting an element
// would lead to stack overflow
if (temp == null)
{
Console.Write("\nHeap Overflow");
return;
}
// initialize data into temp data field
temp.data = x;
// put top reference into temp link
temp.link = top;
// update top reference
top = temp;
}
// Utility function to check if
// the stack is empty or not
public bool isEmpty()
{
return top == null;
}
// Utility function to return
// top element in a stack
public int peek()
{
// check for empty stack
if (!isEmpty())
{
return top.data;
}
else
{
Console.WriteLine("Stack is empty");
return -1;
}
}
// Utility function to pop top element from the stack
public void pop() // remove at the beginning
{
// check for stack underflow
if (top == null)
{
Console.Write("\nStack Underflow");
return;
}
// update the top pointer to
// point to the next node
top = (top).link;
}
public void display()
{
// check for stack underflow
if (top == null)
{
Console.Write("\nStack Underflow");
return;
}
else
{
Node temp = top;
while (temp != null)
{
// print node data
Console.Write("{0}->", temp.data);
// assign temp link to temp
temp = temp.link;
}
}
}
}
// Driver code
public class GFG
{
public static void Main(String[] args)
{
// create Object of Implementing class
StackUsingLinkedlist obj = new StackUsingLinkedlist();
// insert Stack value
obj.push(11);
obj.push(22);
obj.push(33);
obj.push(44);
// print Stack elements
obj.display();
// print Top element of Stack
Console.Write("\nTop element is {0}\n", obj.peek());
// Delete top element of Stack
obj.pop();
obj.pop();
// print Stack elements
obj.display();
// print Top element of Stack
Console.Write("\nTop element is {0}\n", obj.peek());
}
}
// This code is contributed by 29AjayKumar
Javascript




<script>
// Javascript program to Implement a stack
// using singly linked list
// import package
// A linked list node
class Node
{
constructor()
{
this.data=0;
this.link=null;
}
}
// Create Stack Using Linked list
class StackUsingLinkedlist
{
constructor()
{
this.top=null;
}
// Utility function to add an element x in the stack
push(x)
{
// create new node temp and allocate memory
let temp = new Node();
// check if stack (heap) is full. Then inserting an
// element would lead to stack overflow
if (temp == null) {
document.write("<br>Heap Overflow");
return;
}
// initialize data into temp data field
temp.data = x;
// put top reference into temp link
temp.link = this.top;
// update top reference
this.top = temp;
}
// Utility function to check if the stack is empty or not
isEmpty()
{
return this.top == null;
}
// Utility function to return top element in a stack
peek()
{
// check for empty stack
if (!this.isEmpty()) {
return this.top.data;
}
else {
document.write("Stack is empty<br>");
return -1;
}
}
// Utility function to pop top element from the stack
pop() // remove at the beginning
{
// check for stack underflow
if (this.top == null) {
document.write("<br>Stack Underflow");
return;
}
// update the top pointer to point to the next node
this.top = this.top.link;
}
display()
{
// check for stack underflow
if (this.top == null) {
document.write("<br>Stack Underflow");
}
else {
let temp = this.top;
while (temp != null) {
// print node data
document.write(temp.data+"->");
// assign temp link to temp
temp = temp.link;
}
}
}
}
// main class
// create Object of Implementing class
let obj = new StackUsingLinkedlist();
// insert Stack value
obj.push(11);
obj.push(22);
obj.push(33);
obj.push(44);
// print Stack elements
obj.display();
// print Top element of Stack
document.write("<br>Top element is ", obj.peek()+"<br>");
// Delete top element of Stack
obj.pop();
obj.pop();
// print Stack elements
obj.display();
// print Top element of Stack
document.write("<br>Top element is ", obj.peek()+"<br>");
// This code is contributed by rag2127
</script>

Output:



44->33->22->11-> Top element is 44 22->11-> Top element is 22

Time Complexity:

The time complexity for all push(), pop(), and peek() operations is O(1) as we are not performing any kind of traversal over the list. We perform all the operations through the current pointer only.




Article Tags :
Linked List
Stack
Technical Scripter
Technical Scripter 2018
Practice Tags :
Linked List
Stack
Read Full Article

Video liên quan

Postingan terbaru

LIHAT SEMUA