Linked Lists in C++

Mannan Ul Haq
0

What is Linked List?

A linked list is a dynamic data structure used to store a collection of elements. Unlike arrays, linked lists do not store elements in contiguous memory locations. Instead, each element, called a node, contains the data and a reference (or link) to the next node in the sequence. This structure allows for efficient insertion and deletion of elements.


Types of Linked Lists:

1. Singly Linked List

2. Doubly Linked List

3. Circular Linked List


Singly Linked List:

A singly linked list is a linear data structure in which the elements are not stored in contiguous memory locations and each element called nodes is connected only to its next element using a pointer.

Each node contains two parts:

1. Data: The value stored in the node.

2. Next: A pointer/reference to the next node in the sequence.


#include <iostream>
using namespace std;

class Node
{
    int data;      // Data part of the node
    Node* next;    // Pointer to the next node

    // Make LinkedList a friend class to access private members
    friend class LinkedList;
};

class LinkedList
{
    Node* head;    // Pointer to the first node in the list

public:
    // Constructor to initialize the head pointer
    LinkedList() {
        head = nullptr;
    }

    // Insert a new node at the beginning of the list
    bool insertAtStart(int val) {
        Node* newNode = new Node;
        newNode->data = val;
        newNode->next = head;
        head = newNode;
        return true;
    }

    // Delete the first node of the list
    bool deleteFromStart() {
        if (head == nullptr) {
            return false;
        } else {
            Node* Start = head;
            head = head->next;
            delete Start;
            return true;
        }
    }

    // Insert a new node at the end of the list
    bool insertAtEnd(int val) {
        Node* newNode = new Node;
        newNode->data = val;
        newNode->next = nullptr;

        if (head == nullptr) {
            head = newNode;
            return true;
        } else {
            Node* Curr = head;
            while (Curr->next != nullptr) {
                Curr = Curr->next;
            }

            Curr->next = newNode;
            return true;
        }
    }

    // Delete the last node of the list
    bool deleteFromEnd() {
        if (head == nullptr) {
            return false;
        } else {
            Node* Curr = head, * Prev = nullptr;
            while (Curr->next != nullptr) {
                Prev = Curr;
                Curr = Curr->next;
            }

            if (Prev == nullptr) {
                head = nullptr;
            } else {
                Prev->next = nullptr;
            }

            delete Curr;
            Curr = nullptr;
            return true;
        }
    }

    // Insert a new node after a specific value
    bool insertAfterSpecificValue(int Sval, int Nval) {
        Node* newNode = new Node;
        newNode->data = Nval;
        newNode->next = nullptr;

        if (head == nullptr) {
            head = newNode;
            return true;
        }

        Node* Curr = head;
        while (Curr != nullptr) {
            if (Curr->data == Sval) {
                newNode->next = Curr->next;
                Curr->next = newNode;
                return true;
            }
            Curr = Curr->next;
        }
        return false;
    }

    // Reverse the linked list
    bool ReverseList() {
        if (head == nullptr) {
            return false;
        } else if (head->next == nullptr) {
            return true;
        } else {
            Node* Curr = head, * Next = nullptr, * Prev = nullptr;
            while (Curr != nullptr) {
                Next = Curr->next;
                Curr->next = Prev;
                Prev = Curr;
                Curr = Next;
            }

            head = Prev;
            return true;
        }
    }

    // Sort the linked list
    bool SortList() {
        if (head == nullptr) {
            return false;
        } else if (head->next == nullptr) {
            return true;
        } else {
            Node* Curr = head;
            while (Curr->next != nullptr) {
                Node* Next = Curr->next;
                while (Next != nullptr) {
                    if (Next->data < Curr->data) {
                        swap(Next->data, Curr->data);
                    }
                    Next = Next->next;
                }
                Curr = Curr->next;
            }
            return true;
        }
    }

    // Merge another linked list into this one
    void MergeLists(LinkedList* L2) {
        if (head == nullptr || L2->head == nullptr)
            return;

        Node* Curr1 = head;
        while (Curr1->next != nullptr)
            Curr1 = Curr1->next;

        Curr1->next = L2->head;
        L2->head = nullptr;
    }

    // Remove duplicate values from the list
    bool RemoveDuplicates() {
        if (head == nullptr)
            return false;

        Node* Curr1 = head;
        while (Curr1 != nullptr) {
            Node* Prev = Curr1;
            Node* Curr2 = Curr1->next;

            while (Curr2 != nullptr) {
                if (Curr2->data == Curr1->data) {
                    Prev->next = Curr2->next;
                    delete Curr2;
                    Curr2 = Prev->next;
                } else {
                    Prev = Curr2;
                    Curr2 = Curr2->next;
                }
            }

            Curr1 = Curr1->next;
        }

        return true;
    }

