Introduction to Data Structures and Algorithms.
Abdikhafar
Posted on October 10, 2024
Why do I need to learn Data Structures and Algorithms in the first place? Will I use them in my workspace?
Hello and welcome. We are going to demystify the importance of familiarizing oneself with data structures and algorithms and why the interviewers prefer them in the interviews.
Set? Buckle up and let's set off...
To start off, what is a Data Structure as well as an Algorithm?
From Wikipedia, a data structure is a data organization, management, and storage format that enables efficient access and modification. In simple terms, a data structure is a way of storing data in an efficient or structured manner. In the real world examples, we have examples like a book rack, kitchen cabinets and shoe racks.
In my Python from the word ...Go article, I have covered inbuilt python data structures which comprise: lists, dictionaries, tuples, and sets. Inbuilt data structures mean that they come with ready syntax to be used by the user. In addition to inbuilt data structures, we have user-defined data structures which comprise: array, stack, queue, linked list, tree, graph, and hashmap. This means that the user has to create them from scratch.
We will not go into depths on the inbuilt data structures but can be found explained in depths in the article.
What then is an algorithm?
An algorithm is a collection of steps to solve a particular problem which can be understood by non-technical people as well. There can be multiple ways and steps to solve a given problem hence there can be multiple algorithms for a specific problem.
Why are Data Structures and Algorithms important?
To start off, data structures and algorithms in interviews act as a clear demonstration to the interviewer on your problem-solving skills.
Secondly, data structures refer to the way we organize information on our computers and you can guess that the way we organize information can have a lot of impact on the performance. A good example is a library. Suppose, one wants to have a book on Calculus from a library, to do so, one has to first go to the math section, then to the Calculus section. If these books had not been organized in this manner and just distributed randomly then it would have been really a cumbersome process to find the book.
In addition, an Algorithm is a step-by-step process in solving a given task. They are developed to help perform a task more efficiently by one applying a predefined approach or methodology. If you write code as per your perception and judgement without applying any predefined algorithm, your code will probably be botched up after a certain time.
To sum up, they help one write efficient code and solve problems in optimal or near-optimal ways. Without them, one will be reinventing the wheel which is not always successfully.
Built-in Data Structures
List
Lists are data structures used to store data in a sequential manner.
They use square brackets.
Every single element in a list is indexed from index 0.
Negative indexing in lists is also supported where the last item in a list is given a -1 index. This helps access of elements from the last to the first.
Data in lists can be modified.
Example of a list:
sample_list = [3, 5, "hello", True, 4.76]
Output: [3, 5, "hello", True, 4.76]
Tuples
Tuples work like lists but data in tuples cannot be modified (immutable).
They use parenthesis/round brackets.
Example of a tuple:
sample_tuple = (1, 3, "Abdikhafar")
Output: (1, 3, "Abdikhafar")
Dictionaries
Data in dictionaries is stored as key-value pairs.
The pairs can be accessed, added, and deleted when needed.
Data is stored in curly braces.
Example:
sample_dict = {"first":"Abdikhafar", "Second":"Issack"}
Output: sample_dict{'first': 'Abdikhafar', 'Second': 'Issack'}
Sets
Sets, like dictionaries, use curly brackets.
They store a collection of unordered unique elements where each data element must be unique.
Example:
my_set = {1, 2, 3, 3, 4, 5, 5}
Output: {1, 2, 3, 4, 5}
Assuming you have a 'stack' of books, to get a book in the middle of the stack, one has to get the book at the top book first followed by the second book... to the book that the person wants to access. In Stack, this approach is known as LIFO (Last-in First-out).
This means that it is a linear data structure where elements are accessed only from the top position.
In Stack, elements can be pushed, accessed, and popped as required.
User-defined data structures
Stack
Assuming you have a 'stack' of books, to get a book in the middle of the stack, one has to get the book at the top book first followed by the second book... to the book that the person wants to access. In Stack, this approach is known as LIFO (Last-in First-out).
This means that it is a linear data structure where elements are accessed only from the top position.
In Stack, elements can be pushed, accessed, and popped as required.
stack = ['first', 'second', 'third']
print(stack)
print()
# pushing elements
stack.append('fourth')
stack.append('fifth')
print(stack)
print()
# printing top
n = len(stack)
print(stack[n-1])
print()
# poping element
stack.pop()
print(stack)
------
(Output)
[‘first’, ‘second’, ‘third’]
[‘first’, ‘second’, ‘third’, ‘fourth’, ‘fifth’]
fifth
[‘first’, ‘second’, ‘third’, ‘fourth’]
More on stacks
Queue
Unlike Stack, Queue works on a principle known as FIFO (Fist-in First-out).
Queues have both head and tail sections and operations can be performed from both the head and the tail.
This means that data in a queue can be accessed and modified either from both the head and/or the tail.
queue = ['first', 'second', 'third']
print(queue)
print()
# pushing elements
queue.append('fourth')
queue.append('fifth')
print(queue)
print()
# printing head
print(queue[0])
# printing tail
n = len(queue)
print(queue[n-1])
print()
# poping element
queue.remove(queue[0])
print(queue)
------
(Output)
[‘first’, ‘second’, ‘third’]
[‘first’, ‘second’, ‘third’, ‘fourth’, ‘fifth’]
first
fifth
[‘second’, ‘third’, ‘fourth’, ‘fifth’]
More on Queue
Tree
A tree is a non-linear but hierarchical data structure where data originates from the root node.
Each node that precedes another node is known as a parent node while that node is referred to as a child node.
The last nodes in a tree are called leaves
class node:
def __init__(self, ele):
self.ele = ele
self.left = None
self.right = None
def preorder(self):
if self:
print(self.ele)
preorder(self.left)
preorder(self.right)
n = node('first')
n.left = node('second')
n.right = node('third')
preorder(n)
------
(Output)
first
second
third
More on Trees
Graph
A Graph is a non-linear data structure which has a structure which is similar to a tree but works differently. It has nodes which are also referred to as vertices and edges which are lines or arcs that connect any two nodes in the graph.
A valid graph structure consists of a finite set of nodes and edges.
An example is the use of Facebook where everyone is a vertex in the network.
class adjnode:
def __init__(self, val):
self.val = val
self.next = None
class graph:
def __init__(self, vertices):
self.v = vertices
self.ele = [None]*self.v
def edge(self, src, dest):
node = adjnode(dest)
node.next = self.ele[src]
self.ele[src] = node
node = adjnode(src)
node.next = self.ele[dest]
self.ele[dest] = node
def __repr__(self):
for i in range(self.v):
print("Adjacency list of vertex {}\n head".format(i), end="")
temp = self.ele[i]
while temp:
print(" -> {}".format(temp.val), end="")
temp = temp.next
g = graph(4)
g.edge(0, 2)
g.edge(1, 3)
g.edge(3, 2)
g.edge(0, 3)
g.__repr__()
------
(Output)
Adjacency list of vertex 0
head -> 3 -> 2
Adjacency list of vertex 1
head -> 3
Adjacency list of vertex 2
head -> 3 -> 0
Adjacency list of vertex 3
head -> 0 -> 2 -> 1
More on Graphs
Linked List
A linked list is a linear data structure which consists of a sequence of elements that are connected to each other and not stored at contiguous memory locations. The elements in a linked list are linked using pointers.
Python does not have linked lists in its standard library.
llist = ['first', 'second', 'third']
print(llist)
print()
# adding elements
llist.append('fourth')
llist.append('fifth')
llist.insert(3, 'sixth')
print(llist)
print()
llist.remove('second')
print(llist)
print()
------
(Output)
[‘first’, ‘second’, ‘third’]
[‘first’, ‘second’, ‘third’, ‘sixth’, ‘fourth’, ‘fifth’]
[‘first’, ‘third’, ‘sixth’, ‘fourth’, ‘fifth’]
Hashmap
Hash maps are indexed data structures which make use of a hash function to compute the index with a key into an array of slots or buckets.
Its value is mapped to the bucket with a corresponding index.
The key cannot be changed (immutable) and is unique.
In python, dictionaries are examples of hash maps.
def printdict(d):
for key in d:
print(key, "->", d[key])
hm = {0: 'first', 1: 'second', 2: 'third'}
printdict(hm)
print()
hm[3] = 'fourth'
printdict(hm)
print()
hm.popitem()
printdict(hm)
------
(Output)
0 -> first
1 -> second
2 -> third
0 -> first
1 -> second
2 -> third
3 -> fourth
0 -> first
1 -> second
2 -> third
We now have the basics of data structures. Let's meet in the next session where we expound more on data structures and algorithms as we focus on types of algorithms too.
Can't wait to see you...🥳
Posted on October 10, 2024
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.