PYTHON DS
General Data Structures
The various data structures in computer science are divided
broadly into two categories shown below. We will discuss about each of the
below data structures in detail in subsequent chapters.
Liner Data Structures
These are the data structures which store the data elements in a
sequential manner.
·
Array − It is a sequential arrangement of data
elements paired with the index of the data element.
·
Linked
List − Each data
element contains a link to another element along with the data present in it.
·
Stack − It is a data structure which follows
only to specific order of operation. LIFO(last in First Out) or FILO(First in
Last Out).
·
Queue − It is similar to Stack but the order of
operation is only FIFO(First In First Out).
·
Matrix − It is two dimensional data structure in
which the data element is referred by a pair of indices.
Non-Liner Data Structures
These are the data structures in which there is no sequential
linking of data elements. Any pair or group of data elements can be linked to
each other and can be accessed without a strict sequence.
·
Binary
Tree − It is a data
structure where each data element can be connected to maximum two other data
elements and it starts with a root node.
·
Heap − It is a special case of Tree data
structure where the data in the parent node is either strictly greater than/
equal to the child nodes or strictly less than it’s child nodes.
·
Hash
Table − It is a data
structure which is made of arrays associated with each other using a hash
function. It retrieves values using keys rather than index from a data element.
·
Graph − It is an arrangement of vertices and
nodes where some of the nodes are connected to each other through links.
Python Specific Data Structures
These data structures are specific to python language and they
give greater flexibility in storing different types of data and faster
processing in python environment.
·
List − It is similar to array with the
exception that the data elements can be of different data types. You can have
both numeric and string data in a python list.
·
Tuple − Tuples are similar to lists but they are
immutable which means the values in a tuple cannot be modified they can only be
read.
·
Dictionary − The dictionary contains Key-value pairs
as its data elements.
A linked list is a sequence of data elements, which are connected
together via links. Each data element contains a connection to another data
element in form of a pointer. Python does not have linked lists in its standard
library. We implement the concept of linked lists using the concept of nodes as
discussed in the previous chapter.
We have already seen how we create a node class and how to
traverse the elements of a node.In this chapter we are going to study the types
of linked lists known as singly linked lists. In this type of data structure
there is only one link between any two data elements. We create such a list and
create additional methods to insert, update and remove elements from the list.
Creation of Linked list
We create a Node object and create another class to use this ode
object. We pass the appropriate values through the node object to point the to
the next data elements. The below program creates the linked list with three
data elements. In the next section we will see how to traverse the linked list.
class Node:
def __init__(self, dataval=None):
self.dataval = dataval
self.nextval = None
class SLinkedList:
def __init__(self):
self.headval = None
list1 = SLinkedList()
list1.headval = Node("Mon")
e2 = Node("Tue")
e3 = Node("Wed")
# Link first Node to second node
list1.headval.nextval = e2
# Link second Node to third node
e2.nextval = e3
Traversing a Linked List
Singly linked lists can be traversed in only forward direction
starting form the first data element. We simply print the value of the next
data element by assigning the pointer of the next node to the current data
element.
Example
class Node:
def __init__(self, dataval=None):
self.dataval = dataval
self.nextval = None
class SLinkedList:
def __init__(self):
self.headval = None
def listprint(self):
printval = self.headval
while printval is not None:
print (printval.dataval)
printval = printval.nextval
list = SLinkedList()
list.headval = Node("Mon")
e2 = Node("Tue")
e3 = Node("Wed")
# Link first Node to second node
list.headval.nextval = e2
# Link second Node to third node
e2.nextval = e3
list.listprint()
Output
When the above code is executed, it produces the following result
−
Mon
Tue
Wed
Insertion in a Linked List
Inserting element in the linked list involves reassigning the
pointers from the existing nodes to the newly inserted node. Depending on
whether the new data element is getting inserted at the beginning or at the
middle or at the end of the linked list, we have the below scenarios.
Inserting at the Beginning
This involves pointing the next pointer of the new data node to
the current head of the linked list. So the current head of the linked list
becomes the second data element and the new node becomes the head of the linked
list.
Example
class Node:
def __init__(self, dataval=None):
self.dataval = dataval
self.nextval = None
class SLinkedList:
def __init__(self):
self.headval = None
# Print the linked list
def listprint(self):
printval = self.headval
while printval is not None:
print (printval.dataval)
printval = printval.nextval
def AtBegining(self,newdata):
NewNode = Node(newdata)
# Update the new nodes next val to existing node
NewNode.nextval = self.headval
self.headval = NewNode
list = SLinkedList()
list.headval = Node("Mon")
e2 = Node("Tue")
e3 = Node("Wed")
list.headval.nextval = e2
e2.nextval = e3
list.AtBegining("Sun")
list.listprint()
Output
When the above code is executed, it produces the following result
−
Sun
Mon
Tue
Wed
Inserting at the End
This involves pointing the next pointer of the the current last
node of the linked list to the new data node. So the current last node of the
linked list becomes the second last data node and the new node becomes the last
node of the linked list.
Example
class Node:
def __init__(self, dataval=None):
self.dataval = dataval
self.nextval = None
class SLinkedList:
def __init__(self):
self.headval = None
# Function to add newnode
def AtEnd(self, newdata):
NewNode = Node(newdata)
if self.headval is None:
self.headval = NewNode
return
laste = self.headval
while(laste.nextval):
laste = laste.nextval
laste.nextval=NewNode
# Print the linked list
def listprint(self):
printval = self.headval
while printval is not None:
print (printval.dataval)
printval = printval.nextval
list = SLinkedList()
list.headval = Node("Mon")
e2 = Node("Tue")
e3 = Node("Wed")
list.headval.nextval = e2
e2.nextval = e3
list.AtEnd("Thu")
list.listprint()
Output
When the above code is executed, it produces the following result
−
Mon
Tue
Wed
Thu
Inserting in between two
Data Nodes
This involves changing the pointer of a specific node to point to
the new node. That is possible by passing in both the new node and the existing
node after which the new node will be inserted. So we define an additional
class which will change the next pointer of the new node to the next pointer of
middle node. Then assign the new node to next pointer of the middle node.
class Node:
def __init__(self, dataval=None):
self.dataval = dataval
self.nextval = None
class SLinkedList:
def __init__(self):
self.headval = None
# Function to add node
def Inbetween(self,middle_node,newdata):
if middle_node is None:
print("The mentioned node is absent")
return
NewNode = Node(newdata)
NewNode.nextval = middle_node.nextval
middle_node.nextval = NewNode
# Print the linked list
def listprint(self):
printval = self.headval
while printval is not None:
print (printval.dataval)
printval = printval.nextval
list = SLinkedList()
list.headval = Node("Mon")
e2 = Node("Tue")
e3 = Node("Thu")
list.headval.nextval = e2
e2.nextval = e3
list.Inbetween(list.headval.nextval,"Fri")
list.listprint()
Output
When the above code is executed, it produces the following result
−
Mon
Tue
Fri
Thu
Removing an Item
We can remove an existing node using the key for that node. In the
below program we locate the previous node of the node which is to be
deleted.Then, point the next pointer of this node to the next node of the node
to be deleted.
Example
class Node:
def __init__(self, data=None):
self.data = data
self.next = None
class SLinkedList:
def __init__(self):
self.head = None
def Atbegining(self, data_in):
NewNode = Node(data_in)
NewNode.next = self.head
self.head = NewNode
# Function to remove node
def RemoveNode(self, Removekey):
HeadVal = self.head
if (HeadVal is not None):
if (HeadVal.data == Removekey):
self.head = HeadVal.next
HeadVal = None
return
while (HeadVal is not None):
if HeadVal.data == Removekey:
break
prev = HeadVal
HeadVal = HeadVal.next
if (HeadVal == None):
return
prev.next = HeadVal.next
HeadVal = None
def LListprint(self):
printval = self.head
while (printval):
print(printval.data),
printval = printval.next
llist = SLinkedList()
llist.Atbegining("Mon")
llist.Atbegining("Tue")
llist.Atbegining("Wed")
llist.Atbegining("Thu")
llist.RemoveNode("Tue")
llist.LListprint()
Output
When the above code is executed, it produces the following result
−
Thu
Wed
Mon
class Node:
def __init__(self,data=None):
self.data=data
self.next=None
class LinkList:
def __init__(self):
self.head=None
def printnodes(self):
curr=self.head
while curr!=None:
print(curr.data,' ')
curr=curr.next
def insertbeg(self,node):
node.next=self.head
self.head=node
def insertend(self,node):
prev=self.head
curr=self.head
while curr!=None:
prev=curr
curr=curr.next
prev.next=node
l=LinkList()
first=Node("mon")
l.head=first
n1=Node("tue")
first.next=n1
n2=Node("wed")
n1.next=n2
l.printnodes()
print("-----")
l.insertbeg(Node("Sun"))
l.printnodes()
print("-----")
l.insertend(Node("Over"))
l.printnodes()
output
mon
tue
wed
-----
Sun
mon
tue
wed
-----
Sun
mon
tue
wed
Over
Python - Stack
In the english dictionary the word stack means arranging objects
on over another. It is the same way memory is allocated in this data structure.
It stores the data elements in a similar fashion as a bunch of plates are
stored one above another in the kitchen. So stack data strcuture allows
operations at one end wich can be called top of the stack.We can add elements
or remove elements only form this en dof the stack.
In a stack the element insreted last in sequence will come out
first as we can remove only from the top of the stack. Such feature is known as
Last in First Out(LIFO) feature. The operations of adding and removing the
elements is known as PUSH and POP. In the following program we implement
it as add and and remove functions. We declare an empty list
and use the append() and pop() methods to add and remove the data elements.
PUSH into a
Stack
Let us understand, how to use PUSH in Stack. Refer the program
mentioned program below −
Example
class Stack:
def __init__(self):
self.stack = []
def add(self, dataval):
# Use list append method to add element
if dataval not in self.stack:
self.stack.append(dataval)
return True
else:
return False
# Use peek to look at the top of the stack
def peek(self):
return self.stack[-1]
AStack = Stack()
AStack.add("Mon")
AStack.add("Tue")
AStack.peek()
print(AStack.peek())
AStack.add("Wed")
AStack.add("Thu")
print(AStack.peek())
Output
When the above code is executed, it produces the following result
−
Tue
Thu
POP from a
Stack
As we know we can remove only the top most data element from the
stack, we implement a python program which does that. The remove function in
the following program returns the top most element. we check the top element by
calculating the size of the stack first and then use the in-built pop() method
to find out the top most element.
class Stack:
def __init__(self):
self.stack = []
def add(self, dataval):
# Use list append method to add element
if dataval not in self.stack:
self.stack.append(dataval)
return True
else:
return False
# Use list pop method to remove element
def remove(self):
if len(self.stack) <= 0:
return ("No element in the Stack")
else:
return self.stack.pop()
AStack = Stack()
AStack.add("Mon")
AStack.add("Tue")
AStack.add("Wed")
AStack.add("Thu")
print(AStack.remove())
print(AStack.remove())
Output
When the above code is executed, it produces the following result
−
Thu
Wed
STACK PUSH,POP Example
class Stack:
def __init__(self):
self.stack = []
def add(self, dataval):
# Use list append method to add element
if dataval not in self.stack:
self.stack.append(dataval)
return True
else:
return False
# Use peek to look at the top of the stack
def peek(self):
return self.stack[-1]
def printall(self):
print(self.stack)
def remove(self):
if len(self.stack)<=0:
print("Stack is emp[ty")
else:
return self.stack.pop()
AStack = Stack()
AStack.add("Mon")
AStack.add("Tue")
AStack.add('Mon')
AStack.add("Wed")
AStack.add("Thu")
AStack.add('Fri')
AStack.printall()
print(AStack.peek())
AStack.remove()
AStack.printall()
Output:
['Mon', 'Tue', 'Wed', 'Thu', 'Fri']
Fri
['Mon', 'Tue', 'Wed', 'Thu']
QUEUE :
class Queue:
def __init__(self):
self.queue = []
def add(self, dataval):
# Use list append method to add element
if dataval not in self.queue:
self.queue.append(dataval)
return True
else:
return False
# Use peek to look at the top of the queue
def peek(self):
return self.queue[-1]
def printall(self):
print(self.queue)
def remove(self):
if len(self.queue)<=0:
print("queue is emp[ty")
else:
return self.queue.pop(0)
def addbeg(self,wd):
self.queue.insert(0, wd)
Queue = Queue()
Queue.add("Mon")
Queue.add("Tue")
Queue.add('Mon')
Queue.add("Wed")
Queue.add("Thu")
Queue.add('Fri')
Queue.addbeg('Sunday')
Queue.printall()
print(Queue.peek())
Queue.remove()
Queue.printall()
Output:
['Sunday', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri']
Fri
['Mon', 'Tue', 'Wed', 'Thu', 'Fri']