Download as pdf or txt
Download as pdf or txt
You are on page 1of 54

Computer Programming, Algorithms and Data Structure – Mod.

2:

Algorithms and Data Structures


Linear Data Structures

Prof. Piercarlo Dondi – A.Y. 2022/23


Summary

 Definition of linear data structures

 Main linear data structures ADT:


Stacks
Queues
Deques
Arrays
Lists

 Operations on linear data structures

Slides based on Chapter 4 of


“Problem Solving with Algorithms and Data Structures using Python”
by Bradley N. Miller, David L. Ranum
Piercarlo Dondi – Algorithms and Data Structures: Linear Data Structures – A.Y. 2022/23
Linear Data Structures

 In linear data structures items are arranged sequentially


and each item is attached to its previous and next items

 Linear structures have two “ends”:


“left”, “right”
“top”, “bottom”
“head”, “tail”
 etc.

 We can distinguish linear data structures by the way in


which they add and remove item:
A structure might allow new items to be added at only one end and
removed from the other one
Some structures might allow items to be added and removed from
either ends
etc.

Piercarlo Dondi – Algorithms and Data Structures: Linear Data Structures – A.Y. 2022/23
Stack

 A stack is a collection of items where the addition of a new item


and the removal of an existing item always takes place at the
same end
The order of insertion is the reverse of the order of removal
This kind of ordering is generally called LIFO (Last In, First Out)

Newest element

Oldest element

Piercarlo Dondi – Algorithms and Data Structures: Linear Data Structures – A.Y. 2022/23
Stack

3 Push
3
2 Push
2 2
1 1 1

Pop 3

2
Pop 2

1 1 1

Piercarlo Dondi – Algorithms and Data Structures: Linear Data Structures – A.Y. 2022/23
Stack

Operations of Stack ADT

Operation Effect
Stack() Creates a new empty stack

push(item) Adds a new item to the top of the stack

pop() Removes the top item from the stack and returns it

peak() Returns the top item from the stack but does not remove it

isEmpty() Returns True if the stack is empty, False otherwise

size() Returns the number of items in the stack

Piercarlo Dondi – Algorithms and Data Structures: Linear Data Structures – A.Y. 2022/23
Stack

Example
Operation Stack content Returned value

s = Stack() []

s.isEmpty() [] True

s.push(2) [2]

s.push(‘hello’) [2, ‘hello’]

s.push(5.4) [2, ‘hello’, 5.4]

s.size() [2, ‘hello’, 5.4] 3

s.peak() [2, ‘hello’, 5.4] 5.4

s.pop() [2, ‘hello’] 5.4

Note as peak() return the top element but


does not modify the stack

Piercarlo Dondi – Algorithms and Data Structures: Linear Data Structures – A.Y. 2022/23
Stack
A possible Python implementation

class Stack:
def __init__(self):
self.items = []

def isEmpty(self): Check if the stack is empty


return self.items == []

def push(self, item):


self.items.append(item) Insert an element

def pop(self):
Remove and return the last
return self.items.pop()
element
def peek(self):
if len(self.items)>0: Return the last element, but
return self.items[-1] does not remove it

def size(self):
return len(self.items)

Piercarlo Dondi – Algorithms and Data Structures: Linear Data Structures – A.Y. 2022/23
Example: Balanced parentheses

 Problem – check if a string contains a balanced number of


parentheses

 For example:
