You are on page 1of 52

DATA STRUCTURES

DESIGN
Unit – 2
Linear Structures- Stacks &
Queues
THE STACK ADT

• A stack is a data structure that stores a linear collection of items. Adding and removing items is restricted to one
end known as the top of the stack. Stack follows the principle last-in first-out (LIFO).
• Stacks are very common in computer science and are used in many types of problems. Stacks also occur in our
everyday lives. Consider a stack of trays in a lunchroom. When a tray is removed from the top, the others shift up.
If trays are placed onto the stack, the others are pushed down.

Follow study with JBR Trisea You Tube Channel for Tamil Explanation
A stack is an abstract data type (ADT) such that an instance S supports the following methods:

S. stack() : Creates a new empty stack.


S. push(e) : Add element e to the top of stack S.
S.pop() : Remove and return the top element from the stack S. An error occurs
if the stack is empty.
S.top() : Return a reference to the top element of stack S, without removing
it; an error occurs if the stack is empty.
S.is_empty( ) : Return True if stack S does not contain any elements.
len(S) : Return the number of elements in stack S. In Python, it can be
implemented using the special method len.

Follow study with JBR Trisea You Tube Channel for Tamil Explanation
ARRAY BASED IMPLEMENTATION OF STACK USING PYTHON LIST

• In Python, array implementation of a stack is done by storing its elements in a Python list. The list class already
supports adding an element to the end with the append method, and removing the last element with the pop
method, so it is natural to align the top of the stack at the end of the list.
• The adapter pattern is used to define a new class in such a way that it contains an instance of the existing class as
a hidden field, and then to implement each method of the new class using methods of this hidden instance
variable. In the context of the stack ADT, Python’s list class can be used.
Stack Method Realization with Python List

S.push(e) L.append(e)

S.pop( ) L.pop( )

S.top( ) L(-1)

S.is_empty( ) Len(L) = = 0

len(S) len(L)

Follow study with JBR Trisea You Tube Channel for Tamil Explanation
Stack Operations

The implementation starts with the creation of empty stack. An empty stack is a stack containing no items.
Push
The push operation is the insertion operation. In stack, elements can be pushed at the top end of the stack. push(e) method
add element e to the top of stack S.
def push(self, e):
self. stack.append(e)
Pop

The pop operation is the deletion operation. In stack, elements can be popped at the top end of the stack. pop() method
remove and return the top element from the stack S. Performing pop operation in an empty stack creates an error.
def pop(self):
if self.is_empty( ):
raise Empty( “Stack is empty”)
return self.stack.pop( )
Follow study with JBR Trisea You Tube Channel for Tamil Explanation
Top

The top operation returns the element at the top of the stack, without removing it. Performing top operation in an
empty stack creates an error.

def top(self):
if self.is_empty( ):
raise Empty(“Stack is empty”)
return self. stack[−1]
In python the index of last item is -1. So, it returns the top element of the stack.

Follow study with JBR Trisea You Tube Channel for Tamil Explanation
Array Based Implementation of Stack using Python List

class ArrayStack: def top(self):


def _ _init_ _(self): if self.is_empty( ):
self._stack = [ ] raise Empty(“Stack is empty”)
def _ _len _ _ (self): return self._stack[−1]
return len(self._stack)
def is_empty(self): def pop(self):
return len(self._stack) == 0 if self.is _empty( ):
def push(self, e): raise Empty(“Stack is empty”)
self. _stack.append(e) return self._stack.pop( )

Follow study with JBR Trisea You Tube Channel for Tamil Explanation
Analysis
The stack operations are easy to evaluate for the Python list-based implementation. The operations push(), pop(),
top(), is_Empty() and len() only require O(1) time. The space usage is O(n), where n is the current number of
elements in the stack.

Follow study with JBR Trisea You Tube Channel for Tamil Explanation
LINKED LIST IMPLEMENTATION OF STACK

The Python list-based (array based) implementation may not be the best choice for stacks with a large number of
push and pop operations. Because append() and pop() list operation may require a reallocation of the original array.