    // Display the elements of the list
    void Display() {
        if (head == nullptr) {
            cout << "List is Empty!" << endl;
        } else {
            Node* Curr = head;
            while (Curr != nullptr) {
                cout << Curr->data << " ";
                Curr = Curr->next;
            }
            cout << endl;
        }
    }

    // Destructor to clean up the list
    ~LinkedList() {
        while (head != nullptr) {
            Node* Curr = head;
            head = head->next;
            delete Curr;
        }
    }
};

int main() {
    LinkedList List1;
    List1.insertAtEnd(1);
    List1.insertAtEnd(2);
    List1.insertAtEnd(3);
    List1.insertAtEnd(4);
    List1.insertAtEnd(3);
    List1.insertAtEnd(4);
    List1.insertAtEnd(3);

    List1.Display();

    return 0;
}

Doubly Linked List:

Doubly Linked List is a variation of linked list in which navigation is possible in both ways, either forward and backward easily as compared to singly linked list.

Each node contains three parts:

1. Data: The value stored in the node.

2. Next: A pointer/reference to the next node in the sequence.

3. Previous: A pointer/reference to the previous node in the sequence.


#include <iostream>
using namespace std;

// Forward declaration of DoublyLinkedList class
class DoublyLinkedList;

class DNode {
    int Data;      // Data part of the node
    DNode* Next;   // Pointer to the next node
    DNode* Prev;   // Pointer to the previous node

    // Make DoublyLinkedList a friend class to access private members
    friend class DoublyLinkedList;
};

class DoublyLinkedList {
    DNode* Head;   // Pointer to the first node in the list

public:
    // Constructor to initialize the head pointer
    DoublyLinkedList() {
        Head = nullptr;
    }

    // Insert a new node at the beginning of the list
    bool insertAtStart(int Value) {
        DNode* newNode = new DNode;
        newNode->Data = Value;
        newNode->Next = Head;
        newNode->Prev = nullptr;

        if (Head != nullptr) {
            Head->Prev = newNode;
        }

        Head = newNode;

        return true;
    }

    // Insert a new node at the end of the list
    bool insertAtEnd(int Value) {
        DNode* newNode = new DNode;
        newNode->Data = Value;
        newNode->Next = nullptr;

        if (Head == nullptr) {
            newNode->Prev = nullptr;
            Head = newNode;
            return true;
        } else {
            DNode* Curr = Head;
            while (Curr->Next != nullptr) {
                Curr = Curr->Next;
            }

            Curr->Next = newNode;
            newNode->Prev = Curr;
            return true;
        }
    }

    // Insert a new node in a sorted order
    bool sortedInsert(int Value) {
        DNode* newNode = new DNode;
        newNode->Data = Value;

        if (Head == nullptr || Value <= Head->Data) {
            newNode->Next = Head;
            newNode->Prev = nullptr;

            if (Head != nullptr) {
                Head->Prev = newNode;
            }

            Head = newNode;

            return true;
        } else {
            DNode* Curr = Head;
            while (Curr->Next != nullptr && Curr->Next->Data <= Value) {
                Curr = Curr->Next;
            }

            newNode->Next = Curr->Next;
            newNode->Prev = Curr;

            if (Curr->Next != nullptr) {
                Curr->Next->Prev = newNode;
            }

            Curr->Next = newNode;

            return true;
        }
    }

    // Delete the first node of the list
    bool deleteFromStart() {
        if (Head == nullptr) {
            cout << "List is Empty!" << endl;
            return false;
        } else {
            DNode* Temp = Head;
            Head = Head->Next;

            if (Head != nullptr) {
                Head->Prev = nullptr;
            }

            delete Temp;

            return true;
        }
    }

    // Delete the last node of the list
    bool deleteFromEnd() {
        if (Head == nullptr) {
            cout << "List is Empty!" << endl;
            return false;
        } else {
            if (Head->Next == nullptr) {
                delete Head;
                Head = nullptr;
            } else {
                DNode* Curr = Head;
                while (Curr->Next != nullptr) {
                    Curr = Curr->Next;
                }

                Curr->Prev->Next = nullptr;
                delete Curr;
            }

            return true;
        }
    }

