Delete from the front
- Update the head to the next node.
- The old head becomes unreachable and can be reclaimed.
def delete_front(self):
if self.head is None:
return
self.head = self.head.next
Linked-list structures and operations, followed by stack and queue data structures, their algorithms, applications, and abstract data types.
A linked list is a linear data structure made of nodes. Each node stores data and a pointer to the next node.
Each node has two parts:
A singly linked list can be traversed in one direction. The
head points to the first node, and the last node’s
next pointer is None.
def insert_front(self, data):
new_node = Node(data)
new_node.next = self.head
self.head = new_node
def insert_middle(self, position, data):
if position < 0:
print("Invalid position.")
return
new_node = Node(data)
if position == 0:
new_node.next = self.head
self.head = new_node
return
temp = self.head
for _ in range(position - 1):
if temp is None:
print("Position out of bounds.")
return
temp = temp.next
if temp is None:
print("Position out of bounds.")
return
new_node.next = temp.next
temp.next = new_node
temp keeps the address of node 20 while both links are updated.temp = self.head
while last.next:
last = last.next
last.next = new_node
class Node:
def __init__(self, data):
self.data = data
self.next = None
class LinkedList:
def __init__(self):
self.head = None
def insert_at_end(self, data):
new_node = Node(data)
# If list is empty
if self.head is None:
self.head = new_node
return
# Traverse till the last node
current = self.head
while current.next is not None:
current = current.next
# Insert at the end
current.next = new_node
def traverse(self):
current = self.head
while current is not None:
print(current.data, end=" -> ")
current = current.next
print("None")
if __name__ == "__main__":
ll = LinkedList()
ll.insert_at_end(10)
ll.insert_at_end(20)
ll.insert_at_end(30)
ll.insert_at_end(40)
ll.traverse()
10 -> 20 -> 30 -> 40 -> None
def delete_front(self):
if self.head is None:
return
self.head = self.head.next
def delete_key(self, key):
if self.head is None:
return False
if self.head.data == key:
self.head = self.head.next
return True
temp = self.head
while temp.next and temp.next.data != key:
temp = temp.next
if temp.next is None:
return False
temp.next = temp.next.next
return True
def delete_end(self):
if self.head is None:
return
if self.head.next is None:
self.head = None
return
temp = self.head
while temp.next.next:
temp = temp.next
temp.next = None
class DoublyNode:
def __init__(self, data):
self.data = data
self.next = None
self.prev = None
temp = node B
This version first recurses to the end of the list. The base case makes
the last real node the new head; the suspended assignments
then run in reverse frame order—F3, F2, and F1—to redirect the links.
Nothing is returned: the method changes self.head and the
existing nodes in place.
No reverse link yet
The recursive calls are still moving toward the base case; no reverse link has been written.
A stack is a linear data structure that follows the LIFO principle: Last In, First Out.
Elements are added and removed from the same end, called the top.
if S.top == S.size
error(overflow)
else S.top = S.top + 1
S[S.top] = x
if STACK-EMPTY(S)
error(underflow)
else S.top = S.top - 1
return S[S.top + 1]
if S.top == 0
return TRUE
else return FALSE
S.top points to the top element. S.size is the maximum size of the stack.
5 2 3 * +.A queue is a linear data structure that follows the FIFO principle: First In, First Out.
In a circular queue, location 1 immediately follows location n: the queue wraps around.
Q.head = Q.tail
Q.head = Q.head
Q.tail = Q.head + 1
Q.head = Q.tail + 1
or
(Q.head = 1 and Q.tail = Q.size)
An abstract data type describes the logical behavior of a data structure without specifying its implementation. It defines what operations are available, not how they are implemented.
| Abstract data type | Principle | Operations |
|---|---|---|
| Stack | LIFO | push, pop, peek |
| Queue | FIFO | enqueue, dequeue, peek |