Since the linked list implementation uses dynamic allocation of the memory, the stack ADT can be implemented
using the singly linked list to avoid reallocation of the original array.

In linked list implementation of stack, the front of the list is the most efficient representation for the top of the stack.
So, push operation is performed by inserting an element at the front of the list. Pop operation is performed by
deleting an element at the front of the list.

Follow study with JBR Trisea You Tube Channel for Tamil Explanation
Node Structure

class node:
def _ _init_ _(self, element,next):
self.element = element
self.next = next

In node representation, each node has two instance variables, element and next. The element holds the value. The next variable holds the
pointer to the next node.
Class Instance

def _ _init_ _(self):


self.head = None
self.size = 0

Each stack instance maintains two variables. The head member is a reference to the node at the head of the list. The size variable is an
integer value for keeping track of the number of items on the stack. The value of size is adjusted when elements are pushed onto or popped
off the stack.

Follow study with JBR Trisea You Tube Channel for Tamil Explanation
Push

The implementation of push operation is same as insertion at the head of a singly linked list. To push a new element e onto
the stack, the necessary changes to be done in the linked structure are,

i. The next field of the new node is set to the existing top node and
ii. Head is reassigned to the new node

def push(self, e):


self.head = self.Node(e, self.head)
self.size = self.size +1

Follow study with JBR Trisea You Tube Channel for Tamil Explanation
Pop

The implementation of pop operation is same as deletion at the head of a singly linked list. To pop a top element
from the stack, the necessary changes to be done in the linked structure are,

i. Return the top element


ii. By pass the head reference to the second element of the stack and make it as a top.

def pop(self):
if self.is_empty( ):
raise Empty(“Stack is empty” )
answer = self.head.element
self.head = self.head.next
self.size = self.size-1
return answer

Follow study with JBR Trisea You Tube Channel for Tamil Explanation
Top

The top operation returns the element that is at the top of the stack. When the stack is empty, it raises an Empty
exception. When the stack is nonempty, self.head is a reference to the first node of the linked list. The top element
can be identified as self. head. element.

def top(self):
if self.is_empty( ):
raise Empty(“Stack is empty”)
return self.head.element

Follow study with JBR Trisea You Tube Channel for Tamil Explanation
Linked list implementation of a stack

class LinkedStack: def is_empty(self):

class node: return self.size = = 0

def _ _init_ _(self, element,_next):

self.element = element def push(self, e):

self._next = _ next self.head = self.Node(e, self.head)

self.size = self.size +1

def _ _init_ _(self):

self.head = None

self.size = 0

def _ _len_ _ (self):

return self.size

Follow study with JBR Trisea You Tube Channel for Tamil Explanation
def top(self): s= LinkedStack
if self.is_empty( ): s.push(1)
raise Empty(“Stack is empty”) s.push(2)
return self.head.Element s.push(3)
s.push(4)
def pop(self): len(s)
if self.is_empty( ): s.top()
raise Empty(“Stack is empty” ) s.pop()
answer = self.head.element s.pop()
self.head = self.head._next s.top()
self.size = self.size-1
return answer

Follow study with JBR Trisea You Tube Channel for Tamil Explanation
APPLICATIONS OF STACK
Reversing Data Using Stack

A stack can be used to reverse a data sequence. For example, if the values 1, 2, and 3 are pushed onto a stack in that order, they will be popped from the stack in the order 3, 2,
and then 1.

To print lines of a file in reverse order or to display a data set in decreasing order rather than increasing order, read each line and push it onto a stack, and then write the lines in
the order they are popped. Example: If the input file contains the data PYTHON PROGRAMMING, the output file contains GNIMMARGORP NOHTYP.
Implementation
def reversefile(filename):
S = ArrayStack()
original = open(filename)
for line in original:
S.push(line.rstrip( "\n" ))
original.close( )
output = open("testfile.txt", w ) # reopening file overwrites original
while not S.is_empty( ):
output.write(S.pop( )+'\n ')
output.close( )