    // Search for a node with a specific value
    DNode* Search(int Value) {
        DNode* Curr = Head;
        while (Curr != nullptr) {
            if (Curr->Data == Value) {
                return Curr;
            }
            Curr = Curr->Next;
        }
        return nullptr;
    }

    // Delete a node with a specific value
    bool deleteSpecificValue(int Value) {
        DNode* Temp = Search(Value);

        if (Temp == nullptr) {
            cout << "The Value " << Value << " not found in the List!" << endl;
            return false;
        }

        if (Temp->Prev != nullptr) {
            Temp->Prev->Next = Temp->Next;
        } else {
            Head = Temp->Next;
        }

        if (Temp->Next != nullptr) {
            Temp->Next->Prev = Temp->Prev;
        }

        delete Temp;

        return true;
    }

    // Display the elements of the list
    void Display() {
        if (Head == nullptr) {
            cout << "List is Empty!" << endl;
        } else {
            cout << "List: ";
            DNode* Curr = Head;
            while (Curr != nullptr) {
                cout << Curr->Data << " ";
                Curr = Curr->Next;
            }
            cout << endl;
        }
    }

    // Get the number of nodes in the list
    int Size() {
        if (Head == nullptr) {
            return 0;
        } else {
            int size = 0;
            DNode* Curr = Head;
            while (Curr != nullptr) {
                size++;
                Curr = Curr->Next;
            }
            return size;
        }
    }

    // Destructor to clean up the list
    ~DoublyLinkedList() {
        while (Head != nullptr) {
            DNode* Curr = Head;
            Head = Head->Next;
            delete Curr;
        }
    }
};

int main() {
    DoublyLinkedList List1;
    List1.insertAtEnd(2);
    List1.insertAtEnd(3);
    List1.insertAtEnd(3);
    List1.insertAtEnd(5);
    List1.insertAtEnd(6);
    List1.insertAtEnd(7);
    List1.insertAtEnd(8);

    List1.Display();

    return 0;
}

Circular Singly Linked List:

The Circular Linked List is a list where all nodes are connected to form a circle. In a circular singly linked list, the first node and the last node are connected to each other which forms a circle. There is no NULL at the end.

#include <iostream>
using namespace std;

class Node {
private:
    int data;   // Data part of the node
    Node* next; // Pointer to the next node

    friend class CircularSinglyLinkedList; // Make CircularSinglyLinkedList a friend class to access private members
};

class CircularSinglyLinkedList {
private:
    Node* head; // Pointer to the last node in the list

public:
    // Constructor to initialize the head pointer
    CircularSinglyLinkedList() {
        head = nullptr;
    }

    // Check if the list is empty
    bool isEmpty() {
        return head == nullptr;
    }

    // Insert a new node at the beginning of the list
    void insertAtStart(int val) {
        Node* newNode = new Node;
        newNode->data = val;

        if (isEmpty()) {
            newNode->next = newNode;
            head = newNode;
        } else {
            newNode->next = head->next;
            head->next = newNode;
        }
    }

    // Insert a new node at the end of the list
    void insertAtEnd(int val) {
        Node* newNode = new Node;
        newNode->data = val;

        if (isEmpty()) {
            newNode->next = newNode;
            head = newNode;
        } else {
            newNode->next = head->next;
            head->next = newNode;
            head = newNode;
        }
    }

    // Print the elements of the list from head to end
    void Display() {
        if (isEmpty()) {
            cout << "List is Empty!" << endl;
        } else {
            Node* curr = head->next;

            do {
                cout << curr->data << " ";
                curr = curr->next;
            } while (curr != head->next);

            cout << endl;
        }
    }

    // Delete a node from the beginning of the list
    void deleteFromStart() {
        if (!isEmpty()) {
            Node* temp = head->next;

            if (temp == head) {
                delete temp;
                head = nullptr;
            } else {
                head->next = temp->next;
                delete temp;
            }
        }
    }

    // Destructor to clean up the list
    ~CircularSinglyLinkedList() {
        while (!isEmpty()) {
            deleteFromStart();
        }
    }
};

int main() {
    CircularSinglyLinkedList list;
    list.insertAtEnd(1);
    list.insertAtEnd(2);
    list.insertAtEnd(3);
    list.Display(); // Output: 1 2 3

    list.insertAtStart(0);
    list.Display(); // Output: 0 1 2 3

    list.deleteFromStart();
    list.Display(); // Output: 1 2 3

    return 0;
}

