428 lines
		
	
	
		
			10 KiB
		
	
	
	
		
			Markdown
		
	
	
	
	
	
			
		
		
	
	
			428 lines
		
	
	
		
			10 KiB
		
	
	
	
		
			Markdown
		
	
	
	
	
	
---
 | 
						|
title: Data Structure Linked List
 | 
						|
---
 | 
						|
Just like a garland is made with flowers, a linked list is made up of nodes. We call every flower on this particular garland to be a node. And each of the node points to the next node in this list as well as it has data (here it is type of flower).
 | 
						|
 | 
						|
## Types
 | 
						|
 | 
						|
1.  Singly Linked List
 | 
						|
 | 
						|
Singly linked lists contain nodes which have a `data` field as well as a `next` field, which points to the next node in the sequence. Operations that can be performed on singly linked lists are insertion, deletion and traversal.
 | 
						|
 | 
						|
`
 | 
						|
 | 
						|
    Singly Link List
 | 
						|
 | 
						|
* * *
 | 
						|
 | 
						|
       head
 | 
						|
        |
 | 
						|
        |
 | 
						|
      +-----+--+      +-----+--+      +-----+------+
 | 
						|
      |  1  |o----->  |  2  |o----->  |  3  | NULL |
 | 
						|
      +-----+--+      +-----+--+      +-----+------+
 | 
						|
 | 
						|
`
 | 
						|
 | 
						|
Application
 | 
						|
 | 
						|
Internal implementation of CPython, the frames and evaluated variables are kept on a stack.
 | 
						|
 | 
						|
For this we need to iterate only forward aur get the head, therefore singly linked-list is used.
 | 
						|
 | 
						|
1.  Doubly Linked List
 | 
						|
 | 
						|
Doubly linked lists contain node which have `data` field, `next` field and another link field `prev` pointing to the previous node in the sequence.
 | 
						|
 | 
						|
`
 | 
						|
 | 
						|
Doubly Linked List
 | 
						|
 | 
						|
* * *
 | 
						|
 | 
						|
              head
 | 
						|
               |
 | 
						|
               |
 | 
						|
      +------+-----+--+    +--+-----+--+       +-----+------+
 | 
						|
      |      |     |o------>  |     |o------>  |     |      |
 | 
						|
      | NULL |  1  |          |  2  |          |  3  | NULL |
 | 
						|
      |      |     |  <------o|     |  <------o|     |      |
 | 
						|
      +------+-----+--+    +--+-----+--+       +-----+------+
 | 
						|
 | 
						|
`
 | 
						|
 | 
						|
Application
 | 
						|
 | 
						|
The browser cache which allows you to hit the BACK and FORWARD button. Here we need to maintain a doubly linked list, with `URLs` as data field, to allow access in both direction. To go to previous URL we will use `prev` field and to go to next page we will use `next` field.
 | 
						|
 | 
						|
1.  Circular Linked List
 | 
						|
 | 
						|
Circular linked lists is a singly linked list in which last node, `next` field points to first node in the sequence.
 | 
						|
 | 
						|
`
 | 
						|
 | 
						|
Circular Linked List
 | 
						|
 | 
						|
* * *
 | 
						|
 | 
						|
         head
 | 
						|
          |
 | 
						|
          |
 | 
						|
        +-----+--+      +-----+--+      +-----+--+
 | 
						|
 | 
						|
--> | 1 |o-----> | 2 |o-----> | 3 |o----  
 | 
						|
| +-----+--+ +-----+--+ +-----+--+ |  
 | 
						|
| |
 | 
						|
 | 
						|
* * *
 | 
						|
 | 
						|
`
 | 
						|
 | 
						|
**Application**
 | 
						|
 | 
						|
Timesharing problem solved by the operating system.
 | 
						|
 | 
						|
In a timesharing environment, the operating system must maintain a list of present users and must alternately allow each user to use a small portion of CPU time, one user at a time. The operating system will pick a user, let him/her use a small amount of CPU time and then move on to the next user.
 | 
						|
 | 
						|
For this application, there should be no NULL pointers unless there is absolutely no one requesting CPU time, i.e list is empty.
 | 
						|
 | 
						|
