You are on page 1of 18

Stack

It is a linear data structure that follows a particular order in which the operations
are performed.
LIFO( Last In First Out ):
This strategy states that the element that is inserted last will come out first. You
can take a pile of plates kept on top of each other as a real-life example. The
plate which we put last is on the top and since we remove the plate that is at the
top, we can say that the plate that was put last comes out first.

Basic Operations on Stack


In order to make manipulations in a stack, there are certain operations provided
to us.
 push() to insert an element into the stack
 pop() to remove an element from the stack
 top() Returns the top element of the stack.
 isEmpty() returns true if stack is empty else false.
 size() returns the size of stack.

Stack

Push:
Adds an item to the stack. If the stack is full, then it is said to be an Overflow
condition.
Algorithm for push:
begin
if stack is full
return
endif
else
increment top
stack[top] assign value
end else
end procedure

Pop:
Removes an item from the stack. The items are popped in the reversed order in
which they are pushed. If the stack is empty, then it is said to be an Underflow
condition.
Algorithm for pop:
begin
if stack is empty
return
endif
else
store value of stack[top]
decrement top
return value
end else
end procedure

Top:
Returns the top element of the stack.
Algorithm for Top:
begin
return stack[top]
end procedure

isEmpty:
Returns true if the stack is empty, else false.
Algorithm for isEmpty:
begin
if top < 1
return true
else
return false
end procedure
Understanding stack practically:
There are many real-life examples of a stack. Consider the simple example of
plates stacked over one another in a canteen. The plate which is at the top is
the first one to be removed, i.e. the plate which has been placed at the
bottommost position remains in the stack for the longest period of time. So, it
can be simply seen to follow the LIFO/FILO order.

Complexity Analysis:
 Time Complexity
Operations   Complexity

push()  O(1)

pop()    O(1)

isEmpty()  O(1)

size() O(1)

Types of Stacks:
 Register Stack: This type of stack is also a memory element present in the
memory unit and can handle a small amount of data only. The height of the
register stack is always limited as the size of the register stack is very small
compared to the memory.
 Memory Stack: This type of stack can handle a large amount of memory
data. The height of the memory stack is flexible as it occupies a large
amount of memory data. 
Applications of the stack:
 Infix to Postfix /Prefix conversion
 Redo-undo features at many places like editors, photoshop.
 Forward and backward features in web browsers
 Used in many algorithms like Tower of Hanoi, tree traversals , stock span
problems, and histogram problems .
 Backtracking is one of the algorithm designing techniques. Some examples
of backtracking are the Knight-Tour problem, N-Queen problem, find your
way through a maze, and game-like chess or checkers in all these problems
we dive into someway if that way is not efficient we come back to the
previous state and go into some another path. To get back from a current
state we need to store the previous state for that purpose we need a stack.
 In Graph Algorithms like Topological Sorting and Strongly Connected
Components
 In Memory management, any modern computer uses a stack as the primary
management for a running purpose. Each program that is running in a
computer system has its own memory allocations
 String reversal is also another application of stack. Here one by one each
character gets inserted into the stack. So the first character of the string is
on the bottom of the stack and the last element of a string is on the top of the
stack. After Performing the pop operations on the stack we get a string in
reverse order.
 Stack also helps in implementing function call in computers. The last called
function is always completed first.
 Stacks are also used to implement the undo/redo operation in text editor.

Array Implementation of Stack


// C program for array implementation of stack
#include <limits.h>
#include <stdio.h>
#include <stdlib.h>

// A structure to represent a stack


struct Stack {
int top;
unsigned capacity;
int* array;
};

// function to create a stack of given capacity. It initializes size of


// stack as 0
struct Stack* createStack(unsigned capacity)
{
struct Stack* stack = (struct Stack*)malloc(sizeof(struct Stack));
stack->capacity = capacity;
stack->top = -1;
stack->array = (int*)malloc(stack->capacity * sizeof(int));
return stack;
}

// Stack is full when top is equal to the last index


int isFull(struct Stack* stack)
{
return stack->top == stack->capacity - 1;
}

// Stack is empty when top is equal to -1


int isEmpty(struct Stack* stack)
{
return stack->top == -1;
}

// Function to add an item to stack. It increases top by 1