“( () () )” is correct
“( ( ( ( ) ” is not correct
“( [ ] { } )” is correct
“( [ [ { } ) } ” is not correct

Piercarlo Dondi – Algorithms and Data Structures: Linear Data Structures – A.Y. 2022/23
Example: Balanced parentheses

openers = ["(", "[", "{"]


closers = [")", "]", "}"]

def parChecker(symbols_string):
s = Stack()
index = 0

for symbol in symbols_string:


if symbol in openers: If the current symbol is an opening
s.push(symbol) parenthesis, it is pushed in the stack
else:
if s.isEmpty():
return False
else:
top = s.pop() If the current symbol is a closing, check if the
if not matches(top, symbol): element on top of the stack is an opening of
return False the correct type
index = index + 1

if s.isEmpty():
return True

def matches(open, close): The match is done comparing the indexes of


return openers.index(open) == closers.index(close) the two lists corresponding to the current
open and close elements

Piercarlo Dondi – Algorithms and Data Structures: Linear Data Structures – A.Y. 2022/23
Queue

 A queue is a collection of items where the addition of a new


item happens at one end (“rear” or “back”) and the removal of
an existing item occurs at the other end (“front”)
The order of insertion is the same of the order of removal
This kind of ordering is generally called FIFO (First In, First Out)

Piercarlo Dondi – Algorithms and Data Structures: Linear Data Structures – A.Y. 2022/23
Queue

Enqueue E D C B A

F E D C B A

Dequeue
F E D C B

A
Piercarlo Dondi – Algorithms and Data Structures: Linear Data Structures – A.Y. 2022/23
Queue

Operations of Queue ADT

Operation Effect
Queue() Creates a new empty queue

enqueue(item) Adds a new item to the rear of the queue

dequeue() Removes and returns the front item of the queue

isEmpty() Returns True if the queue is empty, False otherwise

size() Returns the number of items in the queue

Piercarlo Dondi – Algorithms and Data Structures: Linear Data Structures – A.Y. 2022/23
Queue

Example

Operation Queue content Returned value

q = Queue() []

q.isEmpty() [] True

q.enque(2) [2]

q.enque(‘hello’) [‘hello’, 2]

q.enque(5.4) [5.4, ‘hello’, 2]

q.size() [5.4, ‘hello’, 2] 3

q.deque() [5.4, ‘hello’] 2

q.isEmpty() [5.4, ‘hello’] False

Piercarlo Dondi – Algorithms and Data Structures: Linear Data Structures – A.Y. 2022/23
Queue

A possible python implementation

class Queue:
def __init__(self):
self.items = []

def isEmpty(self): Check if the queue is empty


return self.items == []

def enqueue(self, item):


Insert an element on “rear”
self.items.insert(0,item)

def dequeue(self): Remove and return the current


return self.items.pop() element on “front”
def size(self):
return len(self.items)

Piercarlo Dondi – Algorithms and Data Structures: Linear Data Structures – A.Y. 2022/23
Queue
Comparison with Stack implementation

class Stack: class Queue:


def __init__(self): def __init__(self):
self.items = [] self.items = []

def isEmpty(self): def isEmpty(self):


return self.items == [] return self.items == []

def push(self, item): def enqueue(self, item):


self.items.append(item) self.items.insert(0,item)

def pop(self): def dequeue(self):


return self.items.pop() return self.items.pop()

def size(self): def size(self):


return len(self.items) return len(self.items)

def peek(self):
if len(self.items)>0:
return self.items[-1]

Piercarlo Dondi – Algorithms and Data Structures: Linear Data Structures – A.Y. 2022/23
Example: simulate a print queue

 Problem – simulate the following situation:


A lab printer has a print queue of limited size (e.g., max 5 tasks)
When a new print task arrives:
If the queue is full the printer refuses the task
If the queue is not full the task is enqueued
Periodically, with a 50% probability, either the printer receives a
new task, or a task is completed (i.e., the task in front of the queue
is dequeued)

Piercarlo Dondi – Algorithms and Data Structures: Linear Data Structures – A.Y. 2022/23
Example: simulate a printer
class Printer:
def __init__(self, max_queue_len):
self.printQueue = Queue()
self.max_queue_len = max_queue_len

def addTask(self, task):


if self.printQueue.size() < self.max_queue_len:
self.printQueue.enqueue(task)
print("Task", task, "enqueued")
else:
print("The queue is full, task", task, "refused")

def completeTask(self):
if not self.printQueue.isEmpty():
print("Task", self.printQueue.dequeue(), " printed")

def simulation(tasks_number, max_queue_len):

myprinter = Printer(max_queue_len)

tasks_list = list(range(tasks_number, 0, -1))

while len(tasks_list) > 0:


if random.random() >= 0.5:
myprinter.addTask(task_list.pop())
else:
myprinter.completeTask()

Piercarlo Dondi – Algorithms and Data Structures: Linear Data Structures – A.Y. 2022/23
Example: simulate a printer

2 1

2 1 Task 1 enqueued
Task 2 enqueued
Task 1 printed
Task 3 enqueued
2 1 Task 2 printed
Task 4 enqueued
Task 5 enqueued
Task 6 enqueued
Task 7 enqueued
The queue is full, task 8 refused
8 7 6 5 4 3 Task 3 printed

7 6 5 4 3

Piercarlo Dondi – Algorithms and Data Structures: Linear Data Structures – A.Y. 2022/23
Priority Queue

 A priority queue is a particular kind of queue in which:


Each element of the queue has a priority
The position of an element in the queue depend by its priority
The element with the highest priority is removed first

New element
F
E D C B A F E D C B A
Standard queue

High priority element


F
E D C B A E D C B A F
Priority queue

Piercarlo Dondi – Algorithms and Data Structures: Linear Data Structures – A.Y. 2022/23
Priority Queue

 A priority queue is generally implemented with a heap


data structure

 We will see an implementation of priority queues during


the lectures about Tree data structures

Coming soon…

Piercarlo Dondi – Algorithms and Data Structures: Linear Data Structures – A.Y. 2022/23
Deque

 A deque (pronounced ‘dek’) also known as a double-ended


queue is a structure similar to a queue where items can be
added and removed at either the front or the rear

 It is a sort of “hybrid” between a stack and a queue

Piercarlo Dondi – Algorithms and Data Structures: Linear Data Structures – A.Y. 2022/23
Deque

Operations of Deque ADT

Operation Effect
Deque() Creates a new empty deque

addFront(item) Adds a new item to the front of the deque

addRear(item) Adds a new item to the rear of the deque

removeFront() Removes and returns the front item of the deque

removeRear() Removes and returns the rear item of the deque

isEmpty() Returns True if the deque is empty, False otherwise

size() Returns the number of items in the deque

Piercarlo Dondi – Algorithms and Data Structures: Linear Data Structures – A.Y. 2022/23
Deque

Example

Operation Deque content Returned value

d = Deque() []

d.isEmpty() [] True

d.addRear(2) [2]

d.addRear(‘hello’) [‘hello’, 2]

d.addFront(5.4) [‘hello’, 2, 5.4]

d.size() [5.4, ‘hello’, 2] 3

d.removeFront() [5.4, ‘hello’] 2

d.removeRear() [‘hello’] 5.4

Piercarlo Dondi – Algorithms and Data Structures: Linear Data Structures – A.Y. 2022/23
Deque

A possible python implementation

class Deque:
def __init__(self):
self.items = []

def isEmpty(self):
return self.items == []

def addFront(self, item): Insert an element on “front”


self.items.append(item)

def addRear(self, item): Insert an element on “rear”


self.items.insert(0,item)

def removeFront(self): Remove and return the current


return self.items.pop() element on “front”

def removeRear(self): Remove and return the current


return self.items.pop(0) element on “rear”

def size(self):
return len(self.items)

Piercarlo Dondi – Algorithms and Data Structures: Linear Data Structures – A.Y. 2022/23
Example: Palindrome-checker

 Problem – check if a string is a palindrome, aka it reads the


same forward and backward

 For example:
“radar” is a palindrome
“home ” is not a palindrome

Piercarlo Dondi – Algorithms and Data Structures: Linear Data Structures – A.Y. 2022/23
Example: Palindrome-checker

def palchecker(aString):
charDeque = Deque()

for ch in aString:
charDeque.addRear(ch)

while charDeque.size() > 1:


first = charDeque.removeFront()
last = charDeque.removeRear()
if first != last:
return False

return True

Piercarlo Dondi – Algorithms and Data Structures: Linear Data Structures – A.Y. 2022/23
Arrays

 An array is a linear data structure that consists in a collection of


item accessible by an integer index

elements
10 4 12 75 30 1 27

indexes 0 1 2 3 4 5 6

 In an array, the data are stored in contiguous memory locations


The size of the array is allocated at initialization and cannot be
modified

 Arrays contain elements of homogeneous type


E.g., all integers, all float, all instances of the same class, etc.

Piercarlo Dondi – Algorithms and Data Structures: Linear Data Structures – A.Y. 2022/23
Arrays

 Python has no a build-in implementation of arrays, but Lists


provide arrays functionalities

 However, mathematical Python libraries, like Numpy, supply an


efficient implementation of the array data structure, since it is
useful for mathematical computations

>>> import numpy as np


>>> arr = np.array([[25, 31, 3], [5, 19, 28]])
>>> print(arr)
[ [25 31 3]
[ 5 19 28] ]

Piercarlo Dondi – Algorithms and Data Structures: Linear Data Structures – A.Y. 2022/23
Lists

 A List is a collection of items where each item holds a


relative position with respect to the others
The size of a list is not fixed at the initialization, it can change
dynamically with the addition and removal of elements

 If the list is ordered:


Each item holds a relative position that is based upon some
underlying characteristic of the item
We assume that list items have a meaningful comparison
operator that is already defined

 The first item of a list is generally referred as head while


the last item is generally called end or tail

Piercarlo Dondi – Algorithms and Data Structures: Linear Data Structures – A.Y. 2022/23
Lists
Common operations of Unordered List ADT

Operation Effect
List() Creates a new empty list

add(item) Adds a new item to the list

append(item) Adds a new item to the end of the list

insert(pos, item) Add a new item to the list at position pos

remove(item) Remove the item from the list

pop() Removes and returns the last item in the list

pop(pos) Removes and returns the item at position pos

search(item) Returns True if the item is present, False otherwise

index(item) Return the position of the item in the list

isEmpty() Returns True if the deque is empty, False otherwise

size() Returns the number of items in the deque

Piercarlo Dondi – Algorithms and Data Structures: Linear Data Structures – A.Y. 2022/23
Lists
Common operations of Ordered List ADT

Operation Effect
OrderedList() Creates a new empty ordered list
Adds a new item to the list making sure that the order is
add(item)
preserved
remove(item) Remove the item from the list

pop() Removes and returns the last item in the list

pop(pos) Removes and returns the item at position pos

search(item) Returns True if the item is present, False otherwise

index(item) Return the position of the item in the list

isEmpty() Returns True if the deque is empty, False otherwise

size() Returns the number of items in the deque

Piercarlo Dondi – Algorithms and Data Structures: Linear Data Structures – A.Y. 2022/23
Lists

 Python lists are an implementation of the list ADT


 As seen in the first lecture they are implemented to be fast in appending
new elements and accessing the data
 They are internally represented as arrays, similarly to Vectors in C++ or
ArrayLists in Java

 We will now see a different implementation of the list ADT called


linked list (both unordered and ordered)

 Linked lists are commonly adopted in many applications:


 Undo/Redo functionality
 Back and forward button in a browser
 Music player list
 Implementing other data structures (e.g., stack and queue)
 Etc.

Piercarlo Dondi – Algorithms and Data Structures: Linear Data Structures – A.Y. 2022/23
Linked List

 A Linked List is a linear data structure in which elements


are not stored at a contiguous memory location but are
instead linked using pointers

 The elements of a linked list are generally called nodes

 Each node stores the data and a pointer to the next node

Head Tail

10 25 3 40 12

Piercarlo Dondi – Algorithms and Data Structures: Linear Data Structures – A.Y. 2022/23
Linked List

 The most common types of linked lists are:

Single linked list (the default one for now on)


Head Tail

10 25 3 40 12

Doubly linked list


Head Tail

10 25 3 40 12

Circular linked list


Head Tail

10 25 3 40 12

Piercarlo Dondi – Algorithms and Data Structures: Linear Data Structures – A.Y. 2022/23
Linked List (unordered)

 We want to create an unordered linked list where each


element is connected to the next one until the last item

 We must maintain the relative position of the items, but


there is no need of contiguous memory positioning

 For simplicity we assume that no duplicate item is allowed

Piercarlo Dondi – Algorithms and Data Structures: Linear Data Structures – A.Y. 2022/23
Linked List (unordered)
class Node:
Node def __init__(self,initData):
self.data = initData
self.next = None

def getData(self):
return self.data

def getNext(self):
return self.next

def setData(self,newData):
self.data = newData

Linked List def setNext(self,newNext):


self.next = newNext

class UnorderedList:

def __init__(self):
self.head = None

def isEmpty(self):
return self.head == None

….

Piercarlo Dondi – Algorithms and Data Structures: Linear Data Structures – A.Y. 2022/23
Linked List (unordered)

class UnorderedList:

def __init__(self):
self.head = None

How to add a new element def isEmpty(self):


return self.head == None

…. add(self, item):
def
temp = Node(item)
temp.setNext(self.head)
self.head = temp

….

Why do we insert a new element at beginning and not at the end?


Insert an element at the end of the list is less efficient since we should traverse
all the list to reach the last element – execution time O(n) instead of O(1)

NOTE: a common variation of linked list keeps track of both head and tail position, in
that case it is equivalent to insert an element at the beginning or at the end of the list

Piercarlo Dondi – Algorithms and Data Structures: Linear Data Structures – A.Y. 2022/23
Linked List (unordered)

class UnorderedList:

def __init__(self):
self.head = None

def isEmpty(self):
return self.head == None

How to compute the list size def add(self, item):


temp = Node(item)
temp.setNext(self.head)
self.head = temp

…. size(self):
def
current = self.head
count = 0
while current is not None:
count = count + 1
current = current.getNext()
return count

….

Piercarlo Dondi – Algorithms and Data Structures: Linear Data Structures – A.Y. 2022/23
Linked List (unordered)

How to search an element in the list class UnorderedList:

def search(self, item):


current = self.head

while current is not None:


if current.getData() == item:
return True
else:
current = current.getNext()
return False

….

Piercarlo Dondi – Algorithms and Data Structures: Linear Data Structures – A.Y. 2022/23
Linked List (unordered)

How to remove an element in the list

Removing a node from the middle

Piercarlo Dondi – Algorithms and Data Structures: Linear Data Structures – A.Y. 2022/23
Linked List (unordered)

How to remove an element in the list

Removing the first node

Piercarlo Dondi – Algorithms and Data Structures: Linear Data Structures – A.Y. 2022/23
Linked List (unordered)

class UnorderedList:


How to remove an element in the list
def remove(self, item):
current = self.head
previous = None
found = False

while current is not None and not found:


if current.getData() == item:
found = True
Removing a node from the middle else:
previous = current
current = current.getNext()

if found:
if previous is None:
self.head = current.getNext()
else:
previous.setNext(current.getNext())
Removing the first node …

Piercarlo Dondi – Algorithms and Data Structures: Linear Data Structures – A.Y. 2022/23
Linked List (ordered)

Same methods of unordered linked list beside search and add

class OrderedList:
How to search an element in the list

def search(self, item):


current = self.head

while current is not None:


if current.getData() == item:
return True
else:
if current.getData() > item:
return False
else:
current = current.getNext()

return False

Piercarlo Dondi – Algorithms and Data Structures: Linear Data Structures – A.Y. 2022/23
Linked List (ordered)

class OrderedList:

def add(self, item):


current = self.head
How to add an element in the list previous = None
stop = False
while current is not None and not stop:
if current.getData() > item:
stop = True
else:
previous = current
current = current.getNext()

temp = Node(item)
if previous is None:
temp.setNext(self.head)
self.head = temp
else:
temp.setNext(current)
previous.setNext(temp)

Piercarlo Dondi – Algorithms and Data Structures: Linear Data Structures – A.Y. 2022/23
Lists – computational complexity

Average computational complexity for common operations

Unordered Ordered
Operation Python list
linked list linked list

isEmpty() O(1) O(1) O(1)

Size() O(n) O(n) O(1)

Add(item) O(1) O(n) O(1)

Remove(item) O(n) O(n) O(n)

Search(item) O(n) O(n) O(n)

Piercarlo Dondi – Algorithms and Data Structures: Linear Data Structures – A.Y. 2022/23
Implementing a Stack with a Linked List

TOP

The head of the Linked List 17


will be the top of our Stack

26
31
54
77
Adding and removing an element from the Stack is equivalent to adding
and removing a node from the head of the Linked List 93

Piercarlo Dondi – Algorithms and Data Structures: Linear Data Structures – A.Y. 2022/23
Implementing a Stack with a Linked List
Implementation with Python List Implementation with Linked List
class Stack: class Node: class Stack:

def __init__(self): def __init__(self, data): def __init__(self):


self.items = [] self.data = data self.head = None
self.next = None
def isEmpty(self): def isEmpty(self):
return self.items == [] if self.head is None:
return True
def size(self): else:
return len(self.items) return False

def push(self, item): def size(self):


self.items.append(item) count = 0
if not self.isEmpty():
def pop(self): currentNode = self.head
return self.items.pop() while currentNode is not None:
count += 1
def peek(self): currentNode = currentNode.next
if len(self.items)>0: return count
return self.items[-1]
….

The Stack is initialized as an empty


linked list, so head is equal to None

Piercarlo Dondi – Algorithms and Data Structures: Linear Data Structures – A.Y. 2022/23
Implementing a Stack with a Linked List
Implementation with Python List Implementation with Linked List
class Stack: class Node: class Stack:

def __init__(self): def __init__(self, data): def __init__(self):


self.items = [] self.data = data self.head = None
self.next = None
def isEmpty(self): def isEmpty(self):
return self.items == [] if self.head is None:
return True
def size(self): else:
return len(self.items) return False

def push(self, item): def size(self):


self.items.append(item) count = 0
if not self.isEmpty():
def pop(self): currentNode = self.head
return self.items.pop() while currentNode is not None:
count += 1
def peek(self): currentNode = currentNode.next
if len(self.items)>0: return count
return self.items[-1]
….

To check if the Stack is empty, we can simply


check if the head of the linked list is None

Piercarlo Dondi – Algorithms and Data Structures: Linear Data Structures – A.Y. 2022/23
Implementing a Stack with a Linked List
Implementation with Python List Implementation with Linked List
class Stack: class Node: class Stack:

def __init__(self): def __init__(self, data): def __init__(self):


self.items = [] self.data = data self.head = None
self.next = None
def isEmpty(self): def isEmpty(self):
return self.items == [] if self.head is None:
return True
def size(self): else:
return len(self.items) return False

def push(self, item): def size(self):


self.items.append(item) count = 0
if not self.isEmpty():
def pop(self): currentNode = self.head
return self.items.pop() while currentNode is not None:
count += 1
def peek(self): currentNode = currentNode.next
if len(self.items)>0: return count
return self.items[-1]
….

To get the size of the Stack we need to traverse all


the linked list and count the nodes

Piercarlo Dondi – Algorithms and Data Structures: Linear Data Structures – A.Y. 2022/23
Implementing a Stack with a Linked List
Implementation with Python List Implementation with Linked List
class Stack: class Node: class Stack:
….
def __init__(self): def __init__(self, data):
self.items = [] self.data = data def push(self, data):
self.next = None if self.head is None:
def isEmpty(self): self.head = Node(data)
return self.items == [] else:
new_node = Node(data)
def size(self): new_node.next = self.head
return len(self.items) self.head = new_node

def push(self, item): def pop(self):


self.items.append(item) if self.isEmpty():
return None
def pop(self): else:
return self.items.pop() head_node = self.head
self.head = self.head.next
def peek(self): head_node.next = None
if len(self.items)>0: return head_node.data
return self.items[-1]
def peek(self):
if self.isEmpty():
return None
Push is equivalent to adding an else:
item at the head of the Linked List return self.head.data

Piercarlo Dondi – Algorithms and Data Structures: Linear Data Structures – A.Y. 2022/23
Implementing a Stack with a Linked List
Implementation with Python List Implementation with Linked List
class Stack: class Node: class Stack:
….
def __init__(self): def __init__(self, data):
self.items = [] self.data = data def push(self, data):
self.next = None if self.head is None:
def isEmpty(self): self.head = Node(data)
return self.items == [] else:
new_node = Node(data)
def size(self): new_node.next = self.head
return len(self.items) self.head = new_node

def push(self, item): def pop(self):


self.items.append(item) if self.isEmpty():
return None
def pop(self): else:
return self.items.pop() head_node = self.head
self.head = self.head.next
def peek(self): head_node.next = None
if len(self.items)>0: return head_node.data
return self.items[-1]
def peek(self):
if self.isEmpty():
Pop is equivalent to removing the return None
current head of the Linked List and else:
set the next node as new head return self.head.data

Piercarlo Dondi – Algorithms and Data Structures: Linear Data Structures – A.Y. 2022/23
Implementing a Stack with a Linked List
Implementation with Python List Implementation with Linked List
class Stack: class Node: class Stack:
….
def __init__(self): def __init__(self, data):
self.items = [] self.data = data def push(self, data):
self.next = None if self.head is None:
def isEmpty(self): self.head = Node(data)
return self.items == [] else:
new_node = Node(data)
def size(self): new_node.next = self.head
return len(self.items) self.head = new_node

def push(self, item): def pop(self):


self.items.append(item) if self.isEmpty():
return None
def pop(self): else:
return self.items.pop() head_node = self.head
self.head = self.head.next
def peek(self): head_node.next = None
if len(self.items)>0: return head_node.data
return self.items[-1]
def peek(self):
if self.isEmpty():
return None
Peak is equivalent to reading the else:
head of the Linked List return self.head.data

Piercarlo Dondi – Algorithms and Data Structures: Linear Data Structures – A.Y. 2022/23
Questions?

You might also like