Thanks to visit codestin.com
Credit goes to www.scribd.com

0% found this document useful (0 votes)
0 views24 pages

Unit 3 Sorting

Uploaded by

Arihant Shukla
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
0 views24 pages

Unit 3 Sorting

Uploaded by

Arihant Shukla
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 24

SORTING

A Sorting Algorithm is used to rearrange a given array or list of elements according to a


comparison operator on the elements. The comparison operator is used to decide the new order
of elements in the respective data structure.
For Example: The below list of characters is sorted in increasing order of their ASCII values.
That is, the character with a lesser ASCII value will be placed first than the character with a
higher ASCII value.

Bubble Sort Algorithm


Bubble Sort is the simplest sorting algorithm that works by repeatedly swapping
the adjacent elements if they are in the wrong order.

In this algorithm,
 Traverse from left and compare adjacent elements and the higher one is placed
at right side.
 In this way, the largest element is moved to the rightmost end at first.
 This process is then continued to find the second largest and place it and so on
until the data is sorted.
This algorithm has a worst-case time complexity of O(n2). The bubble sort has
a space complexity of O(1).
Example-
Input: arr[] = {6, 3, 0, 5}
First Pass:
The largest element is placed in its correct position, i.e., the end of the array.

Second Pass:
Place the second largest element at correct position

Third Pass:
Place the remaining two elements at their correct positions.
Bubble Sort Implementation-
#include<stdio.h>
int main(){
int a[50], i,j,n,t;
printf("enter the No of elements in the list:");
scanf("%d", &n);
printf("enter the elements for sorting:");
for(i=0; i<n; i++){
scanf ("%d", &a[i]);
}
printf("Before bubble sorting the elements are:");
for(i=0; i<n; i++)
printf("%d \t", a[i]);
for (i=0; i<n-1; i++){
for (j=i+1; j<n; j++){
if (a[i] > a[j]){
t = a[i];
a[i] = a[j];
a[j] = t;
}
}
}
printf ("\nAfter bubble sorting the elements are:");
for (i=0; i<n; i++)
printf("%d\t", a[i]);
return 0;
}
Selection Sort
Selection sort is a simple and efficient sorting algorithm that works by repeatedly
selecting the smallest (or largest) element from the unsorted portion of the list and
moving it to the sorted portion of the list.
example:
arr[] = {64, 25, 12, 22, 11}

First pass:
 For the first position in the sorted array, the whole array is traversed from index
0 to 4 sequentially. The first position where 64 are stored presently, after
traversing whole array it is clear that 11 is the lowest value.
 Thus, replace 64 with 11. After one iteration 11, which happens to be the least
value in the array, tends to appear in the first position of the sorted list.

Second Pass:
 For the second position, where 25 are present, again traverse the rest of the array
in a sequential manner.
 After traversing, we found that 12 is the second lowest value in the array and it
should appear at the second place in the array, thus swap these values.

Third Pass:
 Now, for third place, where 25 is present again traversing the rest of the array
and find the third least value present in the array.
 While traversing, 22 came out to be the third least value and it should appear at
the third place in the array, thus swap 22 with element present at third position.
Fourth pass:
 Similarly, for fourth position traverse the rest of the array and find the fourth
least element in the array
 As 25 is the 4th lowest value hence, it will place at the fourth position.

Fifth Pass:
 At last the largest value present in the array automatically get placed at the last
position in the array
 The resulted array is the sorted array.

 The time complexity of the selection sort algorithm is:


 The time complexity of selection sort in the best-case scenario is O. (n2).
 The selection sort has an average case time complexity of O. (n2).
 Selection sort has a worst-case time complexity of O. (n2).
 As a result, the space complexity is O. (1).
Implementation:
#include <stdio.h>
int main() {
int arr[10]={6,12,0,18,11,99,55,45,34,2};
int n=10;
int i, j, position, swap;
printf("Before the Selection sort the elements are:\n");
for(i =0; i<n; i++)
printf("%d\t", arr[i]);

for(i =0;i<(n-1); i++) {


position = i;
for(j =i+1; j < n; j++) {
if(arr[position] > arr[j])
position = j;
}
if(position != i) {
swap = arr[i];
arr[i] = arr[position];
arr[position] = swap;
}
}
printf("\nAfter the Selection sort the elements are:\n");
for(i = 0; i < n; i++)
printf("%d\t", arr[i]);
return 0;
}
Insertion Sort Algorithm

