Professional Documents
Culture Documents
if (r >= l)
{
int mid = l + (r - l)/2;
// If the element is present at the middle itself
if (arr[mid] == x) return mid;
present
int main(void)
{
int arr[] = {2, 3, 4, 10, 40};
int n = sizeof(arr)/ sizeof(arr[0]);
int x = 10;
int result = binarySearch(arr, 0, n-1, x);
(result == -1)? printf("Element is not present in array")
: printf("Element is present at index %d",
result);
return 0;
}
Output:
int main(void)
{
int arr[] = {2, 3, 4, 10, 40};
int n = sizeof(arr)/ sizeof(arr[0]);
int x = 10;
int result = binarySearch(arr, 0, n-1, x);
(result == -1)? printf("Element is not present in array")
: printf("Element is present at index %d",
result);
return 0;
}
Output:
T(n) = T(n/2) + c
The above recurrence can be solved either using Recurrence T ree
method or Master method. It falls in case II of Master Method and
solution of the recurrence is
.
election Sort
January 31, 2014
arr[] = 64 25 12 22 11
// Find the minimum element in arr[0...4] and
place it at beginning
11 25 12 22 64
// Find the minimum element in arr[1...4] and
// place it at beginning of arr[1...4]
11 12 25 22 64
// Find the minimum element in arr[2...4] and
// place it at beginning of arr[2...4]
11 12 22 25 64
Output:
Sorted array:
11 12 22 25 64
Time Complexity: O(n*n) as there are two nested loops.
Auxiliary Space: O(1)
The good thing about selection sort is it never makes more than O(n)
swaps and can be useful when memory write is a costly operation.
Bubble Sort
February 2, 2014
completed. The algorithm needs one whole pass without any swap to
know it is sorted.
Third Pass:
( 1 2 4 5 8 ) > ( 1 2 4 5 8 )
( 1 2 4 5 8 ) > ( 1 2 4 5 8 )
( 1 2 4 5 8 ) > ( 1 2 4 5 8 )
( 1 2 4 5 8 ) > ( 1 2 4 5 8 )
Following is C implementation of Bubble Sort.
// C program for implementation of Bubble sort
#include <stdio.h>
void swap(int *xp, int *yp)
{
int temp = *xp;
*xp = *yp;
*yp = temp;
}
// A function to implement bubble sort
void bubbleSort(int arr[], int n)
{
int i, j;
for (i = 0; i < n; i++)
for (j = 0; j < n-i-1; j++) //Last i elements are already in
place
if (arr[j] > arr[j+1])
swap(&arr[j], &arr[j+1]);
}
/* Function to print an array */
void printArray(int arr[], int size)
{
int i;
for (i=0; i < size; i++)
printf("%d ", arr[i]);
printf("\n");
}
// Driver program to test above functions
int main()
{
int arr[] = {64, 34, 25, 12, 22, 11, 90};
int n = sizeof(arr)/sizeof(arr[0]);
bubbleSort(arr, n);
printf("Sorted array: \n");
printArray(arr, n);
return 0;
}
Output:
Sorted array:
11 12 22 25 34 64 90
Optimized Implementation:
The above function always runs O(n^2) time even if the array is sorted. It
can be optimized by stopping the algorithm if inner loop didnt cause any
swap.
// Optimized implementation of Bubble sort
#include <stdio.h>
void swap(int *xp, int *yp)
{
int temp = *xp;
*xp = *yp;
*yp = temp;
}
// An optimized version of Bubble Sort
void bubbleSort(int arr[], int n)
{
int i, j;
bool swapped;
for (i = 0; i < n; i++)
{
swapped = false;
for (j = 0; j < n-i-1; j++)
{
if (arr[j] > arr[j+1])
{
swap(&arr[j], &arr[j+1]);
swapped = true;
}
}
// IF no two elements were swapped by inner loop, then break
if (swapped == false)
break;
}
int i;
for (i=0; i < size; i++)
printf("%d ", arr[i]);
printf("\n");
Output:
Sorted array:
11 12 22 25 34 64 90
Time Complexity: O(n*n)
Auxiliary Space: O(1)
Boundary Cases: Bubble sort takes minimum time (Order of n) when
elements are already sorted.
Sorting In Place: Yes
Stable: Yes
Due to its simplicity, bubble sort is often used to introduce the concept of
a sorting algorithm.
In computer graphics it is popular for its capability to detect a very small
error (like swap of just two elements) in almost-sorted arrays and fix it
with just linear complexity (2n). For example, it is used in a polygon filling
algorithm, where bounding lines are sorted by their x coordinate at a
specific scan line (a line parallel to x axis) and with incrementing y their
Insertion Sort
March 7, 2013
Insertion sort is a simple sorting algorithm that works the way we sort
playing cards in our hands.
Algorithm
// Sort an arr[] of size n
insertionSort(arr, n)
Loop from i = 1 to n-1.
a) Pick element arr[i] and insert it into sorted sequence arr[0i-1]
Example:
12, 11, 13, 5, 6
Let us loop for i = 1 (second element of the array) to 5 (Size of input
array)
}
// A utility function ot print an array of size n
void printArray(int arr[], int n)
{
int i;
for (i=0; i < n; i++)
printf("%d ", arr[i]);
printf("\n");
Output:
5 6 11 12 13
Time Complexity: O(n*n)
Auxiliary Space: O(1)
Boundary Cases: Insertion sort takes maximum time to sort if elements
are sorted in reverse order. And it takes minimum time (Order of n) when
elements are already sorted.
Algorithmic Paradigm: Incremental Approach
Sorting In Place: Yes
Stable: Yes
Online: Yes
Uses: Insertion sort is uses when number of elements is small. It can
also be useful when input array is almost sorted, only few elements are
misplaced in complete big array.
ShellSort
June 16, 2014
correct
location
}
arr[j] = temp;
}
return 0;
}
void printArray(int arr[], int n)
{
for (int i=0; i<n; i++)
cout << arr[i] << " ";
}
int main()
{
int arr[] = {12, 34, 54, 2, 3}, i;
int n = sizeof(arr)/sizeof(arr[0]);
cout << "Array before sorting: \n";
printArray(arr, n);
shellSort(arr, n);
cout << "\nArray after sorting: \n";
printArray(arr, n);
return 0;
}
Output:
iteration. There are many other ways to reduce gap which lead to better
time complexity
QuickSort
January 7, 2014
Implementation:
Following is C++ implementation of QuickSort.
/* A typical recursive implementation of quick sort */
#include<stdio.h>
// A utility function to swap two elements
void swap(int* a, int* b)
{
int t = *a;
*a = *b;
*b = t;
}
/* This function takes last element as pivot, places the pivot element
at its
correct position in sorted array, and places all smaller (smaller
than pivot)
to left of pivot and all greater elements to right of pivot */
int partition (int arr[], int l, int h)
{
int x = arr[h];
// pivot
int i = (l - 1); // Index of smaller element
Output:
Sorted array:
1 5 7 8 9 10
Analysis of QuickSort
Time taken by QuickSort in general can be written as following.
(n)
The first two terms are for two recursive calls, the last term is for the
partition process. k is the number of elements which are smaller than
pivot.
The time taken by QuickSort depends upon the input array and partition
strategy. Following are three cases.
Worst Case: The worst case occurs when the partition process always
picks greatest or smallest element as pivot. If we consider above
partition strategy where last element is always picked as pivot, the worst
case would occur when the array is already sorted in increasing or
decreasing order. Following is recurrence for worst case.
(n)
T(n) = T(n-1) +
(n)
(n2).
Best Case: The best case occurs when the partition process always
picks the middle element as pivot. Following is recurrence for best case.
T(n) = 2T(n/2) +
(n)
(n)
Merge Sort
March 15, 2013
MergeSort is a Divide and Conquer algorithm. It divides input array in two halves, calls itself for the two
halves and then merges the two sorted halves. The merg() function is used for merging two halves. The
merge(arr, l, m, r) is key process that assumes that arr[l..m] and arr[m+1..r] are sorted and merges the two
sorted sub-arrays into one. See following C implementation for details.
MergeSort(arr[], l, r)
If r > l
1. Find the middle point to divide the
array into two halves:
middle m = (l+r)/2
2. Call mergeSort for first half:
Call mergeSort(arr, l, m)
3. Call mergeSort for second half:
Call mergeSort(arr, m+1, r)
4. Merge the two halves sorted in step 2
and 3:
Call merge(arr, l, m, r)
The following diagram from wikipedia shows the complete merge sort process for an example array {38,
27, 43, 3, 9, 82, 10}. If we take a closer look at the diagram, we can see that the array is recursively
divided in two halves till the size becomes 1. Once the size becomes 1, the merge processes comes into
action and starts merging arrays back till the complete array is merged.
}
/* Copy the remaining elements of L[], if there are any */
while (i < n1)
{
arr[k] = L[i];
i++;
k++;
}
/* UITLITY FUNCTIONS */
/* Function to print an array */
void printArray(int A[], int size)
{
int i;
for (i=0; i < size; i++)
printf("%d ", A[i]);
printf("\n");
}
Output:
Given array is
12 11 13 5 6 7
Sorted array is
5 6 7 11 12 13
Time Complexity: Sorting arrays on different machines. Merge Sort is a recursive algorithm and time
complexity can be expressed as following recurrence relation.
T(n) = 2T(n/2) +
The above recurrence can be solved either using Recurrence Tree method or Master method. It falls in
case II of Master Method and solution of the recurrence is
.
Time complexity of Merge Sort is
always divides the array in two halves and take linear time to merge two halves.
Auxiliary Space: O(n)
Algorithmic Paradigm: Divide and Conquer
Sorting In Place: No in a typical implementation
Stable: Yes
Heap Sort
March 16, 2013
4(3)
1(4)
The heapify procedure calls itself recursively
to build heap in top down manner.
// C implementation of Heap Sort
#include <stdio.h>
#include <stdlib.h>
*b = t; }
// The main function to heapify a Max Heap. The function assumes that
// everything under given root (element at index idx) is already
heapified
void maxHeapify(struct MaxHeap* maxHeap, int idx)
{
int largest = idx; // Initialize largest as root
int left = (idx << 1) + 1; // left = 2*idx + 1
int right = (idx + 1) << 1; // right = 2*idx + 2
// See if left child of root exists and is greater than root
if (left < maxHeap->size && maxHeap->array[left] > maxHeap>array[largest])
largest = left;
// See if right child of root exists and is greater than the largest
so far
if (right < maxHeap->size && maxHeap->array[right] > maxHeap>array[largest])
largest = right;
// Start from bottommost and rightmost internal mode and heapify all
// internal modes in bottom up way
for (i = (maxHeap->size - 2) / 2; i >= 0; --i)
maxHeapify(maxHeap, i);
return maxHeap;
// Repeat following steps while heap size is greater than 1. The last
// element in max heap will be the minimum element
while (maxHeap->size > 1)
{
// The largest item in Heap is stored at the root. Replace it with
the
1.
}
// A utility function to print a given array of given size
void printArray(int* arr, int size)
{
int i;
for (i = 0; i < size; ++i)
printf("%d ", arr[i]);
}
/* Driver program to test above functions */
int main()
{
int arr[] = {12, 11, 13, 5, 6, 7};
int size = sizeof(arr)/sizeof(arr[0]);
printf("Given array is \n");
printArray(arr, size);
heapSort(arr, size);
Output:
Given array is
12 11 13 5 6 7
Sorted array is
5 6 7 11 12 13
Notes:
Heap sort is an in-place algorithm.
Its typical implementation is not stable, but can be made stable
(See this)
Time Complexity: Time complexity of heapify is O(Logn). Time
complexity of createAndBuildHeap() is O(n) and overall time complexity
of Heap Sort is O(nLogn).
Applications of HeapSort
1. Sort a nearly sorted (or K sorted) array
2. k largest(or smallest) elements in an array
Heap sort algorithm has limited uses because Quicksort and Mergesort
are better in practice. Nevertheless, the Heap data structure itself is
enormously used. See Applications of Heap Data Structure
Bucket Sort
Bucket sort is mainly useful when input is uniformly distributed over a
range. For example, consider the following problem.
Sort a large set of floating point numbers which are in range from 0.0 to
1.0 and are uniformly distributed across the range. How do we sort the
numbers efficiently?
A simple way is to apply a comparison based sorting algorithm.
The lower bound for Comparison based sorting algorithm (Merge Sort,
Heap Sort, Quick-Sort .. etc) is
, i.e., they cannot do better than
nLogn.
Can we sort the array in linear time? Counting sort can not be applied
here as we use keys as index in counting sort. Here keys are floating
point numbers.
The idea is to use bucket sort. Following is bucket algorithm.
bucketSort(arr[], n)
1) Create n empty buckets (Or lists).
2) Do following for every array element arr[i].
.......a) Insert arr[i] into bucket[n*array[i]]
3) Sort individual buckets using insertion sort.
4) Concatenate all sorted buckets.
Following diagram (taken from CLRS book) demonstrates working of
bucket sort.
Output:
Sorted array is
0.1234 0.3434 0.565 0.656 0.665 0.897
Solution:
1) Find the candidate unsorted subarray
a) Scan from left to right and find the first element which is greater than
the next element. Let s be the index of such an element. In the above
example 1, s is 3 (index of 30).
b) Scan from right to left and find the first element (first in right to left
order) which is smaller than the next element (next in right to left order).
Let e be the index of such an element. In the above example 1, e is 7
(index of 31).
2) Check whether sorting the candidate unsorted subarray makes
the complete array sorted or not. If not, then include more elements
in the subarray.
a) Find the minimum and maximum values in arr[s..e]. Let minimum and
maximum values be minand max. min and max for [30, 25, 40, 32, 31]
are 25 and 40 respectively.
b) Find the first element (if there is any) in arr[0..s-1] which is greater
than min, change s to index of this element. There is no such element in
above example 1.
c) Find the last element (if there is any) in arr[e+1..n-1] which is smaller
than max, change e to index of this element. In the above example 1, e is
changed to 8 (index of 35)
3) Print s and e.
Implementation:
#include<stdio.h>
void printUnsorted(int arr[], int n)
{
int s = 0, e = n-1, i, max, min;
// step 1(a) of above algo
int main()
int arr[] = {10, 12, 20, 30, 25, 40, 32, 31, 35, 50, 60};
int arr_size = sizeof(arr)/sizeof(arr[0]);
printUnsorted(arr, arr_size);
getchar();
return 0;
# include <stdio.h>
/* Function to swap values at two pointers */
void swap (char *x, char *y)
{
char temp;
temp = *x;
*x = *y;
*y = temp;
}
/* Function to print permutations of string
This function takes three parameters:
1. String
2. Starting index of the string
3. Ending index of the string. */
void permute(char *a, int i, int n)
{
int j;
if (i == n)
printf("%s\n", a);
else
{
for (j = i; j <= n; j++)
{
swap((a+i), (a+j));
permute(a, i+1, n);
swap((a+i), (a+j)); //backtrack
}
}
}
/* Driver program to test above functions */
int main()
{
char a[] = "ABC";
permute(a, 0, 2);
getchar();
return 0;
Output:
ABC
ACB
BAC
BCA
CBA
CAB
Algorithm Paradigm: Backtracking
Time Complexity: O(n*n!)
The inner loop will run at most k times. To move every element to its
correct place, at most k elements need to be moved. So
overall complexity will be O(nk)
We can sort such arrays more efficiently with the help of Heap data
structure. Following is the detailed process that uses Heap.
1) Create a Min Heap of size k+1 with first k+1 elements. This will take
O(k) time (See this GFact)
2) One by one remove min element from heap, put it in result array, and
add a new element to heap from remaining elements.
Removing an element and adding a new element to min heap will take
Logk time. So overall complexity will be O(k) + O((n-k)*logK)
#include<iostream>
using namespace std;
// Prototype of a utility function to swap two integers
void swap(int *x, int *y);
// A class for Min Heap
class MinHeap
{
int *harr; // pointer to array of elements in heap
int heap_size; // size of min heap
public:
// Constructor
MinHeap(int a[], int size);
// to heapify a subtree with root at given index
void MinHeapify(int );
// to get index of left child of node at index i
int left(int i) { return (2*i + 1); }
// to get index of right child of node at index i
int right(int i) { return (2*i + 2); }
// to remove min (or root), add a new value x, and return old root
int replaceMin(int x);
};
heap_size = size;
harr = a; // store address of array
int i = (heap_size - 1)/2;
while (i >= 0)
{
MinHeapify(i);
i--;
}
*x = *y;
*y = temp;
}
// A utility function to print array elements
void printArray(int arr[], int size)
{
for (int i=0; i < size; i++)
cout << arr[i] << " ";
cout << endl;
}
// Driver program to test above functions
int main()
{
int k = 3;
int arr[] = {2, 6, 3, 12, 56, 8};
int n = sizeof(arr)/sizeof(arr[0]);
sortK(arr, n, k);
cout << "Following is sorted array\n";
printArray (arr, n);
return 0;
}
Output: