Basic Data Structures Using Core Python

Posted on March 12, 2021August 22, 2022

A data structure, taken literally is a structure made out of data that isn’t far off from the actual definition, that is a comprehensive way in which data is organized, so it can be read and understood by computers and humans alike. The idea is to make it to be able to reduce the time and space complexity by using certain algorithms on the Data Structures.

Now Data Structures is a vast topic that we can’t hope to cover even in a week worth of blogs, so today we will only cover Sequential Data Structures, i.e. Single Linked List, Doubly Linked List, Queue, and Stack. Without wasting any other time let’s jump into the Data Structure in depth.

Code

Singly Linked List

To visualize the single linked list, remember in your school days when you were made to take “one-hand distance” and leave out the first student all students pointed to the student in front of them. The teacher in turn pointed to the first student.

Now all the students are the nodes pointing to the mode in front of them, the teacher is pointing to the frontmost/head node which lets us know where the line starts from.

Following is the code for the above analogy.

image

Now Let’s see how to implement Singly Linked List using Python

# defining the container for the element of the linked list

class Node:

   def __init__(self, data, next = None):

       self.data = data

       self.next = next

# defining the Singly Linked List class

class SinglyLinkedList:

   def __init__(self, head=None):

       self.head = head

       self.size = 0

  #function to show the length of the LinkedList

   def __len__(self):

       return self.size

  #function to print the LinkedList

   def __str__(self):

       x = self.head

       toprint = []

       while x != None:

           toprint.append(x.data)

           x = x.next

       return (‘[‘ +” .join(f’ {i} ‘ for i in toprint) + ‘]’)

  #function to clear all the data in the linked list

   def clear(self):

       x = self.head

       if self.size != 0:

           while x != None:

               next = x.next

               x.data = None

               x = next

           self.size = 0

       else:

           raise ValueError(“The LinkedList is already empty”)

   #function to check if the LinkedList is empty 

   def emptycheck(self):

       return (self.size == 0)

   #function to add an element in the beginning

   def addBegin(self, data):

       node = Node(data)

       if self.size == 0:

           self.head = node

       else:

           node.next = self.head

           self.head = node

       self.size += 1

   #function to add an element in a certain position

   def addAt(self, data, index):

       if index == 0:

           self.addBegin(data)

       elif index < 0 or index > self.size:

           raise IndexError(“Mention a proper valid index”)

       else:

           node = Node(data)

           x = self.head

           i = 0

           while(i != index):

               if (x != None):

                   x = x.next

                   i += 1

           if x != None:

               node.next = x.next

               x.next = node

           self.size += 1

   #function to add an element at the end of the linked list

   def addLast(self, data):

       x = self.head

       node = Node(data)

       while x.next != None:

           x = x.next

       x.next = node

       self.size += 1

   #function to remove the first element of the list

   def removeHead(self):

       if self.size == 0 :

           raise IndexError(“Linked List is empty”)

       else:

           self.head = self.head.next

           self.size -= 1

   #function to remove element at a certain position

   def removeAt(self, index):

       if index == 0:

           self.removeHead()

       elif index < 0 or index >= self.size:

           raise IndexError(“insert a valid index to remove node”)

       else:

           temp1 = self.head

           temp2 = self.head

           i = 0

           j = 0

           while (i!=index):

               temp1 = temp1.next

               i += 1

           while (j != index-1):

               temp2 = temp2.next

               j += 1

           temp2.next = temp1.next

           temp1 = None

       self.size -= 1

   #function to remove an element from the end of the linked list

   def removeLast(self):

       if self.size == 0:

           raise IndexError(“LinkedList is empty”)

       else:

           x = self.head

           i = 0

           while (i != self.size -2):

               x = x.next

               i += 1

           x.next = None

     #function to check the first element

   def peekHead(self):

       return self.head.data

     #function to display data at a certain index

   def get(self, index):

       if index >= self.size:

           raise IndexError(“insert a valid index”)

       else:

           x = self.head

           i = 0

           while(i != index):

               x = x.next

               i += 1

       return x.data

if __name__ == “__main__”:

   sll = SinglyLinkedList()

   sll.addBegin(5)

   sll.addLast(7)

   sll.addLast(9)

   print(sll)

   sll.addBegin(1)

   print(sll)

   print(sll.peekHead())

   sll.removeHead()

   print(sll)

   sll.removeLast()

   print(sll)

Output:

image 1

Now let’s jump to the next data structure which is Doubly Linked List

Doubly Linked List

A doubly linked list is a complex data structure that contains a pointer node to not just the node in front of it but also behind it. That does take double the memory to store the new pointers, but we get much more flexibility in traversing the list. It’s a simple trade-off, python lists are doubly linked lists.

image 2

So let’s implement a Doubly Linked List in Python

# defining the container to store the data for the element of the linked list

class Node:

   def __init__(self,data,next=None):

       self.data = data

       self.next = next