Follow study with JBR Trisea You Tube Channel for Tamil Explanation
Matching Parentheses

An arithmetic expression may contain various pairs of An Algorithm for Matching Delimiters
grouping symbols, such as
• Parentheses: “(” and “)”
1. Make an empty stack.
• Braces: “{” and “}”
2. Read one character at a time from left to right until end of
• Brackets: “[” and “]” file.
Example 3. If the character is an open symbol, then push it onto the
stack.
• Correct: ( )(( )){([( )])}
4. If it is a close symbol then pop one symbol from stack and
• Correct: ((( )(( )){([( )])}))
check that these two symbols form a valid pair.
5. If we reach the end of the expression and the stack is empty,
then the original expression was properly matched.
6. If there is an opening delimiter on the stack without a
matching symbol then report that the expression is not
matched.

Follow study with JBR Trisea You Tube Channel for Tamil Explanation
Example

• Input sequence: [ ( ) ]
• Read [ - Open symbol so push it on to the stack. [

Follow study with JBR Trisea You Tube Channel for Tamil Explanation
THE STACK ADT

Implementation

def is_matched(expr):
leftdelit = ({[
rightdelit = )}]
S = ArrayStack()
for c in expr:
if c in leftdelit:
S.push(c)
elif c in rightdelit:
if S.is_empty( ):
return False
if rightdelit.index(c) != leftdelit.index(S.pop( )):
return False # mismatched
return S.is_empty( )

Follow study with JBR Trisea You Tube Channel for Tamil Explanation
Matching Tags in a Markup Language

• Another application of stack is matching delimiters in the validation of markup languages such as HTML or
XML. HTML is the standard format for hyperlinked documents on the Internet and XML is an extensible markup
language used for a variety of structured data sets.

• In an HTML document, portions of text are delimited by HTML tags. A simple opening HTML tag has the form
“<name>” and the corresponding closing tag has the form “</name>”. Similarly, the <body> tag should be
matched with </body> tag before closing that document.

• In order to matching tags using stack, the opening tags are pushed onto the stack, and matched against closing
tags as they are popped from the stack, just as matching parentheses.

Follow study with JBR Trisea You Tube Channel for Tamil Explanation
Converting Infix Expression to Postfix Expression

Three different notations can be used to represent a mathematical expression.

1. Infix Notation: In infix notation the operator is specified between the operands. Example: a + b * c
2. Prefix Notation or Polish Notation: The prefix notation places the operator before the operands. Example: + * a b
c
3. Postfix Notation or Reverse Polish Notation: The postfix notation places the operator after the operands.
Example: a b c * +

The postfix and prefix notations have the advantages that, they neither uses parentheses to override the order of
precedence and both create expressions in unique form.

Follow study with JBR Trisea You Tube Channel for Tamil Explanation
Algorithm

1. Read one character at a time


2. If it is an operand then it is placed onto the output array.
3. If it is an operator then push it onto the stack
4. Left parentheses also pushed onto the stack
5. If the input is close symbol then pop the stack until the left parentheses and write onto the output array.
6. If we read the end of input, pop the stack until it is empty and write the symbols on to the output array.

Follow study with JBR Trisea You Tube Channel for Tamil Explanation
Follow study with JBR Trisea You Tube Channel for Tamil Explanation
Follow study with JBR Trisea You Tube Channel for Tamil Explanation
Follow study with JBR Trisea You Tube Channel for Tamil Explanation
Evaluating Postfix Expression

Parentheses are used in infix expressions change the order of evaluation. But in postfix notation, the order cannot be
altered because there are no parentheses in the expression. Evaluating a postfix expression requires the use of a stack
to store the operands or variables at the beginning of the expression until they are needed.

Algorithm to evaluate postfix expression

1. Make an empty stack


2. Read one character at a time
3. If it is a number then push it onto the stack
4. If it is an operator, then pop two numbers from the stack and apply the operator to the popped numbers
then push the result on to the stack.

Follow study with JBR Trisea You Tube Channel for Tamil Explanation
Step Input Description Stack
Token

1 8 It is an operand. So, push it 8


into the stack

2 2 It is an operand. So, push it 8 2


Example 1: into the stack

3 3 It is an operand. So, push it 8 2 3


Evaluate the postfix expression a b c + * d / . into the stack

Where a = 8, b= 2, c = 3, d=4. 4 + It is an operator. So, pop two 8 5


values from stack. Apply the
operator + and push the result
After applying values the expression will be 8 2 3 + * 4 / into the stack. ( 2+3 = 5)

5 * It is an operator. So, pop two 40


values from stack. Apply the
operator * and push the result
into the stack. ( 8*5=40)

a b c + * d / = 8 2 3 + * 4 / = 10
6 4 It is an operand. So, push it 40 4
into the stack

7 / It is an operator. So, pop two 10


values from stack. Apply the
operator / and push the result
into the stack. ( 40 / 4 =10)

Follow study with JBR Trisea You Tube Channel for Tamil Explanation
THE QUEUE ADT

• A queue is a specialized list in which items can be added to one end and removed from the other. New items are
inserted at the rear end (back end) and existing items are removed from the front end. A queue is also known as a
first-in, first-out (FIFO) list.

• There are many other applications of queues. Stores, theaters, reservation centers, and other similar services
typically process customer requests according to the FIFO principle. A queue would therefore be a logical choice
for a data structure to handle calls to a customer service center, or a wait-list at a restaurant. FIFO queues are also
used by many computing devices, such as a networked printer, or a Web server responding to requests.

Follow study with JBR Trisea You Tube Channel for Tamil Explanation
A queue is an abstract data type (ADT) such that an instance Q supports the following methods:

Q.enqueue(e) : Add element e to the back of queue Q.


Q.dequeue( ) : Remove and return the first element from queue Q; an error occurs if the queue is empty.
Q.first() : Return a reference to the element at the front of queue Q, without removing it; an error occurs if
the queue is empty.
Q.is empty( ) : Return True if queue Q does not contain any elements.
len(Q) : Return the number of elements in queue Q; In Python, it can be implemented using the
special method len.

The Queue ADT can be implemented in several ways. The two most common approaches in Python include the use
of an array-based implementation (Python list) and a linked list implementation.

Follow study with JBR Trisea You Tube Channel for Tamil Explanation
ARRAY IMPLEMENTATION OF QUEUE USING PYTHON LIST

• The python array implementation of a queue is done by storing its elements in a Python list. The enqueue
operation can be implemented by append the item to the end of the list. The dequeue operation can be
implemented by popping and returning the item in the first element of the list.
Queue Operations
Enqueue
The enqueue operation is the insertion operation. In queue, elements can be inserted at the rear end (back end) of
the queue.
def enqueue(self,e):
self._queue.append( e)
self._size=self._size+1

Follow study with JBR Trisea You Tube Channel for Tamil Explanation
Dequeue

The dequeue operation is the deletion operation. In queue, elements can be


deleted from the front end of the queue. Performing dequeue operation in def dequeue(self):

an empty queue creates an error. So, before attempting to remove an item if self.is_empty():
from the list, ensure that the queue is not empty. raise Empty(‘queue is empty’)
pop(0), is called to remove the first element from the list when dequeuing. value = self._queue[self._front]
But it makes a hole in the first position. So, after deleting an element from self._queue[self._front]=None
the queue, a loop is executed to shift all elements beyond the specified
self._front=self._front+1
index to the left, to fill the hole in the sequence caused by the pop.
self._size=self._size-1
Therefore, a call to pop(0) always causes the worst-case behaviour of O(n)
time. return value

To improve on the above strategy avoid the call to pop(0) entirely and
replace the dequeued entry in the array with a reference to None, and def first(self):
maintain an explicit variable first to store the index of the element that is
currently at the front of the queue. if self.is_empty():
raise Empty(‘Queue is Empty’)
return self._queue[self._front]

Follow study with JBR Trisea You Tube Channel for Tamil Explanation
Array Based Implementation of Queue using Python List

class ArrayQueue: if self.is_empty(): q.enqueue(20)


def _ _init_ _ (self): raise Empty(‘queue is empty’) print(‘Queue :’,q._queue)
self._queue=[] value = self._queue[self._front] print(‘Length:’,len(q))
self._size=0 self._queue[self._front]=None print(‘Dequeue:’,q.dequeue())
self._front=0 self._front=self._front+1 print(‘Queue:’,q._queue)
def _ _len_ _(self): self._size=self._size-1 q.enqueue(30)
return self._size return value q.enqueue(40)
def is_empty(self): def first(self): print(Queue:”,q._queue)
return self._size ==0 if self.is_empty(): print(‘first element’,q.first())
def enqueue(self,e): raise Empty(‘Queue is Empty’) print(‘Queue:’,q._queue)
self._queue.append( e) return self._queue[self._front] print(‘Dequeue:’,q.dequeue())
self._size=self._size+1 Q=ArrayQueue() print(‘Queue:’,q._queue)

def dequeue(self): q.enqueue(10)

Follow study with JBR Trisea You Tube Channel for Tamil Explanation
LINKED LIST IMPLEMENTATION OF QUEUE

In linked list implementation of queue, the enqueue operation is performed by inserting an element at the tail of the
list. Dequeue operation is performed by deleting an element at the front of the list.
Node Structure
class node:
def _ _init_ _(self,element,_next):
self.element=element
self._next=_next

In node representation, each node has two instance variables, element and next. The element holds the value. The
next variable holds the pointer to the next node.

Follow study with JBR Trisea You Tube Channel for Tamil Explanation
Class Instance

def _ _init_ _(self):


self.head=none
self.tail=none
self.size=0
Each stack instance maintains three variables. The head member is a reference to the node at the head of the list. The tail
member is a reference to the node at the end of the list. The size variable is an integer value for keeping track of the
number of items on the queue. The value of size is adjusted when elements are inserted into or deleted off the queue.

Enqueue

The implementation of enqueue operation is same as insertion at the tail of a singly linked list. To insert a new element e
onto the queue, the necessary changes to be done in the linked structure are,

i. The next field of the new node is set to none and


ii. Tail is reassigned to the new node.

Follow study with JBR Trisea You Tube Channel for Tamil Explanation
def enqueue(self,element):
new=self.node(element,none)
if self.is_empty():
self.head=new
else:
self.tail._next=new
self.tail=new
self.size = self.size + 1

Follow study with JBR Trisea You Tube Channel for Tamil Explanation
Dequeue
The implementation of deletion operation is same as deletion at the head of a singly linked list. To delete a first
element from the queue, the necessary changes to be done in the linked structure are,
i. Return the first element
ii. By pass the head reference to the second argument of the queue and make it as a head.
def dequeue(self):
if self.is_empty():
raise isemptyerror(‘empty queue so cannot
dequeue’)
result = self.head.element
self.head=self.head._next
self.size= self.size -1
if self.is_empty():
self.tail=none
return result Follow study with JBR Trisea You Tube Channel for Tamil Explanation
First
The first operation returns the element that is at the head of the queue. When the queue is empty, it raises an Empty
exception. When the queue is nonempty, self. head is a reference to the first node of the linked list. The first element
can be identified as self. head. element.
def first(self):
if self.is_empty():
raise isemptyerror(‘queue is empty so cannot retrive’)
return self.head.element

Follow study with JBR Trisea You Tube Channel for Tamil Explanation
Linked list implementation of a Queue new=self.node(element,none) self.tail=none
if self.is_empty(): return result
class linkedqueue: self.head=new def first(self):
class node: else: if self.is_empty():
def _ _init_ _(self,element,_next): self.tail._next=new raise isemptyerror(‘queue is
empty so cannot retrive’)
self.element=element self.tail=new
return self.head.element
self._next=_next self.size = self.size + 1
s=linkedqueue()
def _ _init_ _(self):
len(s)
self.head=none def dequeue(self):
s.enqueue(10)
self.tail=none if self.is_empty():
s.enqueue(20)
self.size=0 raise isemptyerror(‘empty
queue so cannot dequeue’) s.enqueue(30)
def _ _ len_ _(self):
result = self.head.element s.enqueue(40)
return self.size
self.head=self.head._next s.dequeue()
def is_empty(self):
self.size= self.size -1 s.dequeue()
return self.size = = 0
if self.is_empty(): s.first()
def enqueue(self,element):

Follow study with JBR Trisea You Tube Channel for Tamil Explanation
CIRCULAR QUEUE

• A Circular Queue is a special version of queue where the last element of the queue is connected to the first
element of the queue forming a circle. If the last location of the queue is occupied, the new element is inserted at
the first memory location of queue.

Follow study with JBR Trisea You Tube Channel for Tamil Explanation
Enqueue

Enqueue is the insertion operation. New elements are enqueued toward the rear end of the queue, progressing from
the front to index N −1 and continuing at index 0, then 1. The circular queue does not explicitly maintain a variable
for the rear (back) of the queue. So, the location of the next index to insert a value will be calculated as,
avail = (self. front + self. size) % len(self.circularQ)
def enqueue(self, e):
if self.isfull():
return false
avail = (self._front + self._size) % len(self._data)
self._circularQ[avail] = e
self._size += 1

Follow study with JBR Trisea You Tube Channel for Tamil Explanation
Dequeue

To dequeue an element the position of front index is calculated by the relation,


front = (front + 1) % N
The modulo operator, taking the remainder after an integral division.

def dequeue(self):
if self.is_empty( ):
raise Empty( Queue is empty )
answer = self._ circularQ [self._front]
self. circularQ [self._front] = None
self._front = (self._front + 1) % len(self._ circularQ)
self._size −= 1
return answer

Follow study with JBR Trisea You Tube Channel for Tamil Explanation
Python Implementation of circular queue

class CircularQueue: return self._size == 0 self._ circularQ[avail] = e


DEFAULT CAPACITY = 10 self._size += 1
def first(self):
def _ _init _ _(self): if self.is_empty( ): def dequeue(self):
self._ circularQ = [None] * raise Empty( Queue is empty ) if self.is_empty( ):
CircularQueue.DEFAULT return self._ circularQ raise Empty( Queue is empty )
CAPACITY [self._front]
answer = self._ circularQ
self._size = 0 [self._front]
self._front = 0 def enqueue(self, e): self._ circularQ [self._front] =
None
if self.isfull():
def _ _len_ _ (self): self._front = (self._front + 1) %
return false len(self._data)
return self._size
avail = (self._front + self._size) % self._size −= 1
def is_empty(self): len(self._data)
return answer

Follow study with JBR Trisea You Tube Channel for Tamil Explanation
Advantages

Easier for insertion-deletion: In the circular queue, elements can be inserted easily if there are vacant locations
until it is not fully occupied, whereas in the case of a linear queue insertion is not possible once the rear reaches
the last index even if there are empty locations present in the queue.
Efficient utilization of memory: In the circular queue, there is no wastage of memory as it uses the unoccupied
space, and memory is used properly in a valuable and effective manner as compared to a linear queue.
Ease of performing operations: In the linear queue, FIFO is followed, so the element inserted first is the element
to be deleted first. This is not the scenario in the case of the circular queue as the rear and front are not fixed so the
order of insertion-deletion can be changed, which is very useful.

Follow study with JBR Trisea You Tube Channel for Tamil Explanation
DOUBLE ENDED QUEUES

• A double ended queue, or deque, is a data structure that supports insertion and deletion at both the front and the
back of the queue. It is usually pronounced as “deck” or “D.Q.”.

The deque ADT supports the following methods:

D.add_first(e): Add element e to the front of deque D.


D.add_last(e): Add element e to the back of deque D.
D.delete_first( ): Remove and return the first element from deque D; an error occurs if the deque is empty.
D.delete_last( ): Remove and return the last element from deque D; an error occurs if the deque is empty.
D.first(): Return (but do not remove) the first element of deque D; an error occurs if the deque is empty.
D.last(): Return (but do not remove) the last element of deque D; an error occurs if the deque is empty.
D.is_empty( ): Return True if deque D does not contain any elements. len(D): Return the number of
elements in deque D;
Follow study with JBR Trisea You Tube Channel for Tamil Explanation
Implementing a Deque with a Circular Array

Insertion
To find the index of the back of the deque, or the first available slot beyond the back of the deque, calculate

back = (self. front + self. size − 1) % len(self.dequearray)

Enqueue/Insertion at Last

def enqueue(self, e):


if self.isfull():
return False
back = (self. front + self. size-1) % len(self.dequearray)
self._ dequearray[back] = e
self._size += 1

Follow study with JBR Trisea You Tube Channel for Tamil Explanation
Enqueue/Insertion at First

A call to add first may need to wrap around the beginning of the array. So, modular arithmetic to circularly
decrement the index, as

self. front = (self. front − 1) % len(self. data)

def enqueue(self, e):


if self.isfull():
return False
front = (self. front − 1) % len(self. data)
self._ dequearray[front] = e
self._size += 1

Follow study with JBR Trisea You Tube Channel for Tamil Explanation
Deletion / Dequeue at First

def dequeue(self):
if self.is_empty( ):
raise Empty( Queue is empty )
answer = self._ dequearray [self._front]
self._ dequearray [self._front] = None
self._front = (self._front + 1) % len(self._ dequearray)
self._size = self._size -1
return answer

Follow study with JBR Trisea You Tube Channel for Tamil Explanation
Deletion / Dequeue at Last

def dequeue(self):
if self.is_empty( ):
raise Empty( Queue is empty )
answer = self._ dequearray [self._back]
self._ dequearray [self._back] = None
self._back = (self. front + self. size − 1) % len(self.dequearray)
self._size = self._size -1
return answer

Follow study with JBR Trisea You Tube Channel for Tamil Explanation
Deques in the Python Collections Module
An implementation of a deque class is available in Python’s standard collections module. A summary of the most
commonly used behaviours of the collections. deque class are,
Our Deque ADT Collections.deque Description
len(D) len(D) number of element
D.add_first( ) D.appendleft( ) add to beginning
D.add_last( ) D.append( ) add to end
D.delete_first( ) D.popleft( ) remove from beginning
D.delete_last( ) D.pop( ) remove from end
D.first( ) D[0] access first element
D.last( ) D[-1] access last element

Follow study with JBR Trisea You Tube Channel for Tamil Explanation
Implementation of DEQUE using Python Collections Module DQ.popleft()
print("The deque after removing from left: " )
import collections print( DQ )
DQ = collections.deque([10, 20, 30, 40, 50])
DQ.append(60) Output
print( "The deque after appending at right: " ) The deque after appending at right:
print( DQ ) deque([10, 20, 30, 40, 50, 60])
DQ.appendleft(70) The deque after appending at left:
print( "The deque after appending at left: " ) deque([70, 10, 20, 30, 40, 50, 60])
print( DQ ) The deque after removing from right:
DQ.pop() deque([70, 10, 20, 30, 40, 50])
print( "The deque after removing from right: " ) The deque after removing from left:
print( DQ ) deque([10, 20, 30, 40, 50])

Follow study with JBR Trisea You Tube Channel for Tamil Explanation
Advantages of Deque

It allows to add and remove items from the both front and back of the queue.
Deques are faster in adding and removing the elements to the end or beginning.
The clockwise and anti-clockwise rotation operations are faster in a deque.
Disadvantages of Deque

Deque has no fixed limitations for the number of elements they may contain. This interface supports capacity-
restricted deques as well as the deques with no fixed size limit.
They are less memory efficient than a normal queue.

Follow study with JBR Trisea You Tube Channel for Tamil Explanation
thank you

You might also like