Insertion sort is a simple sorting algorithm that works similar to the way you sort
playing cards in your hands. The array is virtually split into a sorted and an
unsorted part. Values from the unsorted part are picked and placed at the correct
position in the sorted part.

 To sort an array of size N in ascending order iterate over the array and
compare the current element (key) to its predecessor,
 If the key element is smaller than its predecessor, compare it to the elements
before.
 Move the greater elements one position up to make space for the swapped
element.

Complexity of Insertion Sort


 The worst case time complexity of Insertion sort is O(N^2)
 The average case time complexity of Insertion sort is O(N^2)
 The time complexity of the best case is O(N).
 The space complexity is O(1)

Working of Insertion Sort algorithm


Consider an example:

arr[]: {12, 11, 13, 5, 6}

12 11 13 5 6

First Pass:

 Initially, the first two elements of the array are compared in insertion sort.
12 11 13 5 6

 Here, 12 is greater than 11 hence they are not in the ascending order and 12 is
not at its correct position. Thus, swap 11 and 12.
 So, for now 11 is stored in a sorted sub-array.
11 12 13 5 6

Second Pass:
 Now, move to the next two elements and compare them

11 12 13 5 6

 Here, 13 is greater than 12, thus both elements seems to be in ascending order,
hence, no swapping will occur. 12 also stored in a sorted sub-array along with
11

Third Pass:
 Now, two elements are present in the sorted sub-array which are 11 and 12
 Moving forward to the next two elements which are 13 and 5

11 12 13 5 6

 Both 5 and 13 are not present at their correct place so swap them

11 12 5 13 6

 After swapping, elements 12 and 5 are not sorted, thus swap again

11 5 12 13 6

 Here, again 11 and 5 are not sorted, hence swap again

5 11 12 13 6

 Here, 5 is at its correct position

Fourth Pass:
 Now, the elements which are present in the sorted sub-array are 5, 11 and 12
 Moving to the next two elements 13 and 6

5 11 12 13 6
 Clearly, they are not sorted, thus perform swap between both

5 11 12 6 13

 Now, 6 is smaller than 12, hence, swap again

5 11 6 12 13

 Here, also swapping makes 11 and 6 unsorted hence, swap again

5 6 11 12 13

 Finally, the array is completely sorted.

Implementation-

#include <stdio.h>
// Function to print an array
void printArray(int array[], int size) {
for (int i = 0; i < size; i++) {
printf("%d ", array[i]);
}
printf("\n");
}

void insertionSort(int array[], int size) {


for (int step = 1; step < size; step++) {
int key = array[step];
int j = step - 1;

// For descending order, change key<array[j] to key>array[j].


while (key < array[j] && j >= 0) {
array[j + 1] = array[j];
--j;
}
array[j + 1] = key;
}
}

// Driver code
int main() {
int data[] = {9, 5, 1, 4, 3};
int size = sizeof(data) / sizeof(data[0]);
printf("array before sorting:\n");
printArray(data, size);
insertionSort(data, size);
printf("Sorted array in ascending order:\n");
printArray(data, size);
}

Quick Sort

Quick sort is a highly efficient sorting algorithm and is based on partitioning of


array of data into smaller arrays. A large array is partitioned into two arrays one of
which holds values smaller than the specified value, say pivot, based on which the
partition is made and another array holds values greater than the pivot value.
This algorithm follows the divide and conquers approach. Divide and conquer is a
technique of breaking down the algorithms into sub problems, then solving the sub
problems, and combining the results back together to solve the original problem.

Divide: In Divide, first pick a pivot element. After that, partition or rearrange the
array into two sub-arrays such that each element in the left sub-array is less than or
equal to the pivot element and each element in the right sub-array is larger than the
pivot element.

Conquer: Recursively, sort two sub arrays with Quick sort.

Combine: Combine the already sorted array.