#defining doubly linked list

class DoublyLinkedList:

   def __init__(self,head=None,tail=None):

       self.size = 0

       self.head = head

       self.tail = tail

   #function to check the length of the linked list

   def __len__(self):

       return self.size

   #function to print linked list

   def __str__(self):

       x = self.head

       toprint=[]

       while(x!=None):

           toprint.append(x.data)

           x = x.next

       return (‘[‘+”.join(f’ {i} ‘ for i in toprint)+’]’)          

   #function to clear the LinkedList

   def clear(self):

       x = self.head

       if self.size !=0:

           while(x != None):

               next = x.next

               x.data = None

               x = next

           self.size = 0

       elif self.size ==0:

           Exception(“The LinkedList is already cleared”)

   #function to check whether the linked list is empty or not

   def emptyCheck(self):

       if self.size == 0:

           return True

       return False

   #function to add an element at the beginning of the linked list

   def addBegin(self, data):

       if self.size == 0:

           node  = Node(data)

           self.head = node

           self.tail = node

       else:

           node = Node(data)

           node.next = self.head

           self.head = node

       self.size+=1

   #function to add an element at a certain index  

   def addAfter(self,data,index):

       if index == 0:

           self.addBegin(data)

       elif index<0:

           raise IndexError(“Minimum value must be 0 referred to the beginning of the LinkedList”)

       else:

           node = Node(data)

           x = self.head

           i = 0

           while(i!=index):

               if(x!=None):

                   x = x.next

                   i+=1

           if (x!= None):

               node.next = x.next

               x.next = node

       self.size+=1

   #function to remove node at a certain index

   def removeNodeAt(self,index):

       if index == 0:

           self.removeHead()

       elif index < 0:

           raise Exception(“Please insert valid index”)

       elif index == self.size-1:

           self.removeTail()

       else:

           temp1 = self.head

           temp2 = self.head

           i = 0

           j = 0

           while(i!=index):

               temp1 = temp1.next

               i+=1

           while(j!= index-1):

               temp2 = temp2.next

               j+=1

           temp2.next = temp1.next

           temp1 = None

       self.size -= 1

   #function to add an element at the end of the linked list

   def addLast(self, data):

       if self.size == 0:

           node = Node(data)

           self.head = node

           self.tail = node

       else:

           node = Node(data)

           self.tail.next = node

           self.tail = self.tail.next

       self.size+=1

   #function to get the last element

   def tailitem(self):

       return self.tail.data  

   #function to get the first element

   def headitem(self):

       return self.head.data

   #function to delete the first element of the linked list

   def removeHead(self):

       if self.size == 0:

           IndexError(“LinkedList is empty!”)

       else:

           self.head = self.head.next

           self.size -= 1

   #function to delete the last element of the linked list

   def removeTail(self):

       if self.size == 0:

           raise IndexError(“LinkedList is empty!”)

       else:

           x = self.head

           i = 0

           while(i != self.size-2):

               x = x.next

               i+=1

           self.tail = x

           x.next = None

       self.size -= 1

if __name__ == “__main__”:

   dll = DoublyLinkedList()

   dll.addBegin(1)

   dll.addLast(10)

   dll.addLast(20)

   print(dll)

   dll.addAfter(30, 1)

   print(dll)

   dll.addBegin(40)

   print(dll)

   print(dll.headitem())

   print(dll.emptyCheck())

   dll.removeHead()

   print(dll)

Output:

image 3

Now let’s move to the next element of our Blog which is Stack

Stack

A stack is a linear data structure that follows a specific order in which the operations are performed. Stacks are ordered through LIFO(Last In First Out) or FILO(First In Last Out). Just imagine a stack of Chapati’s, you eat them one by one picking from the top, to reach the last one will take time as you finish all above it. Here we are just following LIFO as the new chapati placed on top will be eaten first.

Let’s step away from this analogy and go into proper code.

image 4

Now as per our schema we will jump to code the stack data structures implementing stack using lists.

# Creating a Stack class

Stack:

   def __init__(self, data):

       self.data = data

       self.top = self.data[0]

# creating push function

   def push(self, data):

       self.data.insert(0,data)

# creating pop function

   def pop(self):

       return self.data.pop(0)

# creating a function to check whether the stack is empty

   def isEmpty(self):

       if self.data ==None:

           return True

       else:

           return False

# creating a function to check the length of the stack

   def __len__(self):

       return len(self.data)

  # creating a function to print the stack

   def __str__(self):

       return (”.join(‘{}\n’.format(i) for i in self.data))

if __name__ == “__main__”:

   stk = Stack([1])

   stk.push(2)

   stk.push(3)

   print(stk.isEmpty())

   print(stk)

   stk.pop()

   print(stk)

Output :

image 5

Now let’s move to our last data structure for today which is Queue

Queue

