0% found this document useful (0 votes)
22 views15 pages

44 Linked Lists

The document outlines programming tasks related to linked lists, categorized into easy, medium, and hard levels. It includes detailed problem descriptions, algorithms, and code implementations for searching an element, checking if a list is empty, deleting a node without a head pointer, and reversing a linked list in groups of K. Each section provides example usage and expected outputs for clarity.

Uploaded by

sampathsai600
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
22 views15 pages

44 Linked Lists

The document outlines programming tasks related to linked lists, categorized into easy, medium, and hard levels. It includes detailed problem descriptions, algorithms, and code implementations for searching an element, checking if a list is empty, deleting a node without a head pointer, and reversing a linked list in groups of K. Each section provides example usage and expected outputs for clarity.

Uploaded by

sampathsai600
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
You are on page 1/ 15

K.B.

SAI SAMPATH
(VU21BTEN0100030)
S.NO TOPIC PAGE NO
1 1. Search for an
Element in a Singly
(Easy Level Programming Linked List 3-6
Tasks)

2. Check if a Linked
List is Empty
6-9

2 1. Delete a Node
Without Head
(Medium Level Pointer 9-12
Programming Task)

3 1. Reverse a Linked
(Hard Level Programming List in Groups of K
Task) 12-15
ASSIGNMENT – 4
Linked Lists:

Easy Level Programming Tasks

1. Search for an Element in a Singly Linked List


o Problem Description: Write a program to search for a given element in a
linked list.
o Input: A linked list: 1 -> 2 -> 3 -> 4 -> 5 and the element to search: 3
o Expected Output: True
Algorithm:
1. Initialize the Current Node: Start with the head of the linked list.
2. Traverse the Linked List:
o Check if the current node's value matches the target element.
o If it matches, return True.
o Otherwise, move to the next node in the list.
3. End of List:
o If you reach the end of the list (current node is None), return False, indicating
the element is not found.
# Define the Node class
class Node:
def __init__(self, data):
self.data = data
self.next = None
# Define the LinkedList class
class LinkedList:
def __init__(self):
self.head = None

# Method to add a new node to the list


def append(self, data):
new_node = Node(data)
if not self.head:
self.head = new_node
return
current = self.head
while current.next:
current = current.next
current.next = new_node

# Method to search for an element in the list


def search(self, target):
current = self.head
while current:
if current.data == target:
return True
current = current.next
return False

# Example usage
linked_list = LinkedList()
for value in [1, 2, 3, 4, 5]:
linked_list.append(value)
# Search for the element
element_to_search = 3
print(linked_list.search(element_to_search)) # Output: True

OUTPUT:

2. Check if a Linked List is Empty


o Problem Description: Write a program to check whether a given linked list is
empty or not.
o Input: A linked list: None
o Expected Output: True

Algorithm to Check if a Linked List is Empty:

1. Initialize:
o Start by accessing the head of the linked list.
o The head is the first node of the list. If the list is empty, this will be None.
2. Check if the head is None:
o If the head is None, it means the linked list is empty because there are no
nodes in the list.
 Return True (the list is empty).
o If the head is not None, it means there are one or more nodes in the list.
 Return False (the list is not empty).
3. End:
o The check is complete. If the head is None, the list is empty. Otherwise, it
contains at least one node.

CODE:
# Step 1: Define the Node class

class Node:

def __init__(self, data):

self.data = data # Store the value of the node

self.next = None # Initialize next as None (next node is not set yet)

# Step 2: Define the LinkedList class


class LinkedList:

def __init__(self):

self.head = None # Initially, the linked list is empty (head is None)

# Function to check if the linked list is empty

def is_empty(self):

# Step 1: Check if the head is None (list is empty)

if self.head is None:

return True # The list is empty

else:

return False # The list is not empty

# Function to append a new node to the linked list

def append(self, data):

new_node = Node(data) # Create a new node with the given data

if not self.head:

self.head = new_node # If the list is empty, make the new node the head

else:

current = self.head

while current.next: # Traverse until we find the last node

current = current.next

current.next = new_node # Add the new node at the end

# Function to print the linked list

def print_list(self):
current = self.head

while current:

print(current.data, end=" -> ") # Print the current node's data

current = current.next # Move to the next node

print("None") # Indicate the end of the list

# Driver code to test the functionality

if __name__ == "__main__":

ll = LinkedList() # Create an empty linked list

# Step 3: Check if the linked list is empty

print("Is the linked list empty?", ll.is_empty()) # Should print True

# Add some nodes to the linked list

ll.append(10)

ll.append(20)

# Check if the linked list is empty again after adding elements

print("Is the linked list empty?", ll.is_empty()) # Should print False

# Print the linked list

ll.print_list() # Should print: 10 -> 20 -> None

Output :
Medium Level Programming Tasks:
2. Delete a Node Without Head Pointer
o Problem Description: Given access to only a node to be deleted in a linked
list (not the head), delete the node.
o Input: A linked list: 4 -> 5 -> 1 -> 9 and the node 5 to delete.
o Expected Output: 4 -> 1 -> 9

Algorithm:
1. Check if the node is not the last node:
o We cannot delete the last node if we only have access to it. This algorithm
works only if the node is not the last node in the list.
2. Copy the data from the next node to the current node:
o Replace the data in the current node with the data from the next node.
3. Update the next pointer:
o Set the next pointer of the current node to point to the next node’s next node.
4. The node is deleted:
o By copying the next node’s data and bypassing the next node, we have
effectively "deleted" the current node and removed it from the list.
5. End:
o The node is deleted from the linked list.