Quick sort picks an element as pivot, and then it partitions the given array around
the picked pivot element. In quick sort, a large array is divided into two arrays in
which one holds values that are smaller than the specified value (Pivot), and
another array holds the values that are greater than the pivot.
Working of Quick Sort-
Consider: arr[] = {10, 80, 30, 90, 40}.
 Compare 10 with the pivot and as it is less than pivot arrange it accrodingly.

 Compare 80 with the pivot. It is greater than pivot.

 Compare 30 with pivot. It is less than pivot so arrange it accordingly.

 Compare 90 with the pivot. It is greater than the pivot.

 Arrange the pivot in its correct position.


As the partition process is done recursively, it keeps on putting the pivot in its
actual position in the sorted array. Repeatedly putting pivots in their actual
position makes the array sorted.
 Initial partition on the main array:

 Partitioning of the subarrays:

Now, in a similar manner, quick sort algorithm is separately applied to the left and
right sub-arrays.

10 30 40 80 90
Time Complexity:
 Best Case: Ω (N log (N))

 Average Case: θ ( N log (N))

 Worst Case: O(N2)

 Auxiliary Space: O(1), if we don’t consider the recursive stack space. If we


consider the recursive stack space then, in the worst case quicksort could
make O(N).

Advantages of Quick Sort:


 It is a divide-and-conquer algorithm that makes it easier to solve problems.
 It is efficient on large data sets.
 It has a low overhead, as it only requires a small amount of memory to
function.

Disadvantages of Quick Sort:


 It has a worst-case time complexity of O(N2), which occurs when the pivot is
chosen poorly.
 It is not a good choice for small data sets.
 It is not a stable sort, meaning that if two elements have the same key, their
relative order will not be preserved in the sorted output in case of quick sort,
because here we are swapping elements according to the pivot’s position
(without considering their original positions).
Merge Sort Algorithm

Merge sort is defined as a sorting algorithm that works by dividing an array into
smaller sub arrays, sorting each sub array, and then merging the sorted sub
arrays back together to form the final sorted array. With worst-case time
complexity being Ο(n log n), it is one of the most respected algorithms.

Merge sort is similar to the quick sort algorithm as it uses the divide and conquer
approach to sort the elements. It is one of the most popular and efficient sorting
algorithm. It divides the given list into two equal halves, calls itself for the two
halves and then merges the two sorted halves

merge() function is defined to perform the merging.

Time complexity of Merge Sort is O(n*Log n) in all the 3 cases (worst, average
and best) as merge sort always divides the array in two halves and takes linear
time to merge two halves.

Merge Sort Working-


Let us take an unsorted array as the following −

 Merge sort first divides the whole array iteratively into equal halves unless
the atomic values are achieved. Now, an array of 8 items is divided into two
arrays of size 4.

 This does not change the sequence of appearance of items in the original.
Now divide these two arrays into halves.
 Further divide these arrays and achieve atomic value which can no more be
divided.

 Now, combine them in exactly the same manner as they were broken down.
 First compare the element for each list and then combine them into another
list in a sorted manner. Now, 14 and 33 are in sorted positions. Compare 27
and 10 and in the target list of 2 values we put 10 first, followed by 27. Let
change the order of 19 and 35 whereas 42 and 44 are placed sequentially.

 In the next iteration of the combining phase, compare lists of two data
values, and merge them into a list of found data values placing all in a sorted
order.

 After the final merging, the list should look like this −

// C implementation of Merge Sort

#include <stdio.h>

// Merge two subarrays L and M into arr


void merge(int arr[], int p, int q, int r) {

// Create L ← A[p..q] and M ← A[q+1..r]


int n1 = q - p + 1;
int n2 = r - q;

int L[n1], M[n2];

for (int i = 0; i < n1; i++)


L[i] = arr[p + i];
for (int j = 0; j < n2; j++)
M[j] = arr[q + 1 + j];

// Maintain current index of sub-arrays and main array


int i, j, k;
i = 0;
j = 0;
k = p;

// Until we reach either end of either L or M, pick larger among elements L and M
and place them in the correct position at A[p..r]
while (i < n1 && j < n2) {
if (L[i] <= M[j]) {
arr[k] = L[i];
i++;
} else {
arr[k] = M[j];
j++;
}
k++;
}

// When we run out of elements in either L or M, pick up the remaining elements


and put in A[p..r]//
while (i < n1) {
arr[k] = L[i];
i++;
k++; }
while (j < n2) {
arr[k] = M[j];
j++;
k++;
}}