void push(struct Stack* stack, int item)
{
if (isFull(stack))
return;
stack->array[++stack->top] = item;
printf("%d pushed to stack\n", item);
}

// Function to remove an item from stack. It decreases top by 1


int pop(struct Stack* stack)
{
if (isEmpty(stack))
return INT_MIN;
return stack->array[stack->top--];
}
// Function to return the top from stack without removing it
int peek(struct Stack* stack)
{
if (isEmpty(stack))
return INT_MIN;
return stack->array[stack->top];
}

// Driver program to test above functions


int main()
{
struct Stack* stack = createStack(100);

push(stack, 10);
push(stack, 20);
push(stack, 30);

printf("%d popped from stack\n", pop(stack));

return 0;
}
Output
10 pushed to stack
20 pushed to stack
30 pushed to stack
30 popped from stack
Top element is 20
Elements present in stack : 20 10
QUEUE
What is Queue Data Structure?
A Queue is defined as a linear data structure that is open at both ends and the operations are
performed in First In First Out (FIFO) order.
We define a queue to be a list in which all additions to the list are made at one end, and all
deletions from the list are made at the other end.  The element which is first pushed into the order,
the operation is first performed on that.

Queue Data Structure

FIFO Principle of Queue:


 A Queue is like a line waiting to purchase tickets, where the first person in line is the first
person served. (i.e. First come first serve).
 Position of the entry in a queue ready to be served, that is, the first entry that will be
removed from the queue, is called the front of the queue(sometimes, head of the queue),
similarly, the position of the last entry in the queue, that is, the one most recently added, is
called the rear (or the tail) of the queue. See the below figure.

Fifo Property in Queue

Characteristics of Queue:
 Queue can handle multiple data.
 We can access both ends.
 They are fast and flexible. 

Queue Representation:

Like stacks, Queues can also be represented in an array: In this representation, the Queue is
implemented using the array. Variables used in this case are
 Queue: the name of the array storing queue elements.
 Front: the index where the first element is stored in the array representing the queue.
 Rear: the index where the last element is stored in an array representing the queue.

Similar to Stack, Queue is a linear data structure that follows a particular order


in which the operations are performed for storing data. The order is First In First
Out (FIFO). One can imagine a queue as a line of people waiting to receive
something in sequential order which starts from the beginning of the line. It is an
ordered list in which insertions are done at one end which is known as the rear
and deletions are done from the other end known as the front. A good example
of a queue is any queue of consumers for a resource where the consumer that
came first is served first. 
The difference between stacks and queues is in removing. In a stack we
remove the item the most recently added; in a queue, we remove the item the
least recently added.
Recommended Problem
Implement Queue using array
Arrays

Queue

+1 more

Goldman Sachs

Amazon

Solve Problem

Submission count: 82.3K

Queue Data structure

Basic Operations on Queue: 


 enqueue(): Inserts an element at the end of the queue i.e. at the rear end.
 dequeue(): This operation removes and returns an element that is at the front end of
the queue.
 front(): This operation returns the element at the front end without removing it.
 rear(): This operation returns the element at the rear end without removing it.
 isEmpty(): This operation indicates whether the queue is empty or not.
 isFull(): This operation indicates whether the queue is full or not.
 size(): This operation returns the size of the queue i.e. the total number of elements
it contains.  
Types of Queues: 
 Simple Queue: Simple queue also known as a linear queue is the most basic version
of a queue. Here, insertion of an element i.e. the Enqueue operation takes place at
the rear end and removal of an element i.e. the Dequeue operation takes place at the
front end. Here problem is that if we pop some item from front and then rear reach
to the capacity of the queue and although there are empty spaces before front means
the stack is not full but as per condition in isFull() function, it will show that the
stack is full then. To solve this problem we use circular queue.
 Circular Queue:  In a circular queue, the element of the queue act as a circular ring.
The working of a circular queue is similar to the linear queue except for the fact that
the last element is connected to the first element. Its advantage is that the memory is
utilized in a better way. This is because if there is an empty space i.e. if no element
is present at a certain position in the queue, then an element can be easily added at
that position using modulo capacity(%n).
 Priority Queue: This queue is a special type of queue. Its specialty is that it