Circular Doubly Linked List:

Circular Doubly Linked List has properties of both doubly linked list and circular singly linked list or circular linked list in which two consecutive elements are linked by the previous and next pointer and the last node points to the first node by the next pointer and also the first node points to the last node by the previous pointer.

#include <iostream>
using namespace std;

class CDNode {
private:
    int data;      // Data part of the node
    CDNode* next;  // Pointer to the next node
    CDNode* prev;  // Pointer to the previous node

    friend class CircularDoublyLinkedList; // Make CircularDoublyLinkedList a friend class to access private members
};

class CircularDoublyLinkedList {
private:
    CDNode* head;   // Pointer to the first node in the list

public:
    // Constructor to initialize the head pointer
    CircularDoublyLinkedList() {
        head = nullptr;
    }

    // Insert a new node at the beginning of the list
    bool insertAtHead(int value) {
        CDNode* newNode = new CDNode;
        newNode->data = value;
        newNode->next = head;
        newNode->prev = nullptr;

        if (head == nullptr) {
            head = newNode;
            newNode->next = newNode;
            newNode->prev = newNode;
        } else {
            CDNode* lastNode = head->prev;
            newNode->next = head;
            newNode->prev = lastNode;
            head->prev = newNode;
            lastNode->next = newNode;
            head = newNode;
        }

        return true;
    }

    // Insert a new node at the end of the list
    bool insertAtEnd(int value) {
        CDNode* newNode = new CDNode;
        newNode->data = value;
        newNode->next = nullptr;
        newNode->prev = nullptr;

        if (head == nullptr) {
            head = newNode;
            head->next = head;
            head->prev = head;
        } else {
            CDNode* lastNode = head->prev;
            newNode->next = head;
            newNode->prev = lastNode;
            head->prev = newNode;
            lastNode->next = newNode;
        }

        return true;
    }

    // Print the elements of the list from head to end
    void Print() {
        if (head == nullptr) {
            cout << "List is Empty!" << endl;
        } else {
            CDNode* curr = head;

            do {
                cout << curr->data << " ";
                curr = curr->next;
            } while (curr != head);

            cout << endl;
        }
    }

    // Search for a node with a specific value
    bool Search(int value) {
        if (head == nullptr) {
            return false;
        }

        CDNode* curr = head;
        do {
            if (curr->data == value) {
                return true;
            }
            curr = curr->next;
        } while (curr != head);

        return false;
    }

    // Erase a node with a specific value
    bool Erase(int value) {
        if (head != nullptr) {
            CDNode* curr = head;
            do {
                if (curr->data == value) {
                    if (curr == head) {
                        head = head->next;
                    }
                    CDNode* prevNode = curr->prev;
                    CDNode* nextNode = curr->next;
                    prevNode->next = nextNode;
                    nextNode->prev = prevNode;
                    delete curr;

                    return true;
                }
                curr = curr->next;

            } while (curr != head);
        }

        return false;
    }

    // Print the elements of the list from end to head
    void printBack() {
        if (head == nullptr) {
            cout << "List is Empty!" << endl;
        } else {
            CDNode* curr = head->prev;

            do {
                cout << curr->data << " ";
                curr = curr->prev;
            } while (curr != head->prev);

            cout << endl;
        }
    }

    // Insert a new node after a specific key
    bool insertAfter(int key, int value) {
        if (head != nullptr) {
            CDNode* curr = head;

            do {
                if (curr->data == key) {
                    CDNode* newNode = new CDNode;
                    newNode->data = value;
                    newNode->next = curr->next;
                    newNode->prev = curr;
                    curr->next->prev = newNode;
                    curr->next = newNode;

                    return true;
                }
                curr = curr->next;

            } while (curr != head);
        }

        return false;
    }

    // Get the number of nodes in the list
    int Size() {
        if (head == nullptr) {
            return 0;
        }

        int count = 0;
        CDNode* current = head;
        do {
            count++;
            current = current->next;
        } while (current != head);

        return count;
    }

    // Destructor to clean up the list
    ~CircularDoublyLinkedList() {
        if (head == nullptr) {
            return;
        }

        CDNode* current = head;
        CDNode* nextNode;

        do {
            nextNode = current->next;
            delete current;
            current = nextNode;
        } while (current != head);

        head = nullptr;
    }
};
Tags

Post a Comment

0Comments

Post a Comment (0)

#buttons=(Accept !) #days=(20)

Our website uses cookies to enhance your experience. Check Now
Accept !