0% found this document useful (0 votes)
11 views20 pages

Extended Dsa Problems

Uploaded by

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

Extended Dsa Problems

Uploaded by

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

Extended Dsa Problems :

Sorting a linkedlist Using bubblesort:


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

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

def append(self, data):


new_node = Node(data)
if not self.head:
self.head = new_node
else:
current = self.head
while current.next:
current = current.next
current.next = new_node

def sort(self):
if not self.head or not self.head.next:
return # No need to sort if the list has 0 or 1 element

# Bubble sort for linked list


end = None
while end != self.head:
current = self.head
while current.next != end:
if current.data > current.next.data:
# Swap data
current.data, current.next.data = current.next.data, current.data
current = current.next
end = current

def __str__(self):
current = self.head
result = []
while current:
result.append(str(current.data))
current = current.next
return " -> ".join(result) + " -> None"

# Example usage:
ll = LinkedList()
ll.append(30)
ll.append(10)
ll.append(20)
print("Before sorting:")
print(ll)

ll.sort()
print("After sorting:")
print(ll)
Inserting a Node in Sorted Linked List:

class Node:
def __init__(self,data=None):
self.data=data
self.next=None
class LinkedList:
def __init__(self):
self.head=None

def insert(self,data):
new_node=Node(data)
if self.head is None:
self.head=new_node
else:
cur=self.head
while cur.next!=None:
cur=cur.next
new_node.next=cur.next
cur.next=new_node

def insertion_in_sorted_list(self,data):
new_node=Node(data)
if self.head is None:
new_node.next=self.head
self.head=new_node

elif self.head.data>=new_node.data:
new_node.next=self.head
self.head=new_node
else:
cur=self.head
while cur.next is not None and cur.next.data<new_node.data:
cur=cur.next
new_node.next=cur.next
cur.next=new_node
return self.head

def display(self):
cur=self.head
while cur!=None:
print(cur.data,end="->")
cur=cur.next
print(None)
ll=LinkedList()
ll.insert(1)
ll.display()
ll.insert(2)
ll.insert(4)
ll.display()
ll.insertion_in_sorted_list(3)
ll.display()

Reverse a linkedlist using recursion:


def reverse_recursive(self, current, prev=None):
if not current:
self.head = prev
return
next_node = current.next
current.next = prev
self.reverse_recursive(next_node, current)
Reverse a Linked List in groups of given size

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

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

def insert(self, data):


new_node = Node(data)
if self.head is None:
self.head = new_node
else:
cur = self.head
while cur.next != None:
cur = cur.next
new_node.next = cur.next
cur.next = new_node

def reverse(self, head, k):


if head is None:
return None
cur = head
next_node = None
prev = None
count = 0
while cur is not None and count < k:
next_node = cur.next
cur.next = prev
prev = cur
cur = next_node
count += 1
if next_node is not None:
head.next = self.reverse(next_node, k) # Recursively reverse the next part
return prev

def display(self):
cur = self.head
while cur != None:
print(cur.data, end="->")
cur = cur.next
print(None)

# Example usage
ll = LinkedList()
ll.insert(0)
ll.insert(1)
ll.insert(2)
ll.insert(3)
ll.insert(4)
ll.insert(5)
ll.insert(6)
ll.insert(7)
ll.insert(8)
ll.display()

# Reverse in groups of 3
ll.head = ll.reverse(ll.head, 3)
ll.display()

Detect loop in Linked List and return where it begins


Find the middle of a Linked List
Sorting a linkedList: time complexity(n+nlogn+n):
space:O(n)
class Node:
def __init__(self,data=None):
self.data=data
self.next=None
class LinkedList:
def __init__(self):
self.head=None
def insert(self,data):
new_node=Node(data)
if self.head is None:
self.head=new_node
else:
cur=self.head
while cur.next!=None:
cur=cur.next
new_node.next=cur.next
cur.next=new_node
def display(self):
cur=self.head
while cur!=None:
print(cur.data,end='->')
cur=cur.next
print(None)
def sort(self,head):
ele=[]
cur=head
while cur!=None:
ele.append(cur.data)
cur=cur.next
ele.sort()
cur=head
for value in ele:
cur.data=value
cur=cur.next
return head