arranges the elements in a queue based on some priority. The priority can be
something where the element with the highest value has the priority so it creates a
queue with decreasing order of values. The priority can also be such that the element
with the lowest value gets the highest priority so in turn it creates a queue with
increasing order of values. In pre-define priority queue, C++ gives priority to
highest value whereas Java gives priority to lowest value.
 Dequeue: Dequeue is also known as Double Ended Queue. As the name suggests
double ended, it means that an element can be inserted or removed from both ends
of the queue, unlike the other queues in which it can be done only from one end.
Because of this property, it may not obey the First In First Out property. 

Applications of Queue: 
Queue is used when things don’t have to be processed immediately, but have to be
processed in First In First Out order like Breadth First Search. This property of Queue
makes it also useful in following kind of scenarios.
 When a resource is shared among multiple consumers. Examples include CPU
scheduling, Disk Scheduling. 
  When data is transferred asynchronously (data not necessarily received at same rate
as sent) between two processes. Examples include IO Buffers, pipes, file IO, etc. 
  Queue can be used as an essential component in various other data structures.
Array implementation Of Queue:
For implementing queue, we need to keep track of two indices, front and rear. We
enqueue an item at the rear and dequeue an item from the front. If we simply increment
front and rear indices, then there may be problems, the front may reach the end of the
array. The solution to this problem is to increase front and rear in circular manner.
Steps for enqueue:
1. Check the queue is full or not
2. If full, print overflow and exit
3. If queue is not full, increment tail and add the element
Steps for dequeue:
1. Check queue is empty or not
2. if empty, print underflow and exit
3. if not empty, print element at the head and increment head
Array Implementation of Queue
// C program for array implementation of queue
#include <limits.h>
#include <stdio.h>
#include <stdlib.h>

// A structure to represent a queue


struct Queue {
int front, rear, size;
unsigned capacity;
int* array;
};

// function to create a queue


// of given capacity.
// It initializes size of queue as 0
struct Queue* createQueue(unsigned capacity)
{
struct Queue* queue = (struct Queue*)malloc(
sizeof(struct Queue));
queue->capacity = capacity;
queue->front = queue->size = 0;

// This is important, see the enqueue


queue->rear = capacity - 1;
queue->array = (int*)malloc(
queue->capacity * sizeof(int));
return queue;
}

// Queue is full when size becomes


// equal to the capacity
int isFull(struct Queue* queue)
{
return (queue->size == queue->capacity);
}

// Queue is empty when size is 0


int isEmpty(struct Queue* queue)
{
return (queue->size == 0);
}

// Function to add an item to the queue.


// It changes rear and size
void enqueue(struct Queue* queue, int item)
{
if (isFull(queue))
return;
queue->rear = (queue->rear + 1)
% queue->capacity;
queue->array[queue->rear] = item;
queue->size = queue->size + 1;
printf("%d enqueued to queue\n", item);
}

// Function to remove an item from queue.


// It changes front and size
int dequeue(struct Queue* queue)
{
if (isEmpty(queue))
return INT_MIN;
int item = queue->array[queue->front];
queue->front = (queue->front + 1)
% queue->capacity;
queue->size = queue->size - 1;
return item;
}

// Function to get front of queue


int front(struct Queue* queue)
{
if (isEmpty(queue))
return INT_MIN;
return queue->array[queue->front];
}

// Function to get rear of queue


int rear(struct Queue* queue)
{
if (isEmpty(queue))
return INT_MIN;
return queue->array[queue->rear];
}

// Driver program to test above functions./


int main()
{
struct Queue* queue = createQueue(1000);

enqueue(queue, 10);
enqueue(queue, 20);
enqueue(queue, 30);
enqueue(queue, 40);

printf("%d dequeued from queue\n\n",


dequeue(queue));

printf("Front item is %d\n", front(queue));


printf("Rear item is %d\n", rear(queue));

return 0;
}
Output
10 enqueued to queue
20 enqueued to queue
30 enqueued to queue
40 enqueued to queue
10 dequeued from queue
Front item is 20
Rear item is 40

SINGLY LINKED LIST

What is Linked List


Like arrays, a Linked List is a linear data structure. Unlike arrays, linked list elements are
not stored at a contiguous location; the elements are linked using pointers. They include a
series of connected nodes. Here, each node stores the data and the address of the next
node.

Linked-List

Why Linked List? 


Arrays can be used to store linear data of similar types, but arrays have the following
limitations:
 The size of the arrays is fixed: So we must know the upper limit on the number of
