DSA Book
DSA Book
This book contains all the information regarding DSA which is asked in Placement Tests. Nowadays you will see many books
and online pages providing information on DSA. Mostly those books contain one section i.e either the coding questions or the
theoretical part. There is no such proper book providing all the updated information at one single place.
This book contains various questions and theory knowledge of all the types asked in Placement tests. This book carries all the
theory and practice questions along with examples and shortcut methods.
It is hoped that the subject matter will instill trust in the applicants, and that the book will assist them in finding an ideal teacher.
Disclaimer: This book is made and published under the complete knowledge and expertise of the Author, however if there will be
any error then it will be taken care of in the next Revised edition. Constructive suggestions and feedback are most welcome by
our esteemed readers.
1
First Edition ● The correct price of the book is already
mentioned on this page. Any revised price on the
May 2021 frontend or backend of the book is not
Edition: 1 (2021) acceptable.
Price- Rs.999/-
2
Contents
3
7. print element not found
8. exit
Chapter 1. Linear search
What is Linear Search ?
C Code:-
Implementation:-
#include <stdio.h> //header files
● Step 1- The list given is the list of elements in an int main () //main function
unsorted array. {
● Step 2- The element to be searched is called an int a[10] = {10, 23, 40, 1, 2, 0, 14, 13, 50, 9};
item, as mentioned in the image, so the value int item, i, flag;
item is compared with all the elements of the
array starting from the 0th element. printf("\nEnter Item which is to be find\n");
● Step 4- As soon as any index contains the same scanf("%d",&item);
value, we stop further comparisons and change
flag value from 0 to 1 //looping logic
● Step 4- If the value is not found until the end of for (i = 0; i< 10; i++)
the array then stop and print value not found {
// if else condition
if(a[i] == item)
Algorithm:- {
flag = i+1;
1. i=1 break;
2. if i>n,go to step 7 }
3. if A[i]=x,go to step 6 else
4. i=i+1 flag = 0;
5. Go to step 2 }
6. print element x found at i
4
if(flag != 0) {
{ int l = ar.length;
//printing the element which is to find for(int i = 0; i < l; i++)
printf("\nItem found at location %d\n",flag); {
} if(ar[i] == s)
else return i;
{ }
printf("\nItem not found\n"); return -1;
} }
return 0; public static void main(String args[])
} {
int ar[] = { 2, 3, 4, 10, 40 };
System.out.println("Enter a number you want to search
for - ");
Scanner s= new Scanner(System.in);
C++ Code
int num=s.nextInt();
#include <iostream> int result = search(ar, num)+1;
using namespace std; if(result == -1)
int main() System.out.print("Element not found.");
{ else
int list[100],size,i,search_el;//Initializing variables. System.out.print("Element found at index " + result);
}
cout<<"Enter size of the list: ";//Taking inputs. }
cin>>size;
5
O(n)
Space Complexity
O(1)
Average Comparisons
(n+1)/2
1. (n-1)/2
Chapter 2. Binary Search
2. Log n
3. (n+1)/2
4. (n)/2 What is Binary Search ?
(Amazon – Mettl Test) Binary search is a very fast and efficient searching
algorithm. It requires to be list be in a sorted order, ie;
Solution & Explanation either in ascending or descending.In this method, to search
an element you might compare that respective element
Just say if you have to find a given element in a sequential present in the center of the list and if it’s same then the
search. It can be found in the first try, then 1 comparison is search is successfully finished and if not, then the list is
required similarly…total comparisons can be 1+2+…+n = divided into two parts:one from 0th element to the centered
n(n+1)/2 element and other from the centered element to the last
element.
Avg will be n(n+1)/2 divided by n ( total elements) = How Binary Search works?
(n+1)/2 1. The searching algorithm proceed from any of two halves
2. Depends upon whether the element you are searching is
Ans. Option C greater or smaller than the central element
3. If the element is small then, searching is done in first half
Question 2. The worst-case occurred in the linear search 5. If it is big then searching is done in the second half.
algorithm when
It is a fast search algorithm with the complexity of O(log
1. The element in the middle of an array n).
2. Item present in the last
3. Item present in the starting
4. Item has the maximum value
(TCS NQT)
Ans. Option B
6
Implementation of Binary Search
Step 2-If the searched element ie; say 15(in context with
the image given below) is in the center then the search is
terminated, as we can see here it is not.
C Code
#include<stdio.h> //header files
7
int main() //main function cin>>search_element;
{
int arr[10] = {9, 26, 33, 47, 53, 60, 75, 80, 86, 99}; location = binarySearch(arr, 0, 9, search_element);
int item, location = -1;
if(location != -1)
printf("Enter the item which you want to find "); {
scanf("%d",&item); cout<<"Search element found at"<<location<<"
location"; //Printing the result.
location = binarySearch(arr, 0, 9, item); }
else
if(location != -1) //looping logic {
{ cout<<"Search element not present";
printf("Item found at location %d",location); //printing }
the element return 0;
} }
else
{ int binarySearch(int a[], int left, int right, int
printf("Item not found"); search_element)
} {
return 0; int middle;
} if(right >= left)
{
int binarySearch(int a[], int start, int last, int item) middle = (left + right)/2;
{ if(a[middle] == search_element) //Checking if elemnet is
int mid; present at middle.
if(last >= start) {
{ return middle+1;
mid = (start + last)/2; }
if(a[mid] == item){ else if(a[middle] < search_element) //Checking if
return mid+1; elemnet is present in greater half.
} {
else if(a[mid] < item){ return binarySearch(a,middle+1,right,search_element);
return binarySearch(a,mid+1,last,item); }
} else //Checking if elemnet is present in samller half.
else{ {
return binarySearch(a,start,mid-1,item); return binarySearch(a,left,middle-1,search_element);
} }
}
return -1; }
} return -1;
}
C++ Code Java Code
import java.util.*;
#include <iostream>//Header file. class Main {
using namespace std; int search(int arr[], int x)
{
int binarySearch(int[], int, int, int); int l = 0, r = arr.length - 1;
while (l <= r) {
int main() //Main function. int m = l + (r - l) / 2;
{
int arr[10] = {19, 26, 37, 53, 56, 61, 77, 82, 87, 91}; if (arr[m] == x) //if x is in the middle
int search_element, location=-1; return m;
if (arr[m] < x) //if x is greater, search the right half
cout<<"Enter the element which you want to search: "; l = m + 1;
8
else //if x is smaller, search the left half Exercise
r = m - 1; Question 1.Binary search algorithm can’t be applied to
}
return -1; //not found 1. Pointed Array List
} 2. Sorted Binary Tree
public static void main(String args[]) 3. Unordered Array
{ 4. Sorted Linked List
Main s=new Main();
Scanner sc= new Scanner(System.in); (Cisco, Walmart Labs)
System.out.println("Enter the element to be searched
"); Solution & ExplanationYou cannot use a binary search on
int num=sc.nextInt(); an unsorted list. Your best bet is to probably iterate over the
int arr[]={3,5,6,7,10,14,15,75,88,96,99}; list’s items until you find the element you are looking for,
int result = s.search(arr, num); an O(n) operation, i.e. do linear search
if (result == -1)
System.out.println("No match found in the Array"); Ans. C
else
System.out.println("Match found at index " + Question 2. Which of the following searching algorithms
result); works on the divide and conquer?
}
} 1. Binary Search
2. Linear
Output:- 3. Sequential
Enter the item which you want to find 26 4. Merge Sort
Item found at location 2
Enter the item which you want to find 3 (CoCubes, Atos Syntel)
Item not found
Solution & ExplanationBinary search only checks the
middle element of the array. when it checks the middle
Time Complexity For Binary Search
element and middle element is not equal to the given
element then we divide the list in two subparts.Ans: Both A
Best &D
O(1)
Average
O(1)
Examples: Bubble sort, Insertion sort, Merge Sort,
9
guranteed to stay in the same order as they appeared in the Examples: Bubble Sort, Selection Sort, Insertion Sort, Heap
dataset is small.
external sorting.
Chapter 4. Bubble Sort
Comparison based Sorting and Counting based Sorting Sorting is the process of arranging the data in some logical
In Comparison based sorting, a comparator is required to order. Bubble sort is an algorithm to sort various linear
ordering to arrange the elements. The logical order can be ascending and descending in case
In-Place Sorting means to sort the array by modifying the Implementation of Bubble Sort
element order directly within the array.
Let’s take an example ,we have a list of number stored in
● No auxiliary data structure is used. array
● There can be only a constant amount of extra
space usually less than log(n). So this algorithm
is space efficient.
10
Logic starts with comparison of the first two elements and [END OF INNER LOOP]
if the left element is greater than the right element,they [END OF OUTER LOOP
swap their position. comparison continues till the end of the Step 4: Return
array.
C Code:-
If we talk about the example taken in the below image, the
in their correct order, you can refer to the image below, for printf("Before bubble sort: \n");
display(array, size);
better understanding.
int i, j, temp;
for (i = 0; i < size-1; i++){
11
*var2 = temp;
} /* Prints the array */
//Here we will implement bubbleSort. void printArray(int a[])
void bubbleSort(int arr[], int n) {
{ int len = a.length;
int i, j; for (int i=0; i<len; i++)
for (i = 0; i < n-1; i++) System.out.print(a[i] + " "); //printing the sorted
//Since, after each iteration rightmost i elements are array
sorted. System.out.println();
for (j = 0; j < n-i-1; j++) }
if (arr[j] > arr[j+1])
swap(&arr[j], &arr[j+1]); // Main method to test above
} public static void main(String args[])
// Function to print array. {
void display(int arr[], int size) Main ob = new Main();
{ int a[] = {64, 34, 25, 12, 22, 11, 90};
int i; ob.bubbleSort(a);//calling the bubbleSort function
for (i=0; i < size; i++) System.out.println("Sorted array");
cout<<arr[i]<<"\t"; ob.printArray(a); //calling the printArray function
cout<<endl; }
} }
//Main function to run the program.
int main() Output:
{ Before bubble sort
int array[] = {5, 3, 1, 9, 8, 2, 4,7}; 53198247
int size = sizeof(array)/sizeof(array[0]); After bubble sort:
cout<<"Before bubble sort: \n"; 12345789
display(array, size);//Calling display function to print
unsorted array.
bubbleSort(array, size);
cout<<"After bubble sort: \n";
display(array, size);//Calling display function to print
sorted array.
return 0;
}
Java Code
class Main
{
void bubbleSort(int a[])
{
int len = a.length; // calculating the length of array
for (int i = 0; i < len-1; i++)
for (int j = 0; j < len-i-1; j++) if (a[j] > a[j+1])
//comparing the pair of elements
{
// swaping a[j+1] and a[i]
Performance Based Analysis of Bubble Sort Algorithm
int temp = a[j];
Pros
a[j] = a[j+1];
1. Easy to implement
a[j+1] = temp;
2. Cool to implement
}
3. Gives the largest value of the array in the first iteration
}
itself.
12
4. Or the smallest value of array in the first iteration itself
(Minor tweak in implementation)
5. No demand for large amounts of memory for operation
😀
Cons
1. Noob (Bad) algorithm
2. Very horrible time complexity of O(n2)
Interesting Facts
13
for (i = 1; i < size; i++)
{
target = array[i];
Execution of Insertion Sort
j = i - 1;
Step 5-A[j+1]=temp,I=I=1
C++ Code
Step 6-Exit #include <iostream>
using namespace std;
C code:-
//Function to print array.
#include <stdio.h> void display(int arr[], int size)
{
// Here we are implementing Insertion sort int i;
void insertionSort(int array[], int size) for (i=0; i < size; i++)
{ cout<< arr[i]<<"\t";
int i, target, j; cout<<"\n";
14
} {
int key = a[i];
//Main function to run the program. int j = i - 1;
int main()
{ /* Shift elements of a[0..i-1], that are
int array[] = {5, 3, 1, 9, 8, 2, 4,7}; greater than key, to one position ahead
int size = sizeof(array)/sizeof(array[0]); of their current position */
while (j >= 0 && a[j] > key)
cout<<"Before Insertion sort: \n"; {
display(array, size);//Using dispaly function to print a[j + 1] = a[j];
unsorted array. j = j - 1;
}
int i, target, j; a[j + 1] = key;
for (i = 1; i < size; i++) }
{ }
target = array[i];
j = i - 1; /* A utility function to print array of size n*/
static void printArray(int a[])
/* Here the elements in b/w arrary[0 to i-1] {
which are greater than target are moved int len = a.length;
ahead by 1 position each*/ for (int i = 0; i < len; ++i)
while (j >= 0 && array[j] > target) System.out.print(a[i] + " ");
{ System.out.println();
array[j + 1] = array[j]; }
j = j - 1; }
}
array[j + 1] = target; Output:
} Before Insertion sort:
cout<<"After Insertion sort: \n"; 53198247
display(array, size);//Using dispaly function to print After Insertion sort:
sorted array. 12345789
return 0;
} Advantages and Disadvantages of Insertion Sort
Advantages
Java Code
1. It is simple, small and easy to write.
// Java Code for implementation of Insertion Sort 2. It doesn’t use a lot of overhead.
class PrepInsta 3. It uses in place sorting, thus O(1) space
{ requirements
// Main method 4. If data is almost sorted, then it can be very fast
public static void main(String args[]) approaching O(n) and faster than Merge sort
{ (for sorted data, and small N, else merge sort is
int a[] = { 12,11,13,5,6 }; faster)
5. Efficient for (quite) small data sets.
PrepInsta ob = new PrepInsta();
ob.sort(a); Disadvantages
15
1. You will encounter the best case if the data is
already or nearly sorted
2. It will give worst case results if the array is sorted
in opposite order as required
Chapter 6. Selection Sort
Time Complexity For Insertion Sort
What is Selection
In this Sorting technique the list is divided into two parts.
Best The first one is the left end and the second one is the right
end . The selection Sort is a very simple sorting algorithm.
Ω(n)
Θ(n2)
Step 1-Select the smallest value in the list.
Step 2-Swap smallest value with the first element of the
Worst list.
Step 3-Again select the smallest value in the list (exclude
O(n2) first value).
Step 4- Repeat above step for (n-1) elements until the list is
sorted.
16
[End of Step 1 loop]
According to the image below, 8 is the smallest value in /* Display function to print values */
this array so 8 is swapped with the first element that is 72. void display(int array[], int size)
{
Similarly, in the next iteration we’ll find the next smallest int i;
value, excluding the starting value so in this array 10 is the for (i=0; i < size; i++)
second smallest value, which is to be swapped with 50. {
printf("%d ",array[i]);
These iterations will continue until we have the largest }
element to the right most end, along with all the other printf("\n");
elements in their correct position. }
And then we can finally say that the given array is // The main function to drive other functions
converted into a sorted array. int main()
{
int array[] = {5, 3, 1, 9, 8, 2, 4, 7};
int size = sizeof(array)/sizeof(array[0]);
int i, j, min_idx,temp;
A[LOC]=TEMP.
17
C++ Code:- // Main method, responsible for the execution of
the code
#include <iostream>
public static void main(String args[])
using namespace std;
{
//Display function to print values.
PrepInsta ob = new PrepInsta();
void display(int array[], int size)
int a[] = {19,17,25,43,15}; //initializing values to the
{
array
int i;
ob.sort(a); //calling sort method
for (i=0; i < size; i++)
System.out.println("Sorted array");
{
ob.printArray(a); //calling printArray method
cout<<array[i]<<"\t";
}
}
cout<<"\n";
void sort(int a[])
}
{
int len = a.length; //calculating the length of the
//The main function to drive other functions.
array
int main()
// One by one move boundary of unsorted subarray
{
for (int i = 0; i < len-1; i++)
int array[] = {5, 3, 1, 9, 8, 2, 4, 7};
{
int size = sizeof(array)/sizeof(array[0]);
// Find the minimum element in unsorted array
int min = i;
cout<<"Before sorting: \n";
for (int j = i+1; j < len; j++)
display(array, size);//Using dispaly function to print
if (a[j] < a[min])
unsorted array.
min = j;
int i, j, min_idx,temp;
// Swap the found minimum element with the first
element
//Loop to iterate elements of array.
int temp = a[min];
for (i = 0; i < size-1; i++)
a[min] = a[i];
{
a[i] = temp;
//Here we try to find the min element in the array.
}
min_idx = i;
}
for (j = i+1; j < size; j++)
{
// Prints the sorted array
if (array[j] < array[min_idx])
void printArray(int a[])
min_idx = j;
{
}
int len = a.length;
//Here we interchange the min element with the first
for (int i=0; i<len; ++i) //printing the sorted array
one.
System.out.print(a[i]+" ");
temp = array[min_idx];
System.out.println();
array[min_idx] = array[i];
}
array[i] = temp;}
cout<<"After sorting: \n";
display(array, size); //Using dispaly function to print
}
sorted array.
return 0;
Output
This is how array looks before sorting:
}
53198247
This is how array looks after sorting:
Java Code: 12345789
class PrepInsta
{ Performance
18
The Selection Sort best and worst case scenarios both
follow the time complexity format O(n^2) as the sorting Chapter 7. Merge Sort
operation involves two nested loops. The size of the array
again affects the performance.[1]
How Merge Sort Works
Strengths Merge Sort is an example of the divide and conquer
approach.It divides the array into equal halves and then
● The arrangement of elements does not affect its combines in a sorted manner.In merge sort the unsorted list
performance. is divided into N sublists, each having one element.
● Uses fewer operations, so where data movement 1. The complexity of the merge sort algorithm is O(NlogN)
is costly it is more economical where N is the number of elements to sort.
2. It can be applied to files of any size.
Weaknesses 3. In Merge sort all the elements are divided into two
sub-array again and again until one element is left.
● The comparisons within unsorted arrays requires 4. After the completion of the divide and conquer the
O(n^2) which is ideal where n is small elements are merged to make a sorted array .
5. This sorting is less efficient and it require more space as
Time Complexity For Selection Sort compare to other sorting,
Best
Ω(n2)
Average
Θ(n2)
Worst
O(n2)
19
{
int i=strt,j=mid+1,p,index = strt;
int temp[10];
void merge(int a[], int strt, int mid, int end) //Display function to print values.
20
void display(int arr[], int size) j = j+1;
{ }
int i;
for(i = 0; i < size; i++) index++;
{ }
cout<<arr[i]<<"\t"; if(i>mid)
} {
cout<<"\n"; while(j<=end)
} {
temp[index] = a[j];
int main() index++;
{ j++;
int a[10]= {8, 4, 5, 1, 3, 9, 0, 2, 7, 6}; }
int i; }
else
int size = sizeof(a)/sizeof(a[0]); {
cout<<"Before sorting: \n"; while(i<=mid)
display(a, size);//Using display function to print unsorted {
array. temp[index] = a[i];
cout<<"After sorting: \n"; index++;
mergeSort(a,0,size-1); i++;
display(a, size);//Using display function to print sorted }
array. }
} p = strt;
//Dividing the list into two sublist, sorting them and while(p<index)
merging them. {
void mergeSort(int a[], int strt, int end) a[p]=temp[p];
{ p++;
int mid; }
if(strt<end) }
{
mid = (strt+end)/2;
Java Code:-
mergeSort(a,strt,mid);//Divide //Java Program for Merge Sorting
mergeSort(a,mid+1,end);//Conqure public class Main {
merge(a,strt,mid,end);//Combine public static void display(int[] arr, int size) //this
} function display the array
} {
//Combining two sublist. for(int i = 0; i < size; i++) {
void merge(int a[], int strt, int mid, int end) System.out.print(arr[i] + " ");
{ }
int i=strt,j=mid+1,p,index = strt; System.out.println();
int temp[10]; }
21
mergeSort(a, 0, size - 1); Merge Sort Advantages
display(a, size);
} 1. Fast ! Time complexity : O(N Log N)
2. Reliable, it gives same time complexity in all cases.
static void mergeSort(int[] a, int strt, int end) 3. Tim sort variant of this really powerful (Not important
//this function apply merging and sorting in the array for Placements)
{
int mid; Merge Sort Disadvantages
if(strt < end) 1. Space Complexity sucks !!!
{ 2. Space Complexity : O(n), most other algorithm have
mid = (strt + end) / 2; O(1)
Output
Input array - 11 9 6 19 33 64 15 75 67 88
Output array - 6 9 11 15 19 33 64 67 75 88
22
● If p < r then
Chapter 8. Quick Sort ● q= Partition (A, p, r)
● Quick Sort (A, p, q)
● Quick Sort (A, q + r, r)
How Quicksort works
Quick sort is an algorithm of the divide and conquer type.
That is,the problem of sorting a set is reduced to the Partition Algorithm
problem of sorting two smaller sets.
PARTITION (A, p, r)
23
}
24
int partition (int array[], int low, int high) return 0;
{ }
//Pivot element selected as right most element in array
each time.
Java Code:-
int pivot = array[high];
int swapIndex = (low - 1); //swapping index. /* Java program for Merge Sort */
public class MergeSort {
for (int j = low; j <= high- 1; j++) void merge(int arr[], int l, int m, int r)
{ {
//Check if current element is smaller than pivot int n1 = m - l + 1;
element. int n2 = r - m;
if (array[j] < pivot) int L[] = new int[n1];
{ int R[] = new int[n2];
swapIndex ++; //increment swapping index. for (int i = 0; i < n1; ++i)
swap(&array[swapIndex], &array[j]); L[i] = arr[l + i];
} for (int j = 0; j < n2; ++j)
} R[j] = arr[m + 1 + j];
swap(&array[swapIndex + 1], &array[high]); int i = 0, j = 0;
return (swapIndex + 1); int k = l;
} while (i < n1 && j < n2) {
if (L[i] <= R[j]) {
//Recursive function to apply quickSort arr[k] = L[i];
void quickSort(int array[], int low, int high) i++;
{ }
if (low < high) else {
{ arr[k] = R[j];
/* indexPI is partitioning index, partition() function j++;
will }
return index of partition */ k++;
int indexPI = partition(array, low, high); }
while (i < n1) {
quickSort(array, low, indexPI - 1); //left partition arr[k] = L[i];
quickSort(array, indexPI + 1, high); //right partition i++;
} k++;
} }
while (j < n2) {
//Function to display the array arr[k] = R[j];
void display(int array[], int size) j++;
{ k++;
int i; }
for (i=0; i < size; i++) }
cout<< array[i]<<"\t"; void sort(int arr[], int l, int r)
} {
if (l < r) {
//Main function to run the program int m = (l + r) / 2;
int main() sort(arr, l, m);
{ sort(arr, m + 1, r);
int array[] = {7, 9, 1, 3, 5, 2, 6, 0, 4, 8}; merge(arr, l, m, r);
int size = sizeof(array)/sizeof(array[0]); }
cout<<"Before Sorting: \n"; }
display(array, size); static void printArray(int arr[])
quickSort(array, 0, size-1); {
cout<<"After Sorting: \n"; int n = arr.length;
display(array, size); for (int i = 0; i < n; ++i)
25
System.out.print(arr[i] + " ");
System.out.println();
}
public static void main(String args[])
{
int arr[] = { 12, 11, 13, 5, 6, 7 };
System.out.println("Given Array");
printArray(arr);
1. As the name suggests !!! Is quick as a horse !! having each distinct key value, after this it performs some
Counting_Sort(A,B,K)
2- for i<-0 to k
3- C[i]<-0
26
4- for j<-1 to length[A] C[i]<-0
// C[i] now contains the number of elements less than or C[A[1]]<-C[1]+1= 0+1 =1
equal to i.
C[1]<-1
10- C[A[j]]<-C[A[j]]-1.
C[6]<-1
Step 3-
For i= 1 to 6
C[i]<-C[i]+C[i-1]
For i=1
C[1]<-C[1]+C[0]
C[1]<-1+0 = 1
For i=2
Execution of Counting Sort
C[2]<-C[2]+C[1]
According to algorithm let us take an example
C[1]<-1+0 = 1
Step 1-
27
Step 4- }
// function calling
counting_sort(a, k, n);
For j=10 to 1 printf("\n");
return 0;
B[C[A[j]]]<-A[j] }
C code-
//sorting in c
//counting sort
#include
//function for counting sort
void counting_sort(int a[], int k, int n)
{
int i, j; #include <iostream>
int b[15], c[100]; using namespace std;
for (i = 0; i <= k; i++)
c[i] = 0; void countSort(int array[], int size)
for (j = 1; j <= n; j++) {
c[a[j]] = c[a[j]] + 1;
for (i = 1; i <= k; i++) int output[10];
c[i] = c[i] + c[i-1]; int count[10];
for (j = n; j >= 1; j--) int max = array[0];
{
b[c[a[j]]] = a[j]; //Find the largest element of the array
c[a[j]] = c[a[j]] - 1; for (int i = 1; i < size; i++)
} {
printf("The Sorted array is : "); if (array[i] > max)
// printing the output max = array[i];
for (i = 1; i <= n; i++) }
printf("%d ", b[i]);
} //Initializing count array with zeros.
/* End of counting_sort() */ for (int i = 0; i <= max; ++i)
// main function {
int main() count[i] = 0;
{ }
int n, k = 0, a[15], i;
printf("Enter the number of input : "); //Storing the count of each element
// user input for (int i = 0; i < size; i++) {
scanf("%d", &n); count[array[i]]++;
printf("\nEnter the elements to be sorted :\n"); }
for (i = 1; i <= n; i++)
{ //Storing the cumulative count of each array
scanf("%d", &a[i]); for (int i = 1; i <= max; i++) {
if (a[i] > k) { count[i] += count[i - 1];
k = a[i]; }
}
28
/*Finding the index of each element of the original array {
in count array, c[i] += c[i - 1];
and place the elements in output array*/ }
for (int i = size - 1; i >= 0; i--) { for (int i = arr.length - 1; i >= 0; i--)
output[count[array[i]] - 1] = array[i]; {
count[array[i]]--; output[c[arr[i] - min] - 1] = arr[i];
} c[arr[i] - min]--;
}
for (int i = 0; i < size; i++) { for (int i = 0; i < arr.length; i++)
array[i] = output[i]; {
} arr[i] = output[i];
} }
}
//printing function
void display(int array[], int size) static void display(int[] arr)
{ {
for (int i = 0; i < size; i++) for (int i = 0; i < arr.length; i++)
cout << array[i] << "\t"; {
cout << endl; System.out.print(arr[i] + " ");
} }
System.out.println("");
}
int main() public static void main(String[] args)
{ {
int array[] = {2, 5, 2, 8, 1, 4, 1}; int[] arr = {-4, -8, 0, -1, 8, 5, 1, 10};
int n = sizeof(array) / sizeof(array[0]); cSort(arr);
cout<<"Unsorted array\n"; display(arr);
display(array, n); }
countSort(array, n); }
cout<<"Sorted array\n"; Time Complexity
display(array, n);
} Best O(n + k)
29
Chapter 10. Radix sort- Implementation of Radix sort
It is a sorting algorithm that is used to sort elements. Radix Given to a list ,the numbers would be sorted in three
sort is the method that many people begin to use when phases. the list is (248,140,261,323,438,120,221,443,266).
The list of names is first sorted according to the first letter 0.(Note 261 will now be at the bottom of the pile and 438 at
of each name. That is, the names are arranged in 26 the top of the pile.) The cards are now rein put to the sorter.
name.And so on.
(B)- In the second phase, the tens digits are sorted into
30
2-use a stable sort to array A on digit i
The code for radix sort assumes that each element in the
C code:
31
for(i=0;i<10;i++)
bucket_count[i]=0; for (int i = 0; i < max; ++i)
for(i=0;i<10;i++) count[i] = 0;
{
// sort the numbers according to the digit at passth //Calculate count of elements
place for (int i = 0; i < size; i++)
remainder = (a[i]/divisor)%10; count[(array[i] / place) % 10]++;
bucket[remainder][bucket_count[remainder]] = a[i];
bucket_count[remainder] += 1; //Calculating cumulative count
} for (int i = 1; i < max; i++)
// collect the numbers after PASS pass count[i] += count[i - 1];
i=0;
for(k=0;k<10;k++) //Placing the elements in sorted order
{ for (int i = size - 1; i >= 0; i--)
for(j=0;j<bucket_count[k];j++) {
{ output[count[(array[i] / place) % 10] - 1] = array[i];
a[i] = bucket[k][j]; count[(array[i] / place) % 10]--;
i++; }
}
} for (int i = 0; i < size; i++)
divisor *= 10; array[i] = output[i];
}
}
} //Main function to implement radix sort
void radixsort(int array[], int size)
{
C++ code //Getting maximum element
int max = getMax(array, size);
32
// Change count[i] so that count[i] now
Output: contains
Before sorting // actual position of this digit in
112 400 543 441 678 675 output[]
9 777 for (i = 1; i < 10; i++)
After sorting count[i] += count[i - 1];
9 112 400 441 543 675
678 777 // Build the output array
for (i = len - 1; i >= 0; i--)
{
output[count[ (a[i]/exp)%10 ]
Java code-
- 1] = a[i];
//Radix sort Java implementation count[ (a[i]/exp)%10 ]--;
import java.io.*; }
import java.util.*;
// Copy the output array to arr[], so that
class PrepInsta arr[] now
{ // contains sorted numbers according to
/*Main Method to check for curent digit
above function*/ for (i = 0; i < len; i++)
>public static void main (String[] args) a[i] = output[i];
{ }
int a[] = {17, 45, 75, 90, 82,
24, 12, 60}; // The main function to that sorts arr[] of size n
int len = a.length; using
radixsort(a,len); // Radix Sort
print(a,len); static void radixsort(int a[], int len)
} {
// Find the maximum number to know
// A utility function to get maximum value in a[] number of digits
static int getMax(int a[], int n) int m = getMax(a, len);
{
int mx = a[0]; // Do counting sort for every digit. Note
for (int i = 1; i < len; i++) that instead
if (a[i] > mx) // of passing digit number, exp is
mx = a[i]; passed. exp is 10^i
return mx; // where i is current digit number
} for (int exp = 1; m/exp > 0; exp *= 10)
countSort(a, len, exp);
// A function to do counting sort of arr[] }
according to
// the digit represented by exp. // A utility function to print an array
static void countSort(int a[], int len, int exp) static void print(int a[], int len)
{ {
int output[] = new int[len]; // output for (int i=0; i<len; i++)
array System.out.print(a[i]+" ");
int i; }
int count[] = new int[10];
Arrays.fill(count,0); }
Time complexity of radix sort
// Store count of occurrences in count[] BEST- O(d(n + k))
for (i = 0; i < len; i++) Average- O(d(n + k))
count[ (a[i]/exp)%10 ]++; Worst- O(d(n + k))
33
3- do exchange A[1]<-> heap-size[A]-1
Chapter 11. Heap sort
4- heap-size[A]<-heap-size[A]-1
A heap is a complete binary tree which is represented using
5- MAX-HEAPIFY(A,1)
array or sequential representation.
BUILD-MAX-HEAP(A)
It is a special balanced binary tree data structure where the
1- heap-size[A]<-length[A]
root node is compared with its children and arranged
accordingly.Normally in max heap parent node always has 2- for i<-(length[A]/2) down to 1 do
The worst and Average complexity of heap sort is O(n Implementation of heap sort
As we know that heap sort is based on the tree structure.
log2 n).
so we will take an example of heap sort based on the tree.
● From the given array, build the initial max heap.
● Interchange the root element with the last Originally the given array is :[6,14,3,25,2,10,20,7,6]
element.
First we call Build-max heap
● Use repetitive downward operation from the root
node to rebuild the heap of size one less than the
heap size[A]=9
starting.
so,i=4 to 1, call MAX HEAPIFY (A,i)
Algorithm of heap sort
i.e., first we call MAX HEAPIFY (A,4)
2- r<-right[i] r<-right[4] = 9
HEAP-SORT(A) i=4
1- BUILD-MAX-HEAP(A) since the parent node is greater than its child node.
34
If the parent node is greater than the child node then the {
parent node replaces it with the lesser child node. int i;
for (i = size / 2 - 1; i >= 0; i--)
similarly for i=3,2,1 we get the following heap tree. heapify(arr, size, i);
for (i=size-1; i>=0; i--)
{
// swaping logic
temp = arr[0];
arr[0]= arr[i];
arr[i] = temp;
heapify(arr, i, 0);
}
}
heapSort(arr, size);
if (max!= i)
{
// performing sorting logic by using temporary variable
temp = arr[i];
arr[i]= arr[max];
arr[max] = temp;
heapify(arr, size, max);
} #include <iostream>
}
using namespace std;
void heapSort(int arr[], int size)// providing definition to
heap sort void heapify(int arr[], int n, int i)
35
{ int n = sizeof(arr)/sizeof(arr[0]);
int largest = i; cout << "Unsorted array \n";
int l = 2*i + 1; display(arr, n);
int r = 2*i + 2;
heapSort(arr, n);
//If left child is larger than root
if (l < n && arr[l] > arr[largest]) cout << "Sorted array \n";
largest = l; display(arr, n);
}
//If right child largest
if (r < n && arr[r] > arr[largest])
largest = r; Java code:
// Java program for implementation of Heap Sort
//If root is nor largest public class PrepInsta
if (largest != i) {
{ //Main() for the execution of the program
swap(arr[i], arr[largest]); public static void main(String args[])
{
//Recursively heapifying the sub-tree int a[] = {12, 11, 13, 5, 6, 7};
heapify(arr, n, largest); int len = a.length;
}
} PrepInsta ob = new PrepInsta();
ob.sort(a);
void heapSort(int arr[], int n)
{ System.out.println("Sorted array is");
printArray(a);
for (int i = n / 2 - 1; i >= 0; i--) }
heapify(arr, n, i); public void sort(int a[])
{
//One by one extract an element from heap int len = a.length;
for (int i=n-1; i>=0; i--)
{ // Build heap (rearrange array)
//Moving current root to end for (int i = len / 2 - 1; i >= 0; i--)
swap(arr[0], arr[i]); heapify(a, len, i);
//Calling max heapify on the reduced heap // One by one extract an element from heap
heapify(arr, i, 0); for (int i=len-1; i>=0; i--)
} {
} // Move current root to end
int temp = a[0];
//Function to print array a[0] = a[i];
void display(int arr[], int n) a[i] = temp;
{
for (int i = 0; i < n; i++) // call max heapify on the reduced heap
{ heapify(a, i, 0);
cout << arr[i] << "\t"; }
} }
cout << "\n";
} // To heapify a subtree rooted with node i which is
// an index in arr[]. n is size of heap
void heapify(int a[], int len, int i)
int main() {
{ int largest = i; // Initialize largest as root
int arr[] = {1, 14, 3, 7, 0}; int l = 2*i + 1; // left = 2*i + 1
36
int r = 2*i + 2; // right = 2*i + 2
Chapter 12. Stacks
// If left child is larger than root
if (l < len && a[l] > a[largest])
largest = l; Introduction to Stacks in Data Structures
Output: the stack. It deletes the top-most data from the stack.
Unsorted array
4. Peek () – This operation helps us in looking at the
1 14 3 7 0
Sorted array topmost element of the data without removing it from the
0 1 3 7 14
stack.
pop operations –
37
Applications of Stacks in Data Structures 3. Random access is not possible.
There are a lot of places where we use stack without even
4. Variable storage will be overwritten, which sometimes
realizing it. Let’s see some of the most common uses of
stack data structure. leads to undefined behavior of the function or program.
Stack
1. Recursion
2. Backtrackking
3. Memory managament
4. Process Managament There are many operations that can be used to manipulate a
deallocated.
38
{
while(1) printf("\nPopped element is:
{ %d",s[top_of_stack]);
printf("\nSelect from the following top_of_stack=top_of_stack-1;
options- "); }
}
printf("\n\n1.Push\n2.Pop\n3.Show\n4.Exit");
printf("\n\nEnter the operation you void show()
want to execute: "); {
scanf("%d",&option); int i;
switch(option) if(top_of_stack==-1)
{ {
case 1: push(); printf("\nStack is empty");
break; }
case 2: pop(); else
break; {
case 3: show(); printf("\nElements of the stack are:\n");
break; for(i = top_of_stack; i>=0; --i)
case 4: exit(0); printf("%d\n",s[i]);
}
default: printf("\nInvalid }
option. Please select a Valid operation");
} Infix Prefix Postfix Conversion (Stack)
}
}
void push()
{
int value;
if(top_of_stack == size-1)
{
printf("\nOperation failed. Stack is
full.");
}
else
{
printf("\nEnter the value you want to
push in the stack:");
scanf("%d",&value);
top_of_stack = top_of_stack + 1;
s[top_of_stack] = value;
} Introduction
}
● Operation : Any Expression of algebraic format
void pop() (Example : A + B)
{
if(top_of_stack == -1) ● Operands : A and B or 5 & 6 are operands
{
● Operators : +. -, %,*,/ etc are operators
printf("\nOperation failed. Stack is
empty");
}
else Infix Notation
39
Infix is the day to day notation that we use of format A + B
● Example 1 : A + B
● Example 2 : A * B + C / D
Postfix Notation
● Example 1 : AB+
● Example 2 : AB*CD/+
Why are Postfix/Prefix Expressions faster than Infix?
For Infix Expression which is format A+B*C, if the
Prefix Notation
compiler is reading left to right then it can’t evaluate A+B
Prefix is notation that compiler uses/converts to while first until it has read whole expression and knows
reading right to left (some compilers can also read prefix expression is actually A + (B*C) i.e. B * C needs to be
left to right) and is of format +AB type. The general form implemented first
can be classified as (op ab) where a and b are
Postfix for above infix is ABC*+. Now, as soon as the
operands(variables) and op is Operator.
compiler sees two operands followed by an operator it can
● Example 1 : +AB implement it without caring for precedence.
● Example 2 : +*AB/CD
● Assume ABC*+
is put back)
Note
Compiler converts our Infix Expression into postfix or
Prefix as expressions are operated as stacks and postfix and
prefix are faster to implement as the compiler doesn't need
to care about precedence at all.
40
Compiler converts the infix expression to postfix/prefix at Else, Pop all the operators that have greater or equal
compile time, so at runtime your calculations are always
happening in post-prefix. A website's code may be precedence than the scanned operator. Once you pop them
compiled once a week but it may need to run 1 million
times a week. push this scanned operator. (If we see a parenthesis while
Which is why we prefer that runtime execution should be
as fast as possible. If calculations happen faster than we popping then stop and push scanned operator in the stack)
have optimized our page load time hugely right?
If the scanned character is an ‘(‘, push it to the stack.
Problem If the scanned character is an ‘)’, pop the stack and output it
● (a + (b * c)) + d and thus further ((a + (b * c)) + Do the pop and output (print) until stack is not empty
d)
Infix to Prefix
● Solving and converting innermost bracket to
Else +d*ef)
41
○ replacing z and w value = -+/abc+d*ef
char pop()
Algorithm (For Code/Manual Calculation)
{
return -1;
Step 1: Reverse the infix string. Note that while reversing
the string you must interchange left and right parentheses. else
return s[top_of_stack--];
Step 2: Obtain the postfix expression of the expression
}
obtained from Step 1.
if(a == '(')
This is how you convert manually for theory question in the
exam return 0;
char expression[20];
#include<stdio.h>
char *exp, a;
char s[100];
printf("Enter the expression you want to convert: ");
int top_of_stack = -1;
scanf("%s",expression);
void push(char a)
exp = expression;
{
while(*exp != '\0')
s[++top_of_stack] = a;
{
}
if(isalnum(*exp))
42
printf("%c",*exp); #include <stdlib.h>
#include <string.h>
else if(*exp == '(')
// A structure to represent a stack
push(*exp); struct Stack {
int top;
else if(*exp == ')') int maxSize;
// we are storing string in integer array, this will not give
{
error
// as values will be stored in ASCII and returned in
while((a = pop()) != '(')
ASCII thus, returned as string again
printf("%c", a); int* array;
};
}
struct Stack* create(int max)
else {
struct Stack* stack = (struct Stack*)malloc(sizeof(struct
{ Stack));
stack->maxSize = max;
while(precedence(s[top_of_stack]) >= stack->top = -1;
precedence(*exp)) stack->array = (int*)malloc(stack->maxSize *
sizeof(int));
printf("%c",pop());
return stack;
}
push(*exp);
}
// By definition the Stack is empty when top is equal to -1
// Will return true if top is -1
}
int isEmpty(struct Stack* stack)
{
return stack->top == -1;
}
43
// Function to remove an item from stack. It decreases top
by 1 for (i = 0, j = -1; expression[i]; ++i)
int pop(struct Stack* stack) {
{ // Here we are checking is the character we scanned is
if (isEmpty(stack)) operand or not
return INT_MIN; // and this adding to to output.
return stack->array[stack->top--]; if (checkIfOperand(expression[i]))
} expression[++j] = expression[i];
// Function to return the top from stack without removing it // Here, if we scan character ‘(‘, we need push it to the
int peek(struct Stack* stack) stack.
{ else if (expression[i] == '(')
if (isEmpty(stack)) push(stack, expression[i]);
return INT_MIN;
return stack->array[stack->top]; // Here, if we scan character is an ‘)’, we need to pop
} and print from the stack
// do this until an ‘(‘ is encountered in the stack.
// A utility function to check if the given character is else if (expression[i] == ')')
operand {
int checkIfOperand(char ch) while (!isEmpty(stack) && peek(stack) != '(')
{ expression[++j] = pop(stack);
return (ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= if (!isEmpty(stack) && peek(stack) != '(')
'Z'); return -1; // invalid expression
} else
pop(stack);
// Fucntion to compare precedence }
// If we return larger value means higher precedence else // if an operator
int precedence(char ch) {
{ while (!isEmpty(stack) &&
switch (ch) precedence(expression[i]) <= precedence(peek(stack)))
{ expression[++j] = pop(stack);
case '+': push(stack, expression[i]);
case '-': }
return 1;
}
case '*':
case '/': // Once all initial expression characters are traversed
return 2; // adding all left elements from stack to exp
while (!isEmpty(stack))
case '^': expression[++j] = pop(stack);
return 3;
} expression[++j] = '\0';
return -1; printf( "%s", expression);
} }
44
Infix to prefix conversion code in C: // Will return true is stack is full else false
#include <limits.h> //Stack is full when top is equal to the last index
#include <stdlib.h> {
struct Stack { // Since array starts from 0, and maxSize starts from 1
int maxSize; }
// we are storing string in integer array, this will not give // By definition the Stack is empty when top is equal to -1
error
// Will return true if top is -1
// as values will be stored in ASCII and returned in ASCII
thus, returned as string again int isEmpty(struct Stack* stack)
int* array; {
stack->maxSize = max; {
45
int pop(struct Stack* stack)
{ case '*':
return stack->array[stack->top--];
} case '^':
{ return -1;
if (isEmpty(stack)) }
return INT_MIN;
return 1;
46
// Here, if we scan character ‘(‘, we need push it to the expression[++j] = pop(stack);
stack.
{ char temp[size];
else j--;
pop(stack); i++;
} }
{ }
exp[i]=')';
}
else if(exp[i]==')')
// Once all inital expression characters are traversed
exp[i]='(';
// adding all left elements from stack to exp
i++;
while (!isEmpty(stack))
47
} Introduction to stack
reverse(exp);
Stack Operations
}
Push: Adding a new item to the Stack Data Structure,
int main()
in other words pushing new item to Stack DS.
{
If Stack is full, then it is said to be in an overflow condition
printf("The infix is: ");
char expression[] = "((a/b)+c)-(d+(e*f))"; Pop: Removing an item from the stack, i.e. popping an
item out.
printf("%s\n",expression);
condition
printf("The prefix is: ");
48
2. Pop()
Representation of stack.
Stack as a data structure can be represented in two ways.
● When we require to remove an element to the
Operations on a Stack
There are a number of operations we can perform on a
● Push().
● Pop().
● Top/Peak().
● isEmpty().
● When we require to add an element to the stack ● The value of top changes with each push() or
data structure.
49
1. When we initialise the stack, there is no element in a
element we use – 1.
by 1, top++
by 1, top–
How does the stack work? // Checking with this function is stack is full or not
// Will return true is stack is full else false
● Top: An integer variable Top is used, to keep //Stack is full when top is equal to the last index
int isFull(struct Stack* stack)
track of topmost element in the stack {
if(stack->top == stack->maxSize - 1){
50
printf("Will not be able to push maxSize reached\n"); else
} printf("Can't Pop stack must be empty\n");
// Since array starts from 0, and maxSize starts from 1
return stack->top == stack->maxSize - 1; printf("Do you want to Pop again? Yes: 1 No: 0\n");
} scanf("%d",&flag);
}
// By definition the Stack is empty when top is equal to -1 return 0;
// Will return true if top is -1 }
int isEmpty(struct Stack* stack)
{ O/P
return stack->top == -1;
} We have pushed 5 to stack
We have pushed 10 to stack
// Push function here, inserts value in stack and increments We have pushed 15 to stack
stack top by 1 We have popped 15 from the stack
void push(struct Stack* stack, int item) Do you want to Pop again? Yes: 1 No: 0
{ 0
if (isFull(stack))
return; Code in C++:
stack->array[++stack->top] = item;
printf("We have pushed %d to stack\n", item); #include <bits/stdc++.h>
} using namespace std;
51
} 1. P for push operation
} 2. R for pop operation
void Stack::diplay() { 3. D for display operation
Node *temp = top; 4. Q to quit
while (temp != NULL) { // Printing until encounter R
NULL position 21 deleted
cout << temp -> data << ” “; Enter
temp = temp -> next; 1. P for push operation
} 2. R for pop operation
cout << endl; 3. D for display operation
} 4. Q to quit
Stack::~Stack() { // Destructor Called to delete data P
Enter Data: 11
while (top != NULL) { Enter
Node *temp = top; 1. P for push operation
cout << temp -> data << ” deleted\n”; 2. R for pop operation
top = top -> next; 3. D for display operation
delete temp; 4. Q to quit
} D
} 11 20
int main() { Enter
Stack st; 1. P for push operation
char ch; 2. R for pop operation
do { 3. D for display operation
cout <<“Enter \n“; 4. Q to quit
cout << “1. P for push operation\n“; Q
cout << “2. R for pop operation\n“; 11 deleted
cout << “3. D for display operation\n“; 20 deleted
cout << “4. Q to quit\n“;
cin >> ch;
switch(ch) {
Code in java:
case ‘P’ : st.push(); break;
case ‘R’ : st.pop(); break;
/* Java program to implement stack
case ‘D’ : st.diplay(); break;
operations using array*/
}
class Stack {
}while (ch != ‘Q’);
static int MAX = 100;
return 0;
int top;
}
int a[] = new int[MAX]; // Maximum size of Stack
Output:
Enter
1. P for push operation
boolean isEmpty()
2. R for pop operation
{
3. D for display operation
return (top < 0);
4. Q to quit
}
P
Stack()
Enter Data: 20
{
Enter
top = –1;
1. P for push operation
}
2. R for pop operation
3. D for display operation
4. Q to quit
boolean push(int x)
P
{
Enter Data: 21
if (top >= (MAX – 1)) {
Enter
System.out.println(“Overflow condition reached”);
52
return false; stacknode node;
}
else { static class stacknode {
a[++top] = x; int data;
System.out.println(x + ” pushed into stack”); stacknode next;
return true;
} stacknode(int data) { this.data = data; }
} }
if (node == null) {
int peek() node = newNode;
{ }
if (top < 0) { else {
System.out.println(“Underflow condition”); stacknode temp = node;
return 0; node = newNode;
} newNode.next = temp;
else { }
int x = a[top]; System.out.println(data);
return x; }
}
} public int pop()
} {
class Prepinsta { int popped = Integer.MIN_VALUE;
public static void main(String args[]) if (node == null) {
{ System.out.println(“Stack is Empty”);
Stack stk = new Stack(); }
stk.push(20); else {
stk.push(40); popped = node.data;
stk.push(60); node = node.next;
System.out.println(stk.pop()); }
} return popped;
} }
53
} Despite the difference, an array can be used to represent a
}
stack by taking an array of maximum size; big enough to
manage a stack.
public static void main(String[] args)
{
slk.push(20);
slk.push(40);
slk.push(60);
System.out.println(slk.pop());
60
● Push (40).
Time complexity ● Top = 40
stack –
Step 2:
An array is used to store an ordered list of elements. Using
54
Step 5:
● Push (08).
● Top = 08
Step 3:
Step 6:
● Push (33).
Step 4:
● Push (21).
● Top = 21
Step 7:
● Top = -1.
● End of array.
55
default:
printf("\nPlease enter a correct option\n");
break;
}
}
void Pop (int []);//to delete elements from the stack void Pop(int stack[])
{
void display(int []); //to display the elements int del_num;
if(top_of_stack==-1)
void main() {
{ printf("Empty Stack.\n");
int num=0; return;
int option=0; }
top_of_stack=-1;
del_num=stack[top_of_stack];
while(1) top_of_stack--;
{ printf("Element deleted: %d \n",del_num);
printf("\n 1: Push \n 2: Pop \n 3: Display \n 4: Exit \n return;
Enter one of your choices: "); }
scanf("%d",&option);
void display(int stack[])
switch(option) {
{ int i=0;
case 1: if(top_of_stack==-1)
printf("Enter the item you want to insert :"); {
scanf("%d",&num); printf("Empty Stack .\n");
Push(stack,num); return;
break; }
56
3: Display {
4: Exit return (top < 0);
}
Enter one of your choices: 1 Stack()
Enter the item you want to insert :1 {
1: Push top = –1;
2: Pop }
3: Display
4: Exit
boolean push(int x)
Enter one of your choices: 1 {
Enter the item you want to insert :2 if (top >= (MAX – 1)) {
1: Push System.out.println(“Overflow condition reached”);
2: Pop return false;
3: Display }
4: Exit else {
Enter one of your choices: 1 a[++top] = x;
System.out.println(x + ” pushed into stack”);
Enter the item you want to insert :3 return true;
}
1: Push }
2: Pop
3: Display
4: Exit int pop()
Enter one of your choices: 2 {
if (top < 0) {
Element deleted: 3 System.out.println(“Underflow condition reached”);
1: Push return 0;
2: Pop }
3: Display else {
4: Exit int x = a[top–];
Enter one of your choices: 3 return x;
}
Top of stack is: }
2 1
57
stk.push(60); But performing the operations at the beginning occurs in
System.out.println(stk.pop());
} constant time. Let us understand this with the help of an
} example.
Output :
Let us consider a linked list as shown here.
60
push and pop operations at the end of the linked list it takes
time O(n).
58
● Now if we want to insert a node at the end of the The time complexity of inserting a new node at the
linked list, we traverse from the first node to the beginning of the linked list is O(1).
second node to the last node. Let us consider the previous example only. We are given a
● We find the end of the list where the node points Linked List as follows:
here.
here.
● The new node is pushed at the end of the list.
The new node 40 is to be inserted at the beginning of the
● The second last node , i.e, 08 now points to the
list.
location of the last node.
null.
59
case 3:
{
display();
break;
}
case 4:
{
printf("Exit");
break;
}
default:
{
printf("\nKindly enter a valid option\n");
}
Code in C(using linked list) };
}
}
#include <stdio.h> void Push ()
#include <stdlib.h> {
int element;
void Push(); /*to insert the element*/ struct n *ptr = (struct n*)malloc(sizeof(struct n));
if(ptr == NULL)
void pop(); /*to delete the element*/ {
printf("Stack full. Operation failed");
void display(); /*to display the elements in a stack*/ }
else
struct n {
{ printf("Enter the element you want to insert: ");
int element; scanf("%d",&element);
struct n *nxt; if(hd==NULL)
}; {
struct n *hd; ptr->element = element;
ptr -> nxt = NULL;
void main () hd=ptr;
{ }
int option=0; else
while(option != 4) {
{ ptr->element = element;
printf("\nSelect from the following ptr->nxt = hd;
options\n1.Push\n2.Pop\n3.Show\n4.Exit \nEnter one of hd=ptr;
your choices:");
scanf("%d",&option); }
switch(option) printf("Element is inserted");
{
case 1: }
{ }
Push();
break; void pop()
} {
case 2: int num;
{ struct n *ptr;
pop(); if (hd == NULL)
break; {
} printf("Not enough elements. Underflow!");
60
} }
else
{ public void push(int data)
num = hd->element; {
ptr = hd; stacknode newNode = new stacknode(data);
hd = hd->nxt;
free(ptr); if (node == null) {
printf("Element deleted: %d",num); node = newNode;
}
} else {
} stacknode temp = node;
void display() node = newNode;
{ newNode.next = temp;
int i; }
struct n *ptr; System.out.println(data);
ptr=hd; }
if(ptr == NULL)
{ public int pop()
printf("The stack is empty\n"); {
} int popped = Integer.MIN_VALUE;
else if (node == null) {
{ System.out.println(“Stack is Empty”);
printf("The stack elements are as follows: \n"); }
while(ptr!=NULL) else {
{ popped = node.data;
printf("%d\n",ptr->element); node = node.next;
ptr = ptr->nxt; }
} return popped;
} }
}
public int peek()
{
Code in java(using linked list) if (node == null) {
System.out.println(“Stack is empty”);
return Integer.MIN_VALUE;
// Java Code for Linked List Implementation
}
else {
public class LinkedList {
return node.data;
}
stacknode node;
}
61
} Steps to convert
}
Output :
Any infix op1 oper op2 can be written as op1 op2 oper
Top element is 60 Where op1 = Operand 1
op2 = Operand2
Infix To Postfix Conversion using Stack oper = Operation
Any operation can be expressed in Infix, postfix and prefix, Example a + b can be written as ab+ in postfix
we shall see how to convert infix to prefix operation via
manual calculation and via code.
Problem
Overview
1. Infix: a + b * c + d can be written as a + (b * c) + d
2. Now, for all + – / * associativity is left to right we will
● Infix – Any operation of format a op b format
write it as
example a + b is called an infix operation
3. (a + (b * c)) + d and thus further ((a + (b * c)) + d)
● Postfix – An operation or expression can also be
4. Solving and converting innermost bracket to postfix
written in the format of a b op i.e. a b + which is
Step 1 –((a + bc*)+ d)
similar to writing a + b in infix. All we are doing
Step 2 – Consider bc* as separate operand x the innermost
is shifting operator to the right of operands
bracket now looks like ((a + x)+ d)
(abc*+ + d)
Why do we need a postfix operator?
Step 3 – Consideringabc*+as separate operand z, the final
For a compiler, it is easier to read postfix or prefix bracket looks like – (z + d)the result would be zd+
operations. As a compiler either reads from right to left or replacing z value = abc*+d+
62
1. If the scanned character is an ‘(‘, push it to the stack.
parenthesis.
4. Print output
5.Do the pop and output (print) until stack is not empty
#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
63
// as values will be stored in ASCII and returned in ASCII int peek(struct Stack* stack)
thus, returned as string again {
int* array; if (isEmpty(stack))
}; return INT_MIN;
return stack->array[stack->top];
struct Stack* create(int max) }
{
struct Stack* stack = (struct Stack*)malloc(sizeof(struct // A utility function to check if the given character is
Stack)); operand
stack->maxSize = max; int checkIfOperand(char ch)
stack->top = -1; {
stack->array = (int*)malloc(stack->maxSize * return (ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z');
sizeof(int)); }
return stack;
} // Function to compare precedence
// If we return larger value means higher precedence
// Checking with this function is stack is full or not int precedence(char ch)
// Will return true is stack is full else false {
//Stack is full when top is equal to the last index switch (ch)
int isFull(struct Stack* stack) {
{ case '+':
if(stack->top == stack->maxSize - 1){ case '-':
printf("Will not be able to push maxSize reached\n"); return 1;
}
// Since array starts from 0, and maxSize starts from 1 case '*':
return stack->top == stack->maxSize - 1; case '/':
} return 2;
// Function to remove an item from stack. It decreases top for (i = 0, j = -1; expression[i]; ++i)
by 1 {
int pop(struct Stack* stack) // Here we are checking is the character we scanned is
{ operand or not
if (isEmpty(stack)) // and this adding to to output.
return INT_MIN; if (checkIfOperand(expression[i]))
return stack->array[stack->top--]; expression[++j] = expression[i];
}
// Here, if we scan character ‘(‘, we need push it to the
// Function to return the top from stack without removing it stack.
64
else if (expression[i] == '(') #include<string>
push(stack, expression[i]); #define MAX 20
using namespace std;
// Here, if we scan character is an ‘)’, we need to pop
and print from the stack char stk[20];
// do this until an ‘(‘ is encountered in the stack. int top=-1;
else if (expression[i] == ')') // Push function here, inserts value in stack and increments
{ stack top by 1
while (!isEmpty(stack) && peek(stack) != '(') void push(char oper)
expression[++j] = pop(stack); {
if (!isEmpty(stack) && peek(stack) != '(') if(top==MAX-1)
return -1; // invalid expression {
else cout<<"stackfull!!!!";
pop(stack); }
}
else // if an operator else
{ {
while (!isEmpty(stack) && top++;
precedence(expression[i]) <= precedence(peek(stack))) stk[top]=oper;
expression[++j] = pop(stack); }
push(stack, expression[i]); }
} // Function to remove an item from stack. It decreases top
by 1
} char pop()
{
// Once all initial expression characters are traversed char ch;
// adding all left elements from stack to exp if(top==-1)
while (!isEmpty(stack)) {
expression[++j] = pop(stack); cout<<"stackempty!!!!";
}
expression[++j] = '\0'; else
printf( "%s", expression); {
} ch=stk[top];
stk[top]='\0';
int main() top--;
{ return(ch);
char expression[] = "((a+(b*c))-d)"; }
covertInfixToPostfix(expression); return 0;
return 0; }
} int priority ( char alpha )
{
if(alpha == '+' || alpha =='-')
Output
{
return(1);
abc*+d- }
65
} {
push(infix[i]);
return 0; i++;
} }
string convert(string infix)
{ else if( priority(infix[i]) <= priority(stk[top])) {
int i=0; postfix.insert(postfix.end(),pop());
string postfix = "";
while(infix[i]!='\0') while(priority(stk[top]) == priority(infix[i])){
{ postfix.insert(postfix.end(),pop());
if(infix[i]>='a' && infix[i]<='z'|| infix[i]>='A'&& if(top < 0) {
infix[i]<='Z') break;
{ }
postfix.insert(postfix.end(),infix[i]); }
i++; push(infix[i]);
} i++;
else if(infix[i]=='(' || infix[i]=='{' || infix[i]=='[') }
{ else if(priority(infix[i]) > priority(stk[top])) {
push(infix[i]); push(infix[i]);
i++; i++;
} }
else if(infix[i]==')' || infix[i]=='}' || infix[i]==']') }
{ }
if(infix[i]==')') while(top!=-1)
{ {
while(stk[top]!='(') postfix.insert(postfix.end(),pop());
{ postfix.insert(postfix.end(),pop()); }
} cout<<"The converted postfix string is : "<<postfix; //it
pop(); will print postfix conversion
i++; return postfix;
} }
if(infix[i]==']')
{ int main()
while(stk[top]!='[') {
{ int cont;
postfix.insert(postfix.end(),pop()); string infix, postfix;
} cout<<"\nEnter the infix expression : "; //enter the
pop(); expression
i++; cin>>infix;
} postfix = convert(infix);
return 0;
if(infix[i]=='}') }
{
while(stk[top]!='{') Output:-
{ Enter the infix expression : a=b*2+5
postfix.insert(postfix.end(),pop()); The converted postfix string is : ab*=+25
}
pop();
i++;
}
Infix to postfix in java
}
else import java.util.Stack;
{
if(top==-1)
66
public class InfixToPostfix { return false;
public static boolean isOperator(char op){ public static String convertInixToPostfix(String infix){
return false;
for(int i=0; i<infix.length(); i++){
}
char currentCharacter = infix.charAt(i);
return 3; }
default : stack.push(currentCharacter);
return 4; }
} }
} }
while(!stack.empty()) sb.append(stack.pop());
67
System.out.println(convertInixToPostfix(“4*5+6/7”)); Example – ((a / b) + c) - (d + (e * f ))
}
2. Prefix: Expressions wherein the operator comes before
}
the operands are prefix expression like – Infix: (A + B) can
OUTPUT: be expressed as +AB
as AB+
Steps to convert
36*48/+
○ oper = Operation
Postfix expression doesn’t have the operator precedence.
● Example a + b can be written as ab+ in prefix
Postfix is slightly easier to evaluate.
You need to worry about the left and right associativity. Problem (This is how to convert manually for MCQ
Question in the exam)
While prefix expression is easier for the compiler, as it is ● Solving and converting innermost bracket to
already sorted in accordance with precedence and compiler,
can start assignments and operations, without caring about prefix
precedence. ● Step 1 –(/ab + c) - ( d + *ef)
What are infix and prefix expressions?
● Step 2 – Consider /ab and *ef as separate operand
1. Infix: Expressions of format (A + B) are called as infix
x and y
expressions, these are just like mathematical expressions
68
● the innermost bracket now looks like (x + c) - (d // we are storing string in integer array, this will not give
error
+ y)
○ Applying prefix it looks like – (+xc - // as values will be stored in ASCII and returned in ASCII
thus, returned as string again
+dy)replacing x and y here (+/abc -
int* array;
+d*ef)
stack->maxSize = max;
stack->top = -1;
stack->array = (int*)malloc(stack->maxSize *
sizeof(int));
return stack;
C Code for Infix to Prefix Conversion //Stack is full when top is equal to the last index
#include <stdio.h> {
// A structure to represent a stack // Since array starts from 0, and maxSize starts from 1
int top; }
69
// Will return true if top is -1 return stack->array[stack->top];
{
// Push function here, inserts value in stack and increments
stack top by 1 return (ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z');
stack->array[++stack->top] = item; {
} switch (ch)
return INT_MIN;
case '*':
return stack->array[stack->top--];
case '/':
}
return 2;
// Function to return the top from stack without removing it
70
return -1; {
expression[++j] = pop(stack);
// The driver function for infix to postfix conversion if (!isEmpty(stack) && peek(stack) != '(')
{ else
int i, j; pop(stack);
push(stack, expression[i]);
expression[++j] = '\0';
71
int size = strlen(exp); int size = strlen(exp);
reverse(exp);
while(exp[i]!='\0') brackets(exp);
{ //get postfix
i++; reverse(exp);
} }
strcpy(exp,temp);
} int main()
while(exp[i]!='\0')
if(exp[i]=='(') printf("%s\n",expression);
exp[i]=')'; InfixtoPrefix(expression);
else if(exp[i]==')')
i++; printf("%s\n",expression);
} return 0;
72
Output – stack->top = -1;
stack->array = (int *) malloc (stack->maxSize * sizeof
(int));
The Infix is: ((a/b)+c)-(d+(e*f)) return stack;
}
The prefix is: -+/abc+d*ef
// Checking with this function is stack is full or not
int stackFull (struct Stack *stack)
C++ Program for Infix To Prefix Conversion {
using stack data structures:- if (stack->top == stack->maxSize - 1)
{
#include <iostream> cout << "Will not be able to push maxSize reached\n";
#include <limits.h> }
#include <stdio.h> // We know array index from 0 and maxSize starts from 1
#include <stdlib.h> return stack->top == stack->maxSize - 1;
#include <string.h> }
using namespace std;
//definition of functions // if Stack is empty when top is equal to -1 and return true
struct Stack *create (int max); int stackEmpty (struct Stack *stack)
int stackFull (struct Stack *stack); {
int stackEmpty (struct Stack *stack); return stack->top == -1;
void pushElement (struct Stack *stack, int item); }
int popElement (struct Stack *stack);
int peekElement (struct Stack *stack); // Push function it inserts value in stack and increments
int checkOperand (char ch); stack top by 1
int precedence (char ch); void pushElement (struct Stack *stack, int item)
int postfix (char *expression); {
void reverse (char *exp); if (stackFull (stack))
void brackets (char *exp); return;
void conversionInfixToPrefix (char *exp); stack->array[++stack->top] = item;
// A structure to represent a stack }
struct Stack
{ // pop Function it remove an item from stack and decreases
int top; top by 1
int maxSize; int popElement (struct Stack *stack)
int *array; {
}; if (stackEmpty (stack))
int main () return INT_MIN;
{ return stack->array[stack->top--];
int n = 10; }
cout << "The infix expression is: \n";
char expression[] = "(P+(Q*R)/(S-T))"; // Function to return the top from stack without removing it
cout << expression << "\n"; int peekElement (struct Stack *stack)
conversionInfixToPrefix (expression); {
cout << "The prefix expression is: \n"; if (stackEmpty (stack))
cout << expression; return INT_MIN;
return 0; return stack->array[stack->top];
} }
//stack implementation
struct Stack * create (int max) // A function check the given character is operand
{ int checkOperand (char ch)
struct Stack *stack = (struct Stack *) malloc (sizeof (struct {
Stack)); return (ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z');
stack->maxSize = max; }
73
{
// Fucntion to compare precedence if return larger value while (!stackEmpty (stack)
means higher precedence && precedence (expression[i]) <=
int precedence (char ch) precedence (peekElement (stack)))
{ expression[++j] = popElement (stack);
switch (ch) pushElement (stack, expression[i]);
{ }
case '+':
case '-': }
return 1;
// if all first expression characters are scanned
case '*': // adding all left elements from stack to expression
case '/': while (!stackEmpty (stack))
return 2; expression[++j] = popElement (stack);
expression[++j] = '\0';
case '^': }
return 3;
} void reverse (char *exp)
return -1; { //reverse function
} for expression
// The function for infix to postfix conversion int size = strlen (exp);
int postfix (char *expression) int j = size, i = 0;
{ char temp[size];
int i, j;
struct Stack *stack = create (strlen (expression)); temp[j--] = '\0';
if (!stack) while (exp[i] != '\0')
return -1; {
temp[j] = exp[i];
for (i = 0, j = -1; expression[i]; ++i) j--;
{ i++;
// checking the character we scanned is operand or not }
if (checkOperand (expression[i])) strcpy (exp, temp);
expression[++j] = expression[i]; }
74
reverse (exp); stack.push(c);
} }else if(c==‘)’){
Output:- char x = stack.pop();
The infix expression is: while(x!=‘(‘){
(P+(Q*R)/(S-T)) result.append(x);
The prefix expression is: x = stack.pop();
+P/*QR-ST }
}else if(c==‘(‘){
stack.push(c);
}else{
Java code : //character is neither operator nor “(“
import java.util.Stack; result.append(c);
public class InfixToPreFix { }
static int precedence(char c){ }
switch (c){
case ‘+’: for (int i = 0; i <=stack.size() ; i++) {
case ‘-‘: result.append(stack.pop());
return 1; }
case ‘*’: return result.reverse();
case ‘/’: }
return 2;
case ‘^’: public static void main(String[] args) {
return 3; String exp = “A+B*(C^D-E)”;
} System.out.println(“Infix Expression: “ + exp);
return –1; System.out.println(“Prefix Expression: “ +
} infixToPreFix(exp));
}
static StringBuilder infixToPreFix(String expression){ }
Output:
StringBuilder result = new StringBuilder();
StringBuilder input = new StringBuilder(expression); Infix Expression: A+B*(C^D-E)
input.reverse(); Prefix Expression: +A*B-^CDE
Stack<Character> stack = new Stack<Character>();
75
● Postfix – The postfix will look like, XY+UV-/
Prefix directly?
will be there.
whole A + B is expression.
76
Note – It has a different logic than the above rule {
explained.
return (ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z');
}
C code to conversion of postfix to prefix
case '-':
#define MAX 20
case '/':
case '*':
char str[MAX], stack[MAX];
return 1;
int top = -1;
}
return 0;
void push(char c)
}
{
stack[++top] = c;
void postfixToprfix()
}
{
int n, i, j = 0;
char pop()
char c[20];
{
char a, b, op;
return stack[top--];
}
printf("Enter the postfix expression\n");
// A utility function to check if the given character is
operand scanf("%s", str);
77
n = strlen(str); char d[20];
if (isOperator(str[i])) }
{ int main()
push(str[i]); {
} else postfixToprfix();
} switch (x){
} case ‘-‘:
case ‘/’:
i = 0; case ‘*’:
78
return true; String postfix = “AB+CD-*”;
} }
AB+CD-*
char c = exp.charAt(i);
prefix exp:
if(isOperator(c)){
String s2 = st.pop();
st.push(temp);
}else{
st.push(c+“”);
return result;
79
Why do we use Linked List in Data
Structure?
Generally, storage arrays are used. But, there are many
many disadvantaged with arrays –
Fixed Size
The size of the array is fixed and needs to be pre-defined
Example – int a[10]; or int a[ ] = {1, 2, 3, 4, 5}
We can’t declare an array without declaring the size.
Memory wastage (Not Optimised)
If you declare an array of size 10 and just assign values to
first two elements
The memory is allocated to all of them even though we
may not end up using them.
Need for Contiguous Memory
Arrays need Contiguous memory, which sometimes is bad.
Chapter 13. Linked List Example – Consider there are only three memories of size
10, 10 and 400
We need to store an array of size 15
What is a Linked List in Data Structure?
In this case, the array will use memory location size 400
A linked list is a linear data structure. In which we can
and not combine memory A and B of size 10 and 10
store the data in a sequence manner. Unlike an array linked
respectively.
list is dynamic data structure the size of a linked list can
Thus wasting a lot of memory
grow or shrink depending on the situation.
The element of a linked list is called a node. Every element Inserting in Array is expensive
or node contains two main entities. The first entity is the Let us say you have an array a[] = {10, 20, 40, 60, 80} and
information or the data whereas the second entity is the we need to add 50 in the same sorted format.
pointer to the next node. Then, we have to move all elements after 40 to one
additional position
More Information Also, same goes for deletion if we want to delete 20. Then
The structure of the linked list is like a train. A linked list all elements after it have to be moved to one position in the
has the following components – opposite direction.
Data: Data is the value stored in it, it could be anything, an Linked Lists Advantages
integer or a string or anything else really. Ease of insertion and deletion. (How? we will learn this in
Pointer (Link) – Each linked list contains a pointer which Linked List insertion Post)
points to the address of the next node in the linked list train. Dynamic Size
Apart from this the following are also keywords used in
linked lists – Disadvantages
We have to search elements linearly, and can’t do random
Node – Any single unit of a linked list, its data and access
pointer(s), is called a node. We can’t do efficient searches like binary search
Head: First is the head who is defined at the beginning of Extra space for pointers is needed
the list. Linked lists are not cache friendly as arrays are stored in
Tail: second is tail which defines the end of the list. contiguous format they can be cached easily
Loss of data threat is there, if we lose one pointer location
What is a linked list the rest of the linked list can’t be accessed.
Linked List like an array is a linear data structure.
However, the elements or data storage of linked list
elements are not in a contiguous manner and we use
Types of Linked link
pointers to create linearity in linked lists. There are three types of linked list, that are mentioned in
following ways-
80
Singly linked list }
Doubly linked list }
Circular linked list
Python Code:
# Node class
class Node:
C Code:
struct Node {
int data; C Code:
struct Node* next; //We are creating program for linked list creation
}; #include <stdio.h>
#include <stdlib.h>
C++ Code: //stdlib used to provide a declaration of ‘malloc’
class Node {
public: // structure of linked list
int data; struct Node {
Node* next; int data;
}; struct Node* next;
// Pointer pointing towards next node
Java COde: };
class LinkedList {
Node head; // head //function to print the linked list
void display(struct Node* node)
/* Linked list Node*/ {
class Node { while (node != NULL) {
int data; printf(" %d ", node->data);
Node next; node = node->next;
}
// For creating new node a Constructor }
// Next is by default initialized
// as null // main function
Node(int d) { data = d; } int main()
81
{ */
//creating 4 pointers of type struct Node
//So these can point to address of struct type variable display(head);
struct Node* head = NULL;
struct Node* node2 = NULL; return 0;
struct Node* node3 = NULL; }
struct Node* node4 = NULL;
node2->data = 10;
node2->next = node3; Introduction to Doubly Linked
node3->data = 12;
List
node3->next = node4;
What are Doubly Linked Lists?
Doubly linked lists are an extension to singly linked lists
node4->data = 3;
and provide a little more additional features and security to
node4->next = NULL;
singly-linked lists. Let us see what these linked lists are –
//last node assigned to Null as linked list ends here
82
C Code:
struct Node {
int Data;
Struct Node* next;
Struct Node* prev;
};
83
// main function head node2 node3 node4
int main() | | | |
{ | | | |
//creating 4 pointers of type struct Node +---++---+-----+ +----+----+----+ +----+----+----+
//So these can point to address of struct type variable +----+----+----+
struct Node* head = NULL; |prev| 5 |next|--->|prev| 10 |next|--->|prev| 12
struct Node* node2 = NULL; |next|--->|prev| 3 |next|
struct Node* node3 = NULL; +---++---+-----+ +----+----+----+ +----+----+----+
struct Node* node4 = NULL; +----+----+----+
node2->data = 10;
node2->next = node3;
node2->prev = head;
node3->data = 12;
node3->next = node4;
node3->prev = node2;
node4->data = 3;
node4->next = NULL;
node4->prev = node3;
Circular linked list Advantages
//last node assigned to Null as linked list ends here
The circular linked list is also two types.
/*
84
1. Singly linked list struct node *prev;
2. Doubly linked list };
Advantages
1. Any node can be starting point and we can still traverse
the whole list Function to traverse in a Circular linked list
2. It can also deem to be useful for implementation as
queues as rather than maintaining the Front and Rear, we
can use a circular linked list and just maintain the pointer to void display(struct Node *head)
the first inserted node and it can simply be the next node to
the last node. {
3. Circular linked lists are commonly used in OS’es for the
task that requires repeatedly to be executed by OS.
struct Node *temp = head;
Disadvantages
if (head != NULL)
1. Doubly Linked List is faster in getting previous node
information due to previous pointer.
2. Doubly Linked List can traverse in both forward and {
backward direction.
3. Finding end of list and loop control is harder (no NULL do
to mark beginning and end).
4. The entire list can be traversed starting from any node {
(traverse means visit every node just once).
So, when we want to traverse the node in a circular linked
printf("%d ", temp->data);
list so we will traverse in a singly circular linked list so, it
is just like the singly linked list where tail nodes hold the
address of head node so traversal can be done circularly in temp = temp->next;
only one direction.
}
And the Traversal in a doubly linked list can be done
circularly in both directions.
while (temp != head);
85
// structure of Circular linked list head->data = 5; // data set for head node
struct Node { head->next = node2; // next pointer assigned to address of
int data; node2
struct Node* next;
// Pointer pointing towards next node node2->data = 10;
}; node2->next = node3;
86
Linked List does not need contiguous memory, i.e; if one
Chapter 14- Linked List in node has an address of 1000 then the next node may have
the address 2000.
C Insertion and Deletion Operation in Linked Lists are pretty
easy and less complicated.
Disadvantages of using Linked List in C
Linked Lists in C Programming Language Although insertion and deletion are not a difficult task in
Linked List in C is a linear type of data structures, which Linked List, searching in Linked List is very difficult.
has some major advantages over arrays and other linear We cannot use efficient searches like Binary Search.
data structures. Linked Lists in C are used for storing the It takes more spaces, as it stores the address also.
data in a contiguous manner. It is not necessary on the Linked lists are not cache friendly as arrays are stored in
concept of linked lists that the address to the next node is contigious format they can be cached easily
provided in continuous manner.Linked is constructed of Loss of data threat is there, if we lose one pointer location
two parts-: the rest of linked list can’t be accessed.
Linked List
Linked List is like an array is a linear data structure.
However, the elements or data storage of linked list Code for Implementing Linked List in C
elements are not in a contiguous manner and we use
pointers to create linearity in linked lists.×Dismiss alert //Linked List Implementation code
How to construct a Linked List in C ? #include <stdio.h>
For constructing a Linked List in C we use user defined #include <stdlib.h>
data type, i.e. we make a structure in C for using Linked //stdlib is included because we will be using ‘malloc’
List. We design a user defined struct data type, that
contains a datatype, for storing the desired data and a // creating a node in linked list
pointer variable for storing the address of the next node in struct Node {
the Linked List. int data;
struct Node* next;
Syntax for creating a node in Linked List in C // Pointer pointing towards next node
struct Node { };
int data;
struct Node* next; //function to print the linked list
}; void display(struct Node* node)
This code will create a new node in a Linked List which {
will be storing integer type of data while (node != NULL) {
printf(" %d ", node->data);
Advantages of using Linked List in C node = node->next;
It does not have a restriction of size, i.e; we do not have to }
declare the size of linked list before creating it. }
There is no memory wastage, as we connect new nodes
depending upon how much data do we have to store, and on // main function
deleting a data its node is also deleted. int main()
{
//creating 4 pointers of type struct Node
87
//So these can point to address of struct type variable June 17, 2020
struct Node* head = NULL;
struct Node* node2 = NULL; Insertion at begin in Singly linked list in C++ programming
struct Node* node3 = NULL; How to perform insertion at beginning in Singly Linked
struct Node* node4 = NULL; List in C++?
Insertion at Beginning in Singly Linked List in C++, is one
// allocate 3 nodes in the heap of the operations that we can perform on Linked List.
head = (struct Node*)malloc(sizeof(struct Node)); Singly linked list in C++ are part of linked list and is a type
node2 = (struct Node*)malloc(sizeof(struct Node)); of linear data structure. Linked is made up of two parts
node3 = (struct Node*)malloc(sizeof(struct Node)); node and pointer where node contains the data and pointer
node4 = (struct Node*)malloc(sizeof(struct Node)); contains the address of the next node.
10 20 30 40 new_node->data = new_data
3.) Point the pointer of new node to the head of singly
linked list
88
SET NEW_NODE → DATA = VALUE stnode-> nextptr = NULL; //Links the address field to
SET NEW_NODE → NEXT = HEAD NULL
SET HEAD = NEW_NODE tmp = stnode;
EXIT
C++ program to insert an element at beginning of singly for(i=2; i<=n; i++)
linked list {
#include <iostream> frntNode = (struct node *)malloc(sizeof(struct
using namespace std; node));
struct node
{ if(frntNode == NULL) //If frntnode is null no
int num; memory cannot be alloted
node *nextptr; {
}*stnode; //node constructed cout<<" Memory can not be allocated";
break;
void createList(int n); }
void insertatBegin(int num); else
void display(); {
cout<<"Enter the data for node "<<i<<": "; //
int main() Entering data in nodes.
{ cin>>num;
int n,num; frntNode->num = num;
frntNode->nextptr = NULL;
cout<<"Enter the number of nodes: "; tmp->nextptr = frntNode;
cin>>n; tmp = tmp->nextptr;
createList(n); }
cout<<"\nLinked list data: \n"; }
display(); }
cout<<"\nEnter data you want to insert at the beginning: }
";
cin>>num; void insertatBegin(int num) //function to insert element at
insertatBegin(num); beginning
cout<<"\nLinked list after insertion: \n"; {
display(); struct node *frntNode;
frntNode = (struct node*)malloc(sizeof(struct node));
return 0; if(frntNode == NULL)
} {
void createList(int n) //function to create linked list. cout<<" Memory can not be allocated";
{ }
struct node *frntNode, *tmp; else
int num, i; {
frntNode->num = num; //Linkinking data
stnode = (struct node *)malloc(sizeof(struct node)); frntNode->nextptr = stnode; //Linking address
if(stnode == NULL) stnode = frntNode;
{ }
cout<<" Memory can not be allocated"; }
}
else void display() //function to print linked list
{ {
struct node *tmp;
cout<<"Enter the data for node 1: "; if(stnode == NULL)
cin>>num; {
stnode-> num = num; cout<<" No data found in the list";
}
89
else Node *next;
{ };
tmp = stnode; Steps to insert an element at end of singly linked list
cout<<"Linked List: "; 1.) Allocate space for a new node.
while(tmp != NULL)
{ new_node = (struct node *) malloc(sizeof(struct node *));
cout<<"\t"<<tmp->num; 2.) In the space created for new node put the data in.
tmp = tmp->nextptr;
} new_node->data = new_data
} 3.) Point the pointer of new node to null
}
Output: new_node->ptr = NULL;
Enter the number of nodes: 4 4.) If the Linked List is empty, then make the new node as
Enter the data for node 1: 11 head
Enter the data for node 2: 22
Enter the data for node 3: 33 if (*head == NULL)
Enter the data for node 4: 44 *head = new_node;
5.) Traverse till last node and point the pointer of this node
Linked list data: to new node.
Linked List: 11 22 33 44
Enter data you want to insert at the beginning: 55 while (last->next != NULL)
last = last->next;
Linked list after insertion: last->ptr = new_node;
Linked List: 55 11 22 33
44
Did you know!
We can traverse in only one direction in singly linked list as
Insertion at End in Singly Linked List in C++ singly linked list does not contain previous pointer, it only
has next pointer.×Dismiss alert
Algorithm for insertion at end in singly linked list in C++ Algorithm for Insertion at end in singly linked list in
How to insert element at End in Singly Linked List in C++? c++
To add a new node at end we need to allocate space for the
new node first, then we have to store null in the pointer of IF PTR = NULL
newly created node and make the new node as tail of the EXIT
linked list. In this way insertion at end is done in linked SET NEW_NODE = PTR
list.Insertion at end in singly linked list in C++, is one of SET PTR = PTR – > NEXT
the insertion operations that we can perform on Linked SET NEW_NODE – > DATA = VAL
List. Singly linked list in C++ are part of linked list and is a SET NEW_NODE – > NEXT = NULL
type of linear data structure. Linked is made up of two parts SET PTR = HEAD
node and pointer where node contains the data and pointer WHILE PTR – > NEXT != NULL
contains the address of the next node. SET PTR = PTR – > NEXT
SET PTR – > NEXT = NEW_NODE
EXIT
Singly linked list definition in C++ C++ program to insert an element at end of singly
Nodes of singly linked list is created by using the code linked list
mentioned besides. #include <iostream>
This set of code will construct linked list by creating each using namespace std;
node of the list. //creating the structure of a new node
struct node
class Node {
{ int num;
int data; node *nextptr;
90
}*stnode; }
else
void createList(int n) //function to create a linked list. {
{ tmp = stnode;
struct node *frntNode, *tmp; cout<<"Linked List: ";
int num, i; while(tmp != NULL)
{
stnode = (struct node *)malloc(sizeof(struct node)); cout<<"\t"<<tmp->num;
if(stnode == NULL) tmp = tmp->nextptr;
{ }
cout<<"Memory can not be allocated"; }
} }
else
{ void insertatEnd(int num)//function to add element at the
end
cout<<"Enter the data for node 1: "; {
cin>>num; struct node *frntNode, *tmp;
stnode-> num = num; frntNode = (struct node*)malloc(sizeof(struct node));
stnode-> nextptr = NULL; //Links the address field to if(frntNode == NULL)
NULL {
tmp = stnode; cout<<"Memory can not be allocated.";
}
for(i=2; i<=n; i++) else
{ {
frntNode = (struct node *)malloc(sizeof(struct frntNode->num = num; //Linking the data part
node)); frntNode->nextptr = NULL;
tmp = stnode;
while(tmp->nextptr != NULL)
if(frntNode == NULL) //If frntnode is null no tmp = tmp->nextptr;
memory cannot be allotted tmp->nextptr = frntNode; //Linking the address part
{ }
cout<<" Memory can not be allocated"; }
break;
}
else int main()
{ {
cout<<"Enter the data for node "<<i<<": "; // int n,num;
Entering data in nodes.
cin>>num; cout<<"Enter the number of nodes: ";
frntNode->num = num; cin>>n;
frntNode->nextptr = NULL; createList(n);
tmp->nextptr = frntNode; cout<<"\nLinked list data: \n";
tmp = tmp->nextptr; display();
} cout<<"\nEnter data you want to insert at the end: ";
} cin>>num;
} insertatEnd(num);
} cout<<"\nLinked list after insertion: \n";
display();
void display() //function to print linked list
{ return 0;
struct node *tmp; }
if(stnode == NULL)
{
cout<<" No data found in the list"; Insertion in between of nodes in singly linked list in C++
91
EXIT
SET NEW_NODE = PTR
Insertion in between the nodes in singly linked list in C++ NEW_NODE → DATA = VAL
How to perform insertion in between nodes in Singly SET TEMP = HEAD
Linked List in C++? SET I = 0
Insertion in between of nodes in singly linked lists in C++ REPEAT
is a multiple step process. In this article we will learn these TEMP = TEMP → NEXT
steps and algorithms for data insertion at desired positions. IF TEMP = NULL
EXIT
We can also perform insertion at beginning that is inserting PTR → NEXT = TEMP → NEXT
an element in the beginning of the linked list and insertion TEMP → NEXT = PTR
at end of the linked list. You can learn about this by SET PTR = NEW_NODE
clicking the button below EXIT
Program for insertion in between of nodes in singly linked
Insertion at beginning list in C++
Steps to insert an element in between of nodes in singly #include <iostream>
linked list using namespace std;
Following steps are followed for insertion of an element at
nth position in singly linked list. struct node
{
1.)If there is no data in the head then exit int num;
node *nextptr;
If(head==NULL) }*stnode; //node constructed
return
2.) Allocate space for a new node. void createList(int n);
void insertNode(int num, int pos);
new_node = (struct node *) malloc(sizeof(struct node *)); void display();
3.) In the space created for the new node, put the data in.
int main()
new_node->data = new_data {
4.)Traverse till the desired position and make the pointer of int n,num,pos;
the new node where the previous node is pointing.
cout<<"Enter the number of nodes: ";
new_node->ptr= prev_node->ptr cin>>n;
5.) Now point the pointer of the previous node to the new createList(n);
node. cout<<"\nLinked list data: \n";
display();
prev_node->ptr = new_node cout<<"\nEnter data you want to insert at the nth
Defining a singly linked list in C++ position: ";
Nodes of singly linked lists are created by using the code cin>>num;
mentioned besides. cout<<"Enter the position to insert new node : ";
This set of code will construct a linked list by creating each cin>>pos;
node of the list. insertNode( num, pos);
cout<<"\nLinked list after insertion: \n";
class Node display();
{
int data; return 0;
Node *next; }
}; void createList(int n) //function to create linked list.
Algorithm for insertion in between the nodes in singly {
linked list in c++ struct node *frntNode, *tmp;
Algorithm to insert an element at nth position of singly int num, i;
linked list
IF PTR = NULL stnode = (struct node *)malloc(sizeof(struct node));
92
if(stnode == NULL) tmp = stnode;
{ for(i=2; i<=pos-1; i++)
cout<<"Memory can not be allocated"; {
} tmp = tmp->nextptr;
else
{ if(tmp == NULL)
break;
cout<<"Enter the data for node 1: "; }
cin>>num; if(tmp != NULL)
stnode-> num = num; {
stnode-> nextptr = NULL; //Linking the address field frntNode->nextptr = tmp->nextptr; //Linking the
to NULL address part of new node
tmp = stnode; tmp->nextptr = frntNode;
}
for(i=2; i<=n; i++) else
{ {
frntNode = (struct node *)malloc(sizeof(struct cout<<"Data cannot be entered in that particular
node)); position\n";
}
}
if(frntNode == NULL) //If frntnode is null no }
memory cannot be allotted
{ void display() //function to print linked list
cout<<"Memory can not be allocated"; {
break; struct node *tmp;
} if(stnode == NULL)
else {
{ cout<<" No data found in the list";
cout<<"Enter the data for node "<<i<<": "; // }
Entering data in nodes. else
cin>>num; {
frntNode->num = num; tmp = stnode;
frntNode->nextptr = NULL; cout<<"Linked List: ";
tmp->nextptr = frntNode; while(tmp != NULL)
tmp = tmp->nextptr; {
} cout<<"\t"<<tmp->num;
} tmp = tmp->nextptr;
} }
} }
}
void insertNode(int num, int pos)//fuction to add node in Output:
desired position Enter the number of nodes: 4
{ Enter the data for node 1: 11
int i; Enter the data for node 2: 22
struct node *frntNode, *tmp; Enter the data for node 3: 33
frntNode = (struct node*)malloc(sizeof(struct node)); Enter the data for node 4: 44
if(frntNode == NULL)
{ Linked list data:
cout<<"Memory can not be allocated."; Linked List: 11 22 33 44
} Enter data you want to insert at the nth position: 55
else Enter the position to insert new node : 4
{
frntNode->num = num; //Linking the data Linked list after insertion: Linked List: 11 22
frntNode->nextptr = NULL; 33 55 44
93