## Basic Operations
 | 
						|
 | 
						|
1.  Insertion
 | 
						|
 | 
						|
To add a new element to the list.
 | 
						|
 | 
						|
`
 | 
						|
 | 
						|
Insertion at the beginning
 | 
						|
 | 
						|
* * *
 | 
						|
 | 
						|
*   Create a new node with given data.
 | 
						|
*   Point new node's `next` to old `head`.
 | 
						|
*   Point `head` to this new node.
 | 
						|
 | 
						|
Insertion in the middle/end
 | 
						|
 | 
						|
* * *
 | 
						|
 | 
						|
Insertion after node X.
 | 
						|
 | 
						|
*   Create a new node with given data.
 | 
						|
*   Point new node's `next` to old X's `next`.
 | 
						|
*   Point X's `next` to this new node.  
 | 
						|
    `
 | 
						|
 | 
						|
**Time Complexity: O(1)**
 | 
						|
 | 
						|
1.  Deletion
 | 
						|
 | 
						|
To delete existing element from the list.
 | 
						|
 | 
						|
`
 | 
						|
 | 
						|
Deletion at the beginning
 | 
						|
 | 
						|
* * *
 | 
						|
 | 
						|
*   Get the node pointed by `head` as Temp.
 | 
						|
*   Point `head` to Temp's `next`.
 | 
						|
*   Free memory used by Temp node.
 | 
						|
 | 
						|
Deletion in the middle/end
 | 
						|
 | 
						|
* * *
 | 
						|
 | 
						|
Deletion after node X.
 | 
						|
 | 
						|
*   Get the node pointed by `X` as Temp.
 | 
						|
*   Point X's `next` to Temp's `next`.
 | 
						|
*   Free memory used by Temp node.  
 | 
						|
    `
 | 
						|
 | 
						|
**Time Complexity: O(1)**
 | 
						|
 | 
						|
1.  Traversing
 | 
						|
 | 
						|
To travel across the list.
 | 
						|
 | 
						|
`
 | 
						|
 | 
						|
Traversal
 | 
						|
 | 
						|
* * *
 | 
						|
 | 
						|
*   Get the node pointed by `head` as Current.
 | 
						|
*   Check if Current is not null and display it.
 | 
						|
*   Point Current to Current's `next` and move to above step.  
 | 
						|
    `
 | 
						|
 | 
						|
**Time Complexity: O(n) // Here n is size of link-list**
 | 
						|
 | 
						|
## Implementation
 | 
						|
 | 
						|
### C++ implementation of singly linked list
 | 
						|
 | 
						|
    // Header files
 | 
						|
    #include <iostream>
 | 
						|
 | 
						|
    struct node
 | 
						|
    {
 | 
						|
        int data;
 | 
						|
        struct node *next;
 | 
						|
    };
 | 
						|
 | 
						|
    // Head pointer always points to first element of the linked list
 | 
						|
    struct node *head = NULL;
 | 
						|
 | 
						|
#### Printing data in each node  
 | 
						|
 | 
						|
    // Display the list
 | 
						|
    void printList()
 | 
						|
    {
 | 
						|
        struct node *ptr = head;
 | 
						|
 | 
						|
        // Start from the beginning
 | 
						|
    while(ptr != NULL)
 | 
						|
    {
 | 
						|
        std::cout << ptr->data << " ";
 | 
						|
        ptr = ptr->next;
 | 
						|
    }
 | 
						|
 | 
						|
    std::cout << std::endl;
 | 
						|
    }
 | 
						|
 | 
						|
#### Insertion at the beginning  
 | 
						|
 | 
						|
    // Insert link at the beginning
 | 
						|
    void insertFirst(int data)
 | 
						|
    {
 | 
						|
        // Create a new node
 | 
						|
        struct node *new_node = new struct node;
 | 
						|
 | 
						|
        new_node->data = data;
 | 
						|
 | 
						|
    // Point it to old head
 | 
						|
    new_node->next = head;
 | 
						|
 | 
						|
    // Point head to new node
 | 
						|
    head = new_node;
 | 
						|
 | 
						|
    std::cout << "Inserted successfully" << std::endl;
 | 
						|
    }
 | 
						|
 | 
						|