A Queue is also a linear structure that follows a specific order just like the stack but with one key difference. The order is instead First In First Out (FIFO). The simple way to visualize a queue is by just taking the word literally. You take queue at a shop, people who join last will reach the window last, and the people who joined the queue first will be out first. So the key difference is adding and removing. In a stack we remove the item the most recently added, meanwhile in a queue, we remove the item the least recently added.

image 6

Now again let’s implement a queue in python

#creating a queue class

class Queue:

   def __init__(self, data):

       self.data = [data]

  # creating an enqueue function

   def enqueue(self,data):

       self.data.append(data)

  # creating a dequeue function

   def dequeue(self):

       self.data.pop(0)

  # creating a function to return the length

   def __len__(self):

       return len(self.data)

  # creating a function to print the queue

   def __str__(self):

       return (”.join(‘|{}|’.format(i) for i in self.data))

# function to check the head

   def head(self):

       return self.data[0]

# function to check the last element

   def tail(self):

       return self.data[-1]

if __name__ == “__main__”:

   q = Queue(5)

   q.enqueue(10)

   q.enqueue(20)

   print(q)

   print(q.head())

   print(q.tail())

   q.dequeue()

   print(q)

Output :

image 7

Conclusion

The OOP syntax of python makes it pretty easy to create Sequential Data Structures.

The harder part is thinking up the logic of these Data Structures.

We can also create advanced Data Structures using Python all that would take is understanding the logic and Classes and Object syntax in python.

Similar Posts

Game Physics for Kids: How Do Video Games Make Movement Feel Real?

A character jumps across a platform, lands on the ground, and continues running. It looks effortless. But behind that simple movement, a game is performing calculations that determine how high the character jumps, how quickly it falls, and exactly when its feet touch the platform. These movements are not accidental. They are created through programming and mathematical rules. Understanding game physics for kids introduces an interesting connection between gaming, coding, and real-world science. For children who enjoy playing video games, discovering how movement works behind the screen can make game development an engaging learning experience. Instead of simply controlling a character, students begin understanding the rules that make the character respond. What Is Game Physics for Kids? Game physics refers to the mathematical rules and programming systems that simulate movement and physical interactions inside video games. In real life, objects respond to forces such as gravity and friction. Video games recreate selected aspects of these behaviours using calculations. For example, a game might need to determine: These behaviours are controlled through programming. However, game physics does not always need to imitate reality perfectly. A superhero might jump unusually high. A racing car might turn more sharply than a real vehicle. Developers adjust physical rules to create the experience they want players to have. How Does Gravity Work in Video Games? Gravity is one of the most recognisable concepts in game physics. When a character jumps, it initially moves upward, slows down, and eventually begins falling. In many games, this effect is created by changing the character’s vertical velocity over time. Velocity describes how quickly an object moves and in which direction. Gravity changes that velocity, causing the character to accelerate downward. A Simple Example of Coding Gravity Imagine a game character standing on a platform. When the player presses the jump button, the program gives the character an upward velocity.

Pseudocode for Kids: Why Learning to Plan Before Coding Makes a Difference

Your child sits down to build a simple program. They know what they want it to do, but after writing a few lines of code, they get stuck. The problem might not be the programming language. It could be that they haven’t decided exactly how the program should work. This is where pseudocode for kids becomes a useful learning tool. Pseudocode helps students organise their ideas into clear instructions before translating them into actual programming code. Instead of immediately worrying about brackets, spelling or syntax, children can focus on the logic behind their solution. For parents exploring coding education, understanding pseudocode offers a useful perspective on what happens before a successful program is written. What Is Pseudocode in Coding? Pseudocode is a simplified way of describing the steps a computer program should follow. It uses ordinary language combined with basic programming concepts such as conditions, repetition and instructions. Unlike Python, JavaScript or other programming languages, pseudocode cannot be executed directly by a computer. Its purpose is to describe the logic of a solution clearly enough that someone can later convert it into working code. For example, imagine a program that checks whether a student has completed their homework. The pseudocode could look like this: This example introduces a conditional statement without requiring the child to memorise the syntax of a particular programming language. Educational resources from Oak National Academy also describe pseudocode as a language-independent way of representing algorithms.  Oak National Academy Why Should Children Learn Pseudocode Before Writing Code? Writing instructions before coding encourages children to separate two different challenges: deciding what a program should do and learning how to express those instructions in a programming language. 1. It Helps Children Organise Their Thinking A programming idea may seem simple until a student tries to explain every step. Consider a program that recommends an activity depending on the weather. The child needs to decide what information the program receives, what conditions it checks and how it selects an answer. Pseudocode provides a structure for arranging these decisions logically. 2. It Makes Programming Logic Easier to Examine Imagine a child designing a program that checks whether someone qualifies for a library membership. Before writing code, they need to decide what happens when the user meets the requirements and what happens when they do not.

logo think create apply new 2 2048x525 1
Group 271
Group 545 4
Group 270

Launching New
3D Unity Course