ll=LinkedList()
ll.insert(5)
ll.insert(9)
ll.insert(4)
ll.insert(2)
ll.insert(11)
ll.display()
ll.sort(ll.head)
ll.display()
Find the middle of a Linked List(Floyds cycle detection algorithm)

Sorting a Linkedlist Using Merge_sort:


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

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

def insert(self, data):


new_node = Node(data)
if not self.head:
self.head = new_node
else:
cur = self.head
while cur.next:
cur = cur.next
cur.next = new_node

def get_middle(self, head):


if not head or not head.next:
return head
slow = head
fast = head.next
while fast and fast.next:
slow = slow.next
fast = fast.next.next
return slow

def merge(self, left, right):


if not left:
return right
if not right:
return left

if left.data < right.data:


result = left
result.next = self.merge(left.next, right)
else:
result = right
result.next = self.merge(left, right.next)

return result

def merge_sort(self, head):


if not head or not head.next:
return head

middle = self.get_middle(head)
next_to_middle = middle.next
middle.next = None # Split the linked list into two halves

left = self.merge_sort(head)
right = self.merge_sort(next_to_middle)

sorted_list = self.merge(left, right)


return sorted_list

def sort(self):
self.head = self.merge_sort(self.head)

def display(self):
cur = self.head
while cur:
print(cur.data, end=" -> ")
cur = cur.next
print("None")
# Example usage
ll = LinkedList()
ll.insert(4)
ll.insert(2)
ll.insert(1)
ll.insert(3)
ll.insert(5)

print("Original List:")
ll.display()

ll.sort()

print("Sorted List:")
ll.display()

Merge two sorted linked-lists:


Stack Data Strucutre:
Valid paranthesis checker:
# retain comments in py code
def ispar(s):
stack = []
for char in s:

# Opening bracket
if char in '({[':
stack.append(char)

# Closing Bracket
elif char in ')}]':

# closing bracket without opening


if not stack:
return False

# Else pop an item check for matching


top = stack.pop()
if (top == '(' and char != ')') or \
(top == '{' and char != '}') or \
(top == '[' and char != ']'):
return False

# If an opening bracket without closing


return len(stack) == 0
s = '{()}[]'

if ispar(s):
print("true")
else:
print("false")

How to Reverse a String using Stack


def reverse(s):
stack=[]
l=len(s)
rev=""
for i in s:
stack.append(i)
print(stack)
while len(stack)!=0:
rev += stack.pop()
print(rev)

s=input("enter a string")
reverse(s)
Postfix to prefix:
def postfix_to_prefix(postfix):
stack = []

# Iterate over each character in the postfix expression


for char in postfix:
if char.isalnum(): # If the character is an operand, push it to the stack
stack.append(char)
else: # If the character is an operator
# Pop the top two elements from the stack
operand2 = stack.pop()
operand1 = stack.pop()
# Form a prefix expression and push it back to the stack
prefix = char + operand1 + operand2
stack.append(prefix)

# The final element in the stack is the prefix expression


return stack[-1]

# Example usage
postfix_expr = "AB+CD-*"
prefix_expr = postfix_to_prefix(postfix_expr)
print("Postfix Expression:", postfix_expr)
print("Prefix Expression:", prefix_expr)
Convert Infix expression to Postfix expression
# Function to return precedence of operators
def prec(c):

if c == '^':
return 3
elif c == '/' or c == '*':
return 2
elif c == '+' or c == '-':
return 1
else:
return -1

# Function to perform infix to postfix conversion


def infixToPostfix(s):
st = []
result = ""

for i in range(len(s)):
c = s[i]

# If the scanned character is


# an operand, add it to the output string.
if (c >= 'a' and c <= 'z') or (c >= 'A' and c <= 'Z') or (c >= '0' and c <= '9'):
result += c

# If the scanned character is an


# ‘(‘, push it to the stack.
elif c == '(':
st.append('(')

# If the scanned character is an ‘)’,


# pop and add to the output string from the stack
# until an ‘(‘ is encountered.
elif c == ')':
while st[-1] != '(':
result += st.pop()
st.pop()

# If an operator is scanned
else:
while st and (prec(c) < prec(st[-1]) or prec(c) == prec(st[-1])):
result += st.pop()
st.append(c)

# Pop all the remaining elements from the stack


while st:
result += st.pop()

print(result)

exp = "a+b*(c^d-e)^(f+g*h)-i"
infixToPostfix(exp)

You might also like