Join Regular Classroom : Visit ClassroomTech

Data Structure – codewindow.in

Related Topics

Data Structure

What is a linked list and how is it implemented?

A linked list is a data structure that consists of a sequence of nodes, each containing a value and a reference to the next node in the sequence. The first node in the sequence is called the head, and the last node in the sequence is called the tail. Unlike an array, which stores its elements in a contiguous block of memory, a linked list stores its elements in separate nodes that are scattered throughout memory.

There are two main types of linked lists: singly linked lists and doubly linked lists. In a singly linked list, each node contains a reference to the next node in the sequence, while in a doubly linked list, each node contains references to both the next and previous nodes in the sequence.

Here is an example implementation of a singly linked list in Python:

class Node:
    def __init__(self, value):
        self.value = value
        self.next = None

class LinkedList:
    def __init__(self):
        self.head = None

    def insert_at_beginning(self, value):
        new_node = Node(value)
        new_node.next = self.head
        self.head = new_node

    def insert_at_end(self, value):
        new_node = Node(value)
        if not self.head:
            self.head = new_node
            return
        current_node = self.head
        while current_node.next:
            current_node = current_node.next
        current_node.next = new_node

    def delete_node(self, value):
        if not self.head:
            return
        if self.head.value == value:
            self.head = self.head.next
            return
        current_node = self.head
        while current_node.next:
            if current_node.next.value == value:
                current_node.next = current_node.next.next
                return
            current_node = current_node.next

    def print_list(self):
        current_node = self.head
        while current_node:
            print(current_node.value)
            current_node = current_node.next

This implementation defines a Node class that contains a value and a reference to the next node in the sequence, and a LinkedList class that contains a reference to the head of the list. The LinkedList class provides methods for inserting nodes at the beginning or end of the list, deleting nodes with a specific value, and printing the contents of the list.

To insert a node at the beginning of the list, we create a new node with the given value and set its next attribute to the current head of the list. To insert a node at the end of the list, we traverse the list starting from the head until we find the last node, and then set its next attribute to the new node. To delete a node with a specific value, we traverse the list starting from the head until we find the node with the given value, and then set its next attribute to the node after it. To print the contents of the list, we traverse the list starting from the head and print the value of each node.

What is a doubly linked list and how is it implemented?

A doubly linked list is a type of linked list in which each node contains two references, one to the next node in the sequence and one to the previous node in the sequence. This allows for more efficient traversal of the list in both directions compared to a singly linked list, at the cost of increased memory usage due to the additional reference in each node.

Here is an example implementation of a doubly linked list in Python:

class Node:
    def __init__(self, value):
        self.value = value
        self.next = None
        self.prev = None

class DoublyLinkedList:
    def __init__(self):
        self.head = None
        self.tail = None

    def insert_at_beginning(self, value):
        new_node = Node(value)
        if not self.head:
            self.head = new_node
            self.tail = new_node
        else:
            new_node.next = self.head
            self.head.prev = new_node
            self.head = new_node

    def insert_at_end(self, value):
        new_node = Node(value)
        if not self.tail:
            self.head = new_node
            self.tail = new_node
        else:
            new_node.prev = self.tail
            self.tail.next = new_node
            self.tail = new_node

    def delete_node(self, value):
        if not self.head:
            return
        if self.head.value == value:
            self.head = self.head.next
            self.head.prev = None
            return
        current_node = self.head
        while current_node.next:
            if current_node.next.value == value:
                current_node.next = current_node.next.next
                if current_node.next:
                    current_node.next.prev = current_node
                else:
                    self.tail = current_node
                return
            current_node = current_node.next

    def print_list(self):
        current_node = self.head
        while current_node:
            print(current_node.value)
            current_node = current_node.next

This implementation is similar to the singly linked list implementation, but with the addition of a prev attribute in each node and some modifications to the insertion and deletion methods to handle the prev references.