elements in advance. Also, generally, the allocated memory is equal to the upper limit
irrespective of the usage. 
 Insertion of a new element / Deletion of a existing element in an array of elements
is expensive: The room has to be created for the new elements and to create room
existing elements have to be shifted but in Linked list if we have the head node then
we can traverse to any node through it and insert new node at the required position.
Example: 
In a system, if we maintain a sorted list of IDs in an array id[] = [1000, 1010, 1050,
2000, 2040]. 
If we want to insert a new ID 1005, then to maintain the sorted order, we have to move
all the elements after 1000 (excluding 1000). 
Deletion is also expensive with arrays until unless some special techniques are used. For
example, to delete 1010 in id[], everything after 1010 has to be moved due to this so
much work is being done which affects the efficiency of the code.

 
Advantages of Linked Lists over arrays:
 Dynamic Array.
 Ease of Insertion/Deletion.
Drawbacks of Linked Lists: 
 Random access is not allowed. We have to access elements sequentially starting from
the first node(head node). So we cannot do a binary search with linked lists efficiently
with its default implementation. 
 Extra memory space for a pointer is required with each element of the list. 
 Not cache-friendly. Since array elements are contiguous locations, there is the locality
of reference which is not there in the case of linked lists.
 It takes a lot of time in traversing and changing the pointers.
 Reverse traversing is not possible in singly linked lists.
 It will be confusing when we work with pointers.
 Direct access to an element is not possible in a linked list as in an array by index.
 Searching for an element is costly and requires O(n) time complexity.
 Sorting of linked lists is very complex and costly.
Types of Linked Lists:
 Simple Linked List – In this type of linked list, one can move or traverse the linked
list in only one direction. where the next pointer of each node points to other nodes
but the next pointer of the last node points to NULL. It is also called “Singly Linked
List”.
 Doubly Linked List – In this type of linked list, one can move or traverse the linked
list in both directions (Forward and Backward)
Basic operations on Linked Lists:
 Deletion
 Insertion
 Search
 Display
Array Representation of Singly Linked Lists: 
A linked list is represented by a pointer to the first node of the linked list. The first node
is called the head of the linked list. If the linked list is empty, then the value of the head
points to NULL. 
Each node in a list consists of at least two parts: 
 A Data Item (we can store integers, strings, or any type of data).
 Pointer (Or Reference) to the next node (connects one node to another) or An
address of another node
In C, we can represent a node using structures. Below is an example of a linked list
node with integer data. 
// A linked list node
struct Node {
int data;
struct Node* next;
};

Doubly Linked List (DLL)

A Doubly Linked List (DLL) contains an extra pointer, typically called the previous
pointer, together with the next pointer and data which are there in the singly linked list.

// Node of a doubly linked list

struct Node {
int data;

// Pointer to next node in DLL


struct Node* next;

// Pointer to previous node in DLL


struct Node* prev;
};

What is Binary Tree Data Structure?


Binary Tree is defined as a tree data structure where each node has at most 2 children. Since each
element in a binary tree can have only 2 children, we typically name them the left and right child.
Binary Tree Representation

A Binary tree is represented by a pointer to the topmost node (commonly known as the “root”) of
the tree. If the tree is empty, then the value of the root is NULL. Each node of a Binary Tree
contains the following parts:
1. Data
2. Pointer to left child
3. Pointer to right child
Basic Operation On Binary Tree:
 Inserting an element.
 Removing an element.
 Searching for an element.
 Traversing the tree.
Auxiliary Operation On Binary Tree:
 Finding the height of the tree
 Find the level of a node of the tree
 Finding the size of the entire tree.

Topic :
 Introduction
 Basic Operation
 Traversals
 Standard Problems on Binary Trees
Introduction :
1. Introduction to Binary Tree – Data Structure and Algorithm Tutorials
2. Properties of Binary Tree
3. Types of Binary Tree
4. Applications, Advantages and Disadvantages of Binary Tree
5. Binary Tree (Array implementation)
6. Complete Binary Tree
7. Perfect Binary Tree
Basic Operations on Binary Tree:
1. Insertion in a Binary Tree
2. Deletion in a Binary Tree
3. Enumeration of Binary Trees
4. Tree Traversals (Inorder, Preorder and Postorder)

You might also like