#### Deletion at the beginning  
 | 
						|
 | 
						|
    // Delete first item
 | 
						|
    void deleteFirst()
 | 
						|
    {
 | 
						|
        // Save reference to head
 | 
						|
        struct node *temp = head;
 | 
						|
 | 
						|
        // Point head to head's next
 | 
						|
    head = head->next;
 | 
						|
 | 
						|
    // Free memory used by temp
 | 
						|
    temp = NULL:
 | 
						|
    delete temp;
 | 
						|
 | 
						|
    std::cout << "Deleted successfully" << std::endl;
 | 
						|
    }
 | 
						|
 | 
						|
#### Size  
 | 
						|
 | 
						|
    // Find no. of nodes in link list
 | 
						|
    void size()
 | 
						|
    {
 | 
						|
        int length = 0;
 | 
						|
        struct node *current;
 | 
						|
 | 
						|
        for(current = head; current != NULL; current = current->next)
 | 
						|
    {
 | 
						|
        length++;
 | 
						|
    }
 | 
						|
 | 
						|
    std::cout << "Size of Linked List is " << length << std::endl;
 | 
						|
    }
 | 
						|
 | 
						|
#### Searching  
 | 
						|
 | 
						|
    // Find node with given data
 | 
						|
    void find(int data){
 | 
						|
 | 
						|
        // Start from the head
 | 
						|
    struct node* current = head;
 | 
						|
 | 
						|
    // If list is empty
 | 
						|
    if(head == NULL)
 | 
						|
    {
 | 
						|
        std::cout << "List is empty" << std::endl;
 | 
						|
        return;
 | 
						|
    }
 | 
						|
 | 
						|
    // Traverse through list
 | 
						|
    while(current->data != data){
 | 
						|
 | 
						|
        // If it is last node
 | 
						|
        if(current->next == NULL){
 | 
						|
            std::cout << "Not Found" << std::endl;
 | 
						|
            return;
 | 
						|
        }
 | 
						|
        else{
 | 
						|
            // Go to next node
 | 
						|
            current = current->next;
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    // If data found
 | 
						|
    std::cout << "Found" << std::endl;
 | 
						|
    }
 | 
						|
 | 
						|
#### Deletion after a node  
 | 
						|
 | 
						|
    // Delete a node with given data
 | 
						|
    void del(int data){
 | 
						|
 | 
						|
        // Start from the first node
 | 
						|
    struct node* current = head;
 | 
						|
    struct node* previous = NULL;
 | 
						|
 | 
						|
    // If list is empty
 | 
						|
    if(head == NULL){
 | 
						|
        std::cout << "List is empty" << std::endl;
 | 
						|
        return ;
 | 
						|
    }
 | 
						|
 | 
						|
    // Navigate through list
 | 
						|
    while(current->data != data){
 | 
						|
 | 
						|
        // If it is last node
 | 
						|
        if(current->next == NULL){
 | 
						|
            std::cout << "Element not found" << std::endl;
 | 
						|
            return ;
 | 
						|
        }
 | 
						|
        else {
 | 
						|
            // Store reference to current node
 | 
						|
            previous = current;
 | 
						|
            // Move to next node
 | 
						|
            current = current->next;
 | 
						|
        }
 | 
						|
 | 
						|
    }
 | 
						|
 | 
						|
    // Found a match, update the node
 | 
						|
    if(current == head) {
 | 
						|
        // Change head to point to next node
 | 
						|
        head = head->next;
 | 
						|
    }
 | 
						|
    else {
 | 
						|
        // Skip the current node
 | 
						|
        previous->next = current->next;
 | 
						|
    }
 | 
						|
 | 
						|
    // Free space used by deleted node
 | 
						|
    current = NULL;
 | 
						|
    delete current;
 | 
						|
    std::cout << "Deleted succesfully" << std::endl;
 | 
						|
    }
 | 
						|
 | 
						|
 <a href='https://repl.it/CXVt/1' target='_blank' rel='nofollow'>Run Code</a>
 | 
						|
 | 
						|
### Python Implementation of Singly Linked List  
 | 
						|
 | 
						|
    class Node(object):
 | 
						|
        # Constructor
 | 
						|
        def __init__(self, data=None, next=None):
 | 
						|
            self.data = data
 | 
						|
            self.next = next
 | 
						|
 | 
						|
        # Function to get data
 | 
						|
    def get_data(self):
 | 
						|
        return self.data
 | 
						|
 | 
						|
    # Function to get next node
 | 
						|
    def get_next(self):
 | 
						|
        return self.next
 | 
						|
 | 
						|
    # Function to set next field
 | 
						|
    def set_next(self, new_next):
 | 
						|
        self.next = new_next
 | 
						|
    class LinkedList(object):
 | 
						|
        def __init__(self, head=None):
 | 
						|
            self.head = head
 | 
						|
 | 
						|
#### Insertion  
 | 
						|
 | 
						|
        # Function to insert data
 | 
						|
    def insert(self, data):
 | 
						|
        # new_node is a object of class Node
 | 
						|
        new_node = Node(data)
 | 
						|
        new_node.set_next(self.head)
 | 
						|
        self.head = new_node
 | 
						|
        print("Node with data " + str(data) + " is created succesfully")
 | 
						|
 | 
						|
#### Size  
 | 
						|
 | 
						|
        # Function to get size
 | 
						|
    def size(self):
 | 
						|
        current = self.head
 | 
						|
        count = 0
 | 
						|
        while current:
 | 
						|
            count += 1
 | 
						|
            current = current.get_next()
 | 
						|
        print("Size of link list is " + str(count))
 | 
						|
 | 
						|
#### Searching  
 | 
						|
 | 
						|
        # Function to search a data
 | 
						|
    def search(self, data):
 | 
						|
        current = self.head
 | 
						|
        found = False
 | 
						|
        while current and found is False:
 | 
						|
            if current.get_data() == data:
 | 
						|
                found = True
 | 
						|
            else:
 | 
						|
                current = current.get_next()
 | 
						|
        if current is None:
 | 
						|
            print("Node with data " + str(data) + " is not present")
 | 
						|
        else:
 | 
						|
            print("Node with data " + str(data) + " is found")
 | 
						|
 | 
						|
#### Deletion after a node  
 | 
						|
 | 
						|
        # Function to delete a node with data
 | 
						|
    def delete(self, data):
 | 
						|
        current = self.head
 | 
						|
        previous = None
 | 
						|
        found = False
 | 
						|
        while current and found is False:
 | 
						|
            if current.get_data() == data:
 | 
						|
                found = True
 | 
						|
            else:
 | 
						|
                previous = current
 | 
						|
                current = current.get_next()
 | 
						|
        if current is None:
 | 
						|
            print("Node with data " + str(data) + " is not in list")
 | 
						|
        elif previous is None:
 | 
						|
            self.head = current.get_next()
 | 
						|
            print("Node with data " + str(data) + " is deleted successfully")
 | 
						|
        else:
 | 
						|
            previous.set_next(current.get_next())
 | 
						|
            print("Node with data " + str(data) + " is deleted successfully")
 | 
						|
 | 
						|
 <a href='https://repl.it/CVq3/2' target='_blank' rel='nofollow'>Run Code</a>
 | 
						|
 | 
						|
**Advantages**
 | 
						|
 | 
						|
1.  Linked lists are a dynamic data structure, which can grow and shrink, allocating and deallocating memory while the program is running.
 | 
						|
2.  Insertion and deletion of node are easily implemented in a linked list at any position.
 | 
						|
 | 
						|
**Disadvantages**
 | 
						|
 | 
						|
1.  They use more memory than arrays because of the memory used by their pointers (`next` and `prev`).
 | 
						|
2.  Random access is not possible in linked list. We have to access nodes sequentially.
 | 
						|
3.  It's more complex than array. If a language supports array bound check automatically, Arrays would serve you better.
 | 
						|
 | 
						|
#### Note
 | 
						|
 | 
						|
We have to use free() in C and delete in C++ to free the space used by deleted node, whereas, in Python and Java free space is collected automatically by garbage collector. |