// Divide the array into two subarrays, sort them and merge them
void mergeSort(int arr[], int l, int r) {
if (l < r) {

// m is the point where the array is divided into two subarrays


int m = l + (r - l) / 2;
mergeSort(arr, l, m);
mergeSort(arr, m + 1, r);

// Merge the sorted subarrays


merge(arr, l, m, r);
}
}
// Print the array
void printArray(int arr[], int size) {
for (int i = 0; i < size; i++)
printf("%d ", arr[i]);
printf("\n");
}

// Driver program
int main() {
int arr[] = {6, 5, 12, 10, 9, 1};
int size = sizeof(arr) / sizeof(arr[0]);
printf("Unsorted array: \n");
printArray(arr, size);
mergeSort(arr, 0, size - 1);
printf("Sorted array after merge sort: \n");
printArray(arr, size);}
Radix Sort Algorithm
Radix sort is the linear sorting algorithm that is used for integers. In Radix sort,
there is digit by digit sorting is performed that is started from the least significant
digit to the most significant digit.

Example-

The process of radix sort works similar to the sorting of students names, according
to the alphabetical order. In this case, there are 26 radix formed due to the 26
alphabets in English. In the first pass, the names of students are grouped according
to the ascending order of the first letter of their names. After that, in the second
pass, their names are grouped according to the ascending order of the second letter
of their name. And the process continues until we find the sorted list.

Working of Radix sort Algorithm-

Steps Involved in Radix sort to sort an array in ascending order are --

 Find the maximum element of the array, let it be max


 Find the number of digits in max, let it be k.
 For each, i ranging from 1 to k, apply the counting sort algorithm for
the ith least-significant digit of each element. If any element has less
than i digits consider 0 at its place (Because 29 can also be represented
as 029).

Let us take an example-

Pass 1:

In the first pass, the list is sorted on the basis of the digits at 0's place.
After the first pass, the array elements are -

Pass 2:

In this pass, the list is sorted on the basis of the next significant digits (i.e., digits at
10th place).
After the second pass, the array elements are -

Pass 3:

In this pass, the list is sorted on the basis of the next significant digits (i.e., digits at
100th place).
After the third pass, the array elements are -

Now, the array is sorted in ascending order.

Radix sort complexity

Now, let's see the time complexity of Radix sort in best case, average case, and
worst case. We will also see the space complexity of Radix sort.

1. Time Complexity
Case Time Complexity

Best Case Ω(n+k)

Average Case θ(nk)

Worst Case O(nk)

2. Space Complexity
Space Complexity O(n + k)

Stable YES

// Radix Sort implementation in C

#include <stdio.h>

// Function to get the largest element from an array

int getMax(int array[], int n) {

int max = array[0];


for (int i = 1; i < n; i++)

if (array[i] > max)

max = array[i];

return max;

// Using counting sort to sort the elements in the basis of significant places

void countingSort(int array[], int size, int place) {

int output[size + 1];

int max = (array[0] / place) % 10;

for (int i = 1; i < size; i++) {

if (((array[i] / place) % 10) > max)

max = array[i];

int count[max + 1];

for (int i = 0; i < max; ++i)

count[i] = 0;

// Calculate count of elements

for (int i = 0; i < size; i++)

count[(array[i] / place) % 10]++;

// Calculate cumulative count

for (int i = 1; i < 10; i++)

count[i] += count[i - 1];

// Place the elements in sorted order


for (int i = size - 1; i >= 0; i--) {

output[count[(array[i] / place) % 10] - 1] = array[i];

count[(array[i] / place) % 10]--;

for (int i = 0; i < size; i++)

array[i] = output[i];

// Main function to implement radix sort

void radixsort(int array[], int size) {

// Get maximum element

int max = getMax(array, size);

// Apply counting sort to sort elements based on place value.

for (int place = 1; max / place > 0; place *= 10)

countingSort(array, size, place);

// Print an array

void printArray(int array[], int size) {

for (int i = 0; i < size; ++i) {

printf("%d ", array[i]);

printf("\n");

// Driver code
int main() {

int array[] = {121, 432, 564, 23, 1, 45, 788};

int n = sizeof(array) / sizeof(array[0]);

radixsort(array, n);

printArray(array, n);

You might also like