To insert a node at the beginning of the list, we create a new node with the given value and set its next attribute to the current head of the list and its prev attribute to None. If the list is empty, we also set the tail attribute to the new node. To insert a node at the end of the list, we create a new node with the given value and set its prev attribute to the current tail of the list and its next attribute to None. If the list is empty, we also set the head attribute to the new node. To delete a node with a specific value, we traverse the list starting from the head until we find the node with the given value, and then update its prev and next references to remove it from the list. If the node is the head of the list, we update the head attribute to the next node in the sequence and set its prev attribute to None. If the node is the tail of the list, we update the tail attribute to the previous node in the sequence. To print the contents of the list, we traverse the list starting from the head and print the value of each node.

What is a circular linked list and how is it implemented?

A circular linked list is a type of linked list in which the last node of the list points back to the first node, forming a loop. This means that traversal of the list can be continuous, with the last node pointing back to the first node and the first node pointing to the next node in the sequence.

Here is an example implementation of a circular linked list in Python:

class Node:
    def __init__(self, value):
        self.value = value
        self.next = None

class CircularLinkedList:
    def __init__(self):
        self.head = None
        self.tail = None

    def insert_at_beginning(self, value):
        new_node = Node(value)
        if not self.head:
            self.head = new_node
            self.tail = new_node
            new_node.next = self.head
        else:
            new_node.next = self.head
            self.head = new_node
            self.tail.next = self.head

    def insert_at_end(self, value):
        new_node = Node(value)
        if not self.tail:
            self.head = new_node
            self.tail = new_node
            new_node.next = self.head
        else:
            self.tail.next = new_node
            self.tail = new_node
            self.tail.next = self.head

    def delete_node(self, value):
        if not self.head:
            return
        if self.head.value == value:
            self.head = self.head.next
            self.tail.next = self.head
            return
        current_node = self.head
        while current_node.next != self.head:
            if current_node.next.value == value:
                current_node.next = current_node.next.next
                return
            current_node = current_node.next
        if self.tail.value == value:
            self.tail = current_node
            self.tail.next = self.head

    def print_list(self):
        current_node = self.head
        while current_node:
            print(current_node.value)
            current_node = current_node.next
            if current_node == self.head:
                break

This implementation is similar to the singly linked list implementation, with some modifications to handle the circular nature of the list. To insert a node at the beginning of the list, we create a new node with the given value and set its next attribute to the current head of the list. If the list is empty, we also set the tail attribute to the new node and its next attribute to itself to form the loop. To insert a node at the end of the list, we create a new node with the given value and set its next attribute to the current head of the list. If the list is empty, we also set the head attribute to the new node and its next attribute to itself to form the loop. To delete a node with a specific value, we traverse the list starting from the head until we find the node with the given value, and then update its next reference to remove it from the list. If the node is the head of the list, we update the head attribute to the next node in the sequence and update the next reference of the tail node to the new head node to maintain the loop. If the node is the tail of the list, we update the tail attribute to the previous node in the sequence and update its next reference to the new head node to maintain the loop. To print the contents of the list, we traverse the list starting from the head and print the value of each node until we reach the head node again to avoid an infinite loop.

What is a stack implemented using a linked list?

A stack is a data structure that follows the Last-In-First-Out (LIFO) principle, which means that the last element inserted is the first one to be removed. A stack implemented using a linked list is a linked list in which insertion and deletion are performed at one end of the list, called the “top” of the stack.

Here is an example implementation of a stack using a singly linked list in Python:

class Node:
    def __init__(self, value):
        self.value = value
        self.next = None

class Stack:
    def __init__(self):
        self.top = None

    def push(self, value):
        new_node = Node(value)
        new_node.next = self.top
        self.top = new_node

    def pop(self):
        if not self.top:
            return None
        value = self.top.value
        self.top = self.top.next
        return value

    def peek(self):
        if not self.top:
            return None
        return self.top.value

    def is_empty(self):
        return self.top is None

In this implementation, the Stack class has a single instance variable top that points to the top of the stack. When we push a new element onto the stack, we create a new node with the given value and set its next attribute to the current top node. Then, we set the top node to be the new node, effectively making it the new top of the stack. When we pop an element from the stack, we return the value of the top node and update top to point to the next node in the stack. If the stack is empty, we return None. The peek method returns the value of the top node without removing it from the stack. Finally, the is_empty method checks if the top node is None to determine if the stack is empty.

Questions on Chapter 1

Questions on Chapter 1

      

We Love to Support you

Go through our study material. Your Job is awaiting.

Recent Posts
Categories