CODE:
# Step 1: Define the Node class

class Node:

def __init__(self, data):

self.data = data # Store the value of the node

self.next = None # Initialize the next pointer as None


# Step 2: Define the LinkedList class

class LinkedList:

def __init__(self):

self.head = None # Initially, the linked list is empty

# Function to append a new node to the linked list

def append(self, data):

new_node = Node(data) # Create a new node with the given data

if not self.head:

self.head = new_node # If the list is empty, make the new node the head

else:

current = self.head

while current.next: # Traverse until we find the last node

current = current.next

current.next = new_node # Add the new node at the end

# Function to print the linked list

def print_list(self):

current = self.head

while current:

print(current.data, end=" -> ") # Print the current node's data

current = current.next # Move to the next node

print("None") # Indicate the end of the list


# Function to delete a node (without head pointer)

def delete_node(self, node):

# Step 1: Check if the node is not the last one

if node is not None and node.next is not None:

node.data = node.next.data # Step 2: Copy the next node's data to the current node

node.next = node.next.next # Step 3: Bypass the next node

# Driver code to test the functionality

if __name__ == "__main__":

ll = LinkedList() # Create an empty linked list

# Append some nodes to the linked list

ll.append(4)

ll.append(5)

ll.append(1)

ll.append(9)

print("Original Linked List:")

ll.print_list() # Should print: 4 -> 5 -> 1 -> 9 -> None

# Suppose we are asked to delete the node with value 5

node_to_delete = ll.head.next # This is the node with value 5

# Delete the node with value 5


ll.delete_node(node_to_delete)

print("Linked List after deleting node 5:")

ll.print_list() # Should print: 4 -> 1 -> 9 -> None

OUTPUT:

Hard Level Programming Tasks:


2. Reverse a Linked List in Groups of K
o Problem Description: Reverse the nodes of a linked list in groups of size K.
o Input:
o List: 1 -> 2 -> 3 -> 4 -> 5 -> 6 -> 7 -> 8

o K: 3

o Expected Output: 3 -> 2 -> 1 -> 6 -> 5 -> 4 -> 8 -> 7

Algorithm:

1. Define the Problem Constraints:


o If there are fewer than K nodes left in the list, do not reverse them.
o If there are exactly K nodes or more in the current segment, reverse that
segment.
2. Reverse a Sublist of K nodes:
o Given the current head of a sublist, reverse it using the standard method of
altering the next pointers.
o Once the sublist is reversed, reconnect it with the rest of the list.
3. Break Down the Process:
oUse a dummy node: To handle edge cases, such as when the head of the list
changes after the first group reversal, we use a dummy node. This dummy
node will simplify managing the head of the list.
o Group-wise Reversal: Process the list in chunks of K nodes. For each chunk,
reverse the K nodes, and then reconnect them properly.
4. Reconnection after Reversal:
o After reversing a group, the last node of that group should point to the
remaining list, and the previous group should be connected to the first node of
the reversed group.

CODE:

class ListNode:

def __init__(self, val=0, next=None):

self.val = val

self.next = next

def reverseKGroup(head, k):

# Step 1: Check if the list is empty or if K is 1 (no reversal needed)

if not head or k == 1:

return head

# Step 2: Create a dummy node to simplify edge cases (e.g., if the head of the list changes)

dummy = ListNode(0)

dummy.next = head

prev_group_end = dummy # This will point to the node before the current group to
reverse

# Step 3: Traverse the list in groups of K nodes

current = head

while current:

# Step 3a: Find the Kth node in the current group


group_end = current

for _ in range(k - 1):

group_end = group_end.next

if not group_end: # If there are less than K nodes remaining, no need to reverse

return dummy.next

# Step 3b: Save the next node after the current group

next_group_start = group_end.next

# Step 3c: Reverse the current group

prev, curr = None, current

while curr != next_group_start:

next_node = curr.next

curr.next = prev

prev = curr

curr = next_node

# Step 3d: Connect the reversed group to the rest of the list

prev_group_end.next = prev

current.next = next_group_start

# Step 3e: Move prev_group_end to the end of the reversed group

prev_group_end = current

current = next_group_start # Move to the next group


# Return the new head of the list (dummy.next points to the new head)

return dummy.next

# Helper function to print the linked list

def print_linked_list(head):

while head:

print(head.val, end=" -> " if head.next else "")

head = head.next

print()

# Example usage:

# Constructing the linked list: 1 -> 2 -> 3 -> 4 -> 5 -> 6 -> 7 -> 8

head = ListNode(1)

head.next = ListNode(2)

head.next.next = ListNode(3)

head.next.next.next = ListNode(4)

head.next.next.next.next = ListNode(5)

head.next.next.next.next.next = ListNode(6)

head.next.next.next.next.next.next = ListNode(7)

head.next.next.next.next.next.next.next = ListNode(8)

k=3

print("Original List:")

print_linked_list(head)
# Reverse the linked list in groups of k

new_head = reverseKGroup(head, k)

print(f"List after reversing in groups of {k}:")

print_linked_list(new_head)

OUTPUT :

You might also like