0% found this document useful (0 votes)
70 views

Algorithms Review Report: Analysis of Algorithm

The document provides an analysis of various sorting and searching algorithms. It discusses 10 sorting algorithms including selection sort, heap sort, counting sort, bucket sort, binary insertion sort, shell sort, cycle sort, brick sort, cartesian sorting and radix sort. It also discusses 5 searching algorithms: Fibonacci search, jump search, interpolation search, exponential search and sublist search. Finally, it discusses two divide and conquer algorithms - closest pair of point problem and FFT algorithm, as well as two dynamic programming problems - friends pairing problem and tiling problem.

Uploaded by

Sitara Shafiq
Copyright
© © All Rights Reserved
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
70 views

Algorithms Review Report: Analysis of Algorithm

The document provides an analysis of various sorting and searching algorithms. It discusses 10 sorting algorithms including selection sort, heap sort, counting sort, bucket sort, binary insertion sort, shell sort, cycle sort, brick sort, cartesian sorting and radix sort. It also discusses 5 searching algorithms: Fibonacci search, jump search, interpolation search, exponential search and sublist search. Finally, it discusses two divide and conquer algorithms - closest pair of point problem and FFT algorithm, as well as two dynamic programming problems - friends pairing problem and tiling problem.

Uploaded by

Sitara Shafiq
Copyright
© © All Rights Reserved
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
You are on page 1/ 41

1

Analysis of Algorithm
Algorithms Review Report

Student Information:
Sitara Shafiq 2017-CS-355
Report Submitted to:
Sir Samyan

Computer Science and Engineering Department


University of Engineering and Technology, Lahore

[Type here]
2

Table of Content:
1. Sorting Algorithm
i) Selection Sort --------------------------------------------------------------3
ii) Heap Sort--------------------------------------------------------------------4
iii) Counting Sort---------------------------------------------------------------6
iv) Bucket Sort------------------------------------------------------------------19
v) Binary Insertion Sort------------------------------------------------------10
vi) Shell sort---------------------------------------------------------------------13
vii) Cycle Sort--------------------------------------------------------------------13
viii) Brick Sort----------------------------------------------------------------16
ix) Cartesian Sorting----------------------------------------------------------18
x) Radix Sort-------------------------------------------------------------------23
2. Searching Algorithm---------------------------------------------------------25
i) Fibonacci Search----------------------------------------------------------25
ii) Jump Search----------------------------------------------------------------27
iii) Interpolation Search------------------------------------------------------29
iv) Exponential Search--------------------------------------------------------31
v) Sublist Search---------------------------------------------------------------34
3. Divide and Conquer-----------------------------------------------------------34
i) Closest Pair of Point--------------------------------------------------------34
ii) FFT Algorithm----------------------------------------------------------------38
4. Dynamic Programming--------------------------------------------------------39
i) Friends pairing problem----------------------------------------------------39
ii) Tiling Problem-----------------------------------------------------------------40

[Type here]
3

Sorting Algorithm
i- Selection Sort:

Selection sort is a kind algorithm kinds an array through time and again
finding the minimum element from unsorted element and setting it at the start.
The algorithm continues sub arrays in a given array.
X) The sub array that's already looked after.
2) Remaining sub array that's unsorted.
In every generation of choice sort, the minimal detail (thinking about ascending
order) from the unsorted sub array is picked and moved to the looked after sub
array.

Time Complexity
Time complexity of Selection Sort is O(n2) because of two nested loops.
Pseudocode
procedure selection sort
list : array of items
n : size of list

for i = 1 to n - 1
/* set current element as minimum*/
min = i

/* check the element to be minimum */

for j = i+1 to n
if list[j] < list[min] then
min = j;
end if
end for

/* swap the minimum element with the current element*/


if indexMin != i then
swap list[min] and list[i]
end if

[Type here]
4

end for

end procedure

ii- Heap Sort:


Heap type is a evaluation-based sorting method primarily based on
Binary Heap statistics shape. It is like selection sort in which we first
locate the most detail and place the most elements at the stop. We
repeat the identical technique for last detail.

Time Complexity:
Overall time complexity of Heap Sort is O(nLogn).
#include <iostream>

using namespace std;

void heapify(int arr[], int n, int i)


{
int largest = i;
int l = 2*i + 1;
int r = 2*i + 2;

// if left child is larger than root


if (l < n && arr[l] > arr[largest])
largest = l;

// if right child is larger than largest so far


if (r < n && arr[r] > arr[largest])
largest = r;

// if largest is not root


if (largest != i)
{
swap(arr[i], arr[largest]);
[Type here]
5

// recursively heapify the affected sub-tree


heapify(arr, n, largest);
}
}

void heapSort(int arr[], int n)


{
// build heap (rearrange array)
for (int i = n / 2 - 1; i >= 0; i--)
heapify(arr, n, i);

// one by one extract an element from heap


for (int i=n-1; i>=0; i--)
{
// move current root to end
swap(arr[0], arr[i]);

// call max heapify on the reduced heap


heapify(arr, i, 0);
}
}

/* function to print array of size n */


void printArray(int arr[], int n)
{
for (int i = 0; i < n; i++)
{
cout << arr[i] << " ";
}
cout << "\n";
}

int main()
[Type here]
6

{
int arr[] = {121, 10, 130, 57, 36, 17};
int n = sizeof(arr)/sizeof(arr[0]);

heapSort(arr, n);

cout << "Sorted array is \n";


printArray(arr, n);
}

iii- Counting Sort:


Counting sort is a sorting approach based on keys between a particular variety. It
works by way of counting the wide variety of items having distinct key values
(kind of hashing). Then doing some mathematics to calculate the placement of
each item within the output collection.

Time Complexity:
O(n+k) where n is the number of elements in input array and k is the range of
input.
// C++ Program for counting sort
#include<bits/stdc++.h>
#include<string.h>
using namespace std;
#define RANGE 255

// The main function that sort


// the given string arr[] in
// alphabatical order
void countSort(char arr[])

[Type here]
7

{
// The output character array
// that will have sorted arr
char output[strlen(arr)];

// Create a count array to store count of inidividul


// characters and initialize count array as 0
int count[RANGE + 1], i;
memset(count, 0, sizeof(count));

// Store count of each character


for(i = 0; arr[i]; ++i)
++count[arr[i]];

// Change count[i] so that count[i] now contains actual


// position of this character in output array
for (i = 1; i <= RANGE; ++i)
count[i] += count[i-1];

// Build the output character array


for (i = 0; arr[i]; ++i)
{
output[count[arr[i]]-1] = arr[i];
--count[arr[i]];

[Type here]
8

/*
For Stable algorithm
for (i = sizeof(arr)-1; i>=0; --i)
{
output[count[arr[i]]-1] = arr[i];
--count[arr[i]];
}

For Logic : See implementation


*/

// Copy the output array to arr, so that arr now


// contains sorted characters
for (i = 0; arr[i]; ++i)
arr[i] = output[i];
}

// Driver code
int main()
{
char arr[] = "geeksforgeeks";

[Type here]
9

countSort(arr);

cout<< "Sorted character array is " << arr;


return 0;
}

iv- Bucket Sort:


Bucket sort is in particular beneficial whilst input is uniformly dispensed
over a variety. For instance, remember the following trouble.

Sort a massive set of floating-factor numbers which might be in variety


from zero.Zero to at least one.Zero and are uniformly dispensed
throughout the range. How do we sort the numbers efficaciously?

A easy manner is to apply a assessment-primarily based sorting set of


rules. The lower sure for Comparison based totally sorting set of rules
(Merge Sort, Heap Sort, Quick-Sort .. Etc.) is Ω (n Log n), i.E., they can
not do higher than nLogn.

Can we type the array in linear time? Counting type can't be


implemented here as we use keys as index in counting kind. Here keys
are floating point numbers.
Time Complexity:
Time complexity of Bucket Sort Algorithm is O(n).
function bucketSort(array, k) is
buckets ← new array of k empty lists
M ← the maximum key value in the array
for i = 1 to length(array) do
insert array[i] into buckets[floor(k * array[i] / M)]
for i = 1 to k do
nextSort(buckets[i])
return the concatenation of buckets[1], ...., buckets[k]

[Type here]
10

v- Binary Insertion Sort:


We can use binary seek to lessen the variety of comparisons in
everyday insertion sort. Binary Insertion Sort makes use of binary search to
locate the proper location to insert the chosen item at each iteration.

In ordinary insertion kind, it takes O(n) comparisons (at nth


generation) in worst case. We can lessen it to O(log n) with the aid of the
use of binary search.
Time Complexity:
Worst case running time of binary insertion Sort is s O(n2).

// C program for implementation of binary insertion sort

#include <stdio.h>

// A binary search based function to find the position

// where item should be inserted in a[low..high]

int binarySearch(int a[], int item, int low, int high)

if (high <= low)

return (item > a[low])? (low + 1): low;

int mid = (low + high)/2;

if(item == a[mid])

return mid+1;

[Type here]
11

if(item > a[mid])

return binarySearch(a, item, mid+1, high);

return binarySearch(a, item, low, mid-1);

// Function to sort an array a[] of size 'n'

void insertionSort(int a[], int n)

int i, loc, j, k, selected;

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

j = i - 1;

selected = a[i];

// find location where selected sould be inseretd

loc = binarySearch(a, selected, 0, j);

// Move all elements after location to create space

while (j >= loc)

[Type here]
12

a[j+1] = a[j];

j--;

a[j+1] = selected;

// Driver program to test above function

int main()

int a[] = {37, 23, 0, 17, 12, 72, 31,

46, 100, 88, 54};

int n = sizeof(a)/sizeof(a[0]), i;

insertionSort(a, n);

printf("Sorted array: \n");

for (i = 0; i < n; i++)

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

[Type here]
13

return 0;

vi- Shell Sort:


ShellSort is especially a variant of Insertion Sort. In insertion kind, we
flow elements best one role in advance. When an detail should be moved
some distance beforehand, many moves are concerned. The concept of
shellSort is to allow alternate of a ways objects. In shellSort, we make the
array h-looked after for a massive value of h. We keep decreasing the fee
of h till it turns into 1. An array is said to be h-sorted if all sub lists of
every h’th detail is taken care of.
Time Complexity:
Time complexity of Shell sort is O(n2).
1. shellSort(array, size)
2. for interval i <- size/2n down to 1
3. for each interval "i" in array
4. sort all the elements at interval "i"
5. end shellSort

vii- Cycle Sort:


Cycle type is an in-location sorting Algorithm, volatile sorting algorithm, a
assessment sort that is theoretically foremost in phrases of the full variety of
writes to the unique array.
• It is superior in phrases of number of memory writes. It minimizes the
number of memory writes to kind (Each cost is both written 0 instances, if it’s
already in its correct role, or written one time to its correct position.)
• It is based on the idea that array to be sorted can be divided into cycles.
Cycles can be visualized as a graph. We have n nodes and an side directed
from node I to node j if the detail at i-th index need to be present at j-th
index inside the looked after array.
Cycle in arr [] = 2, 4, five, 1, 3
• We separately don't forget all cycles. We first take into account the cycle
that includes first element. We locate correct role of first element, vicinity it
at its accurate role, say j. We bear in mind antique fee of arr[j] and locate its
accurate function, we hold doing this till all elements of cutting-edge cycle

[Type here]
14

are located at accurate position, i.E., we don’t come again to cycle starting
point.
Time Complexity:
Time complexity of Cycle Sort is O(n2).

// C++ program to implement cycle sort


#include <iostream>
using namespace std;

// Function sort the array using Cycle sort


void cycleSort(int arr[], int n)
{
// count number of memory writes
int writes = 0;

// traverse array elements and put it to on


// the right place
for (int cycle_start = 0; cycle_start <= n - 2; cycle_start++) {
// initialize item as starting point
int item = arr[cycle_start];

// Find position where we put the item. We basically


// count all smaller elements on right side of item.
int pos = cycle_start;
for (int i = cycle_start + 1; i < n; i++)
if (arr[i] < item)
pos++;

// If item is already in correct position


if (pos == cycle_start)
continue;

// ignore all duplicate elements


while (item == arr[pos])
pos += 1;

// put the item to it's right position

[Type here]
15

if (pos != cycle_start) {
swap(item, arr[pos]);
writes++;
}

// Rotate rest of the cycle


while (pos != cycle_start) {
pos = cycle_start;

// Find position where we put the element


for (int i = cycle_start + 1; i < n; i++)
if (arr[i] < item)
pos += 1;

// ignore all duplicate elements


while (item == arr[pos])
pos += 1;

// put the item to it's right position


if (item != arr[pos]) {
swap(item, arr[pos]);
writes++;
}
}
}

// Number of memory writes or swaps


// cout << writes << endl ;
}

// Driver program to test above function


int main()
{
int arr[] = { 1, 8, 3, 9, 10, 10, 2, 4 };
int n = sizeof(arr) / sizeof(arr[0]);
cycleSort(arr, n);

[Type here]
16

cout << "After sort : " << endl;


for (int i = 0; i < n; i++)
cout << arr[i] << " ";
return 0;
}

viii- Brick Sort:


This is essentially a variant of bubble-kind. This algorithm is dividedinto stages-
Odd and Even Phase. The algorithm runs till the array elements are looked after
and in every new release two levels happens- Odd and Even Phases.In the unusual
phase, we perform a bubble sort on strange indexed elements and inside the
even section, we perform a bubble kind on even listed factors.
Time Complexity:
O(N2) where, N = Number of elements in the input array.

// A C++ Program to implement Odd-Even / Brick Sort


#include<bits/stdc++.h>
using namespace std;

// A function to sort the algorithm using Odd Even sort


void oddEvenSort(int arr[], int n)
{
bool isSorted = false; // Initially array is unsorted

while (!isSorted)
{
isSorted = true;

// Perform Bubble sort on odd indexed element


for (int i=1; i<=n-2; i=i+2)
{
if (arr[i] > arr[i+1])
{
swap(arr[i], arr[i+1]);
isSorted = false;
}

[Type here]
17

// Perform Bubble sort on even indexed element


for (int i=0; i<=n-2; i=i+2)
{
if (arr[i] > arr[i+1])
{
swap(arr[i], arr[i+1]);
isSorted = false;
}
}
}

return;
}

// A utility function ot print an array of size n


void printArray(int arr[], int n)
{
for (int i=0; i < n; i++)
cout << arr[i] << " ";
cout << "\n";
}

// Driver program to test above functions.


int main()
{
int arr[] = {34, 2, 10, -9};
int n = sizeof(arr)/sizeof(arr[0]);

oddEvenSort(arr, n);
printArray(arr, n);

return (0);
}

[Type here]
18

ix- CartesianTree Sorting:


Cartesian Sort is an Adaptive Sorting as it types the facts quicker if data is in part
taken care of. In reality, there are only a few sorting algorithms that employ this
truth.

Below are steps used for sorting.


Step 1 : Build a (min-heap) Cartesian Tree from the given enter sequence.
Step 2: Starting from the foundation of the constructed Cartesian Tree, we push
the nodes in a concern queue.
Then we pop the node on the pinnacle of the concern queue and push the kids
of the popped node inside the precedence queue in a pre-order way.
1. Pop the node at the pinnacle of the concern queue and add it to a
listing.
2. Push left infant of the popped node first (if present).
3. Push proper child of the popped node next (if gift).
Time Complexity:
Time complexity of Cartesian tree sorting is O(n).

// A C++ program to implement Cartesian Tree sort


// Note that in this program we will build a min-heap
// Cartesian Tree and not max-heap.
#include<bits/stdc++.h>
using namespace std;

/* A binary tree node has data, pointer to left child


and a pointer to right child */
struct Node
{
int data;
Node *left, *right;
};

// Creating a shortcut for int, Node* pair type


typedef pair<int, Node*> iNPair;

// This function sorts by pushing and popping the

[Type here]
19

// Cartesian Tree nodes in a pre-order like fashion


void pQBasedTraversal(Node* root)
{
// We will use a priority queue to sort the
// partially-sorted data efficiently.
// Unlike Heap, Cartesian tree makes use of
// the fact that the data is partially sorted
priority_queue <iNPair, vector<iNPair>, greater<iNPair>> pQueue;
pQueue.push (make_pair (root->data,root));

// Resembles a pre-order traverse as first data


// is printed then the left and then right child.
while (! pQueue.empty())
{
iNPair popped_pair = pQueue.top();
printf("%d ",popped_pair.first);

pQueue.pop();

if (popped_pair.second->left != NULL)
pQueue.push (make_pair(popped_pair.second->left-
>data,
popped_pair.second-
>left));

if (popped_pair.second->right != NULL)
pQueue.push (make_pair(popped_pair.second->right-
>data,

popped_pair.second->right));
}

return;
}

Node *buildCartesianTreeUtil(int root, int arr[],

[Type here]
20

int parent[], int leftchild[], int rightchild[])


{
if (root == -1)
return NULL;

Node *temp = new Node;

temp->data = arr[root];
temp->left = buildCartesianTreeUtil(leftchild[root],
arr, parent, leftchild, rightchild);

temp->right = buildCartesianTreeUtil(rightchild[root],
arr, parent, leftchild, rightchild);

return temp ;
}

// A function to create the Cartesian Tree in O(N) time


Node *buildCartesianTree(int arr[], int n)
{
// Arrays to hold the index of parent, left-child,
// right-child of each number in the input array
int parent[n],leftchild[n],rightchild[n];

// Initialize all array values as -1


memset(parent, -1, sizeof(parent));
memset(leftchild, -1, sizeof(leftchild));
memset(rightchild, -1, sizeof(rightchild));

// 'root' and 'last' stores the index of the root and the
// last processed of the Cartesian Tree.
// Initially we take root of the Cartesian Tree as the
// first element of the input array. This can change
// according to the algorithm
int root = 0, last;

// Starting from the second element of the input array

[Type here]
21

// to the last on scan across the elements, adding them


// one at a time.
for (int i=1; i<=n-1; i++)
{
last = i-1;
rightchild[i] = -1;

// Scan upward from the node's parent up to


// the root of the tree until a node is found
// whose value is smaller than the current one
// This is the same as Step 2 mentioned in the
// algorithm
while (arr[last] >= arr[i] && last != root)
last = parent[last];

// arr[i] is the smallest element yet; make it


// new root
if (arr[last] >= arr[i])
{
parent[root] = i;
leftchild[i] = root;
root = i;
}

// Just insert it
else if (rightchild[last] == -1)
{
rightchild[last] = i;
parent[i] = last;
leftchild[i] = -1;
}

// Reconfigure links
else
{
parent[rightchild[last]] = i;
leftchild[i] = rightchild[last];

[Type here]
22

rightchild[last]= i;
parent[i] = last;
}

// Since the root of the Cartesian Tree has no


// parent, so we assign it -1
parent[root] = -1;

return (buildCartesianTreeUtil (root, arr, parent,


leftchild,
rightchild));
}

// Sorts an input array


int printSortedArr(int arr[], int n)
{
// Build a cartesian tree
Node *root = buildCartesianTree(arr, n);

printf("The sorted array is-\n");

// Do pr-order traversal and insert


// in priority queue
pQBasedTraversal(root);
}

/* Driver program to test above functions */


int main()
{
/* Given input array- {5,10,40,30,28},
it's corresponding unique Cartesian Tree
is-

5
\

[Type here]
23

10
\
28
/
30
/
40
*/

int arr[] = {5, 10, 40, 30, 28};


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

printSortedArr(arr, n);

return(0);
}

X_) Radix Sort:


Do following for every digit I where I range from least widespread digit to the
most widespread digit.
Sort input array the usage of counting kind (or any strong sort) consistent with the
i’th digit.
Time Complexity:
Time complexity of Radix Sort is O(n).
// C++ implementation of Radix Sort
#include<iostream>
using namespace std;

// A utility function to get maximum value in arr[]


int getMax(int arr[], int n)
{
int mx = arr[0];
for (int i = 1; i < n; i++)
if (arr[i] > mx)
mx = arr[i];
return mx;
}

[Type here]
24

// A function to do counting sort of arr[] according to


// the digit represented by exp.
void countSort(int arr[], int n, int exp)
{
int output[n]; // output array
int i, count[10] = {0};

// Store count of occurrences in count[]


for (i = 0; i < n; i++)
count[ (arr[i]/exp)%10 ]++;

// Change count[i] so that count[i] now contains actual


// position of this digit in output[]
for (i = 1; i < 10; i++)
count[i] += count[i - 1];

// Build the output array


for (i = n - 1; i >= 0; i--)
{
output[count[ (arr[i]/exp)%10 ] - 1] = arr[i];
count[ (arr[i]/exp)%10 ]--;
}

// Copy the output array to arr[], so that arr[] now


// contains sorted numbers according to current digit
for (i = 0; i < n; i++)
arr[i] = output[i];
}

// The main function to that sorts arr[] of size n using


// Radix Sort
void radixsort(int arr[], int n)
{
// Find the maximum number to know number of digits
int m = getMax(arr, n);

[Type here]
25

// Do counting sort for every digit. Note that instead


// of passing digit number, exp is passed. exp is 10^i
// where i is current digit number
for (int exp = 1; m/exp > 0; exp *= 10)
countSort(arr, n, exp);
}

// A utility function to print an array


void print(int arr[], int n)
{
for (int i = 0; i < n; i++)
cout << arr[i] << " ";
}

// Driver program to test above functions


int main()
{
int arr[] = {170, 45, 75, 90, 802, 24, 2, 66};
int n = sizeof(arr)/sizeof(arr[0]);
radixsort(arr, n);
print(arr, n);
return 0;
}

Searching Algorithm
Fibonacci Algorithm:
Let the searched element be x.
The idea is to first locate the smallest Fibonacci range that is extra than or equal
to the period of given array. Let the discovered Fibonacci variety be fib (m’th
Fibonacci range). We use (m-2)’th Fibonacci variety as the index (If it is a
legitimate index). Let (m-2)’th Fibonacci Number be I, we examine arr[i] with x, if
x is equal, we go back i. Else if x is more, we recur for subarray after i, else we
recur for subarray earlier than i.
Below is the entire algorithm
Let arr [0..N-1] be the input array and element to be searched be x.
1. Find the smallest Fibonacci Number extra than or identical to n. Let this
variety be fibM [m’th Fibonacci Number]. Let the 2 Fibonacci numbers preceding
[Type here]
26

or not it's fibMm1 [(m-1)’th Fibonacci Number] and fibMm2 [(m-2)’th Fibonacci
Number].
2. While the array has factors to be inspected:
1. Compare x with the closing detail of the range included by way of
fibMm2
2. If x suits, return index
3. Else If x is much less than the detail, circulate the three Fibonacci
variables two Fibonacci down, indicating removal of about rear -third of the
last array.
4. Else x is greater than the element, move the 3 Fibonacci variables
one Fibonacci down. Reset offset to index. Together those indicate removal
of approximately the front one-1/3 of the last array.
3. Since there might be a single element last for comparison, check if fibMm1
is 1. If Yes, examine x with that remaining detail. If in shape, return index.

//Fibonacci Series using Recursion


#include<bits/stdc++.h>
using namespace std;

int fib(int n)
{
if (n <= 1)
return n;
return fib(n-1) + fib(n-2);
}

int main ()
{
int n = 9;
cout << fib(n);
getchar();
return 0;
}

[Type here]
27

Jump Search:
Like Binary Search, Jump Search is a looking set of rules for looked after arrays.
The basic concept is to test fewer factors (than linear seek) via jumping ahead by
way of constant steps or skipping a few factors in place of looking all factors.
For example, assume we've an array arr[] of length n and block (to be jumped)
length m. Then we search at the indexes arr[0], arr[m], arr[2m]…..Arr[km] and so
forth. Once we discover the interval (arr[km] < x < arr[(k+1)m]), we carry out a
linear search operation from the index km to find the detail x.
Let’s don't forget the following array: (0, 1, 1, 2, three, five, eight, 13, 21, 34, 55,
89, one hundred forty four, 233, 377, 610). Length of the array is sixteen. Jump
seek will find the value of fifty five with the following steps assuming that the
block size to be jumped is four.
STEP 1: Jump from index zero to index 4;
STEP 2: Jump from index 4 to index eight;
STEP three: Jump from index eight to index 12;
STEP four: Since the detail at index 12 is more than 55 we are able to bounce back
a step to come to index eight.
STEP 5: Perform linear seek from index eight to get the detail fifty five.
// C++ program to implement Jump Search

#include <bits/stdc++.h>
using namespace std;

int jumpSearch(int arr[], int x, int n)


{
// Finding block size to be jumped
int step = sqrt(n);

// Finding the block where element is

[Type here]
28

// present (if it is present)


int prev = 0;
while (arr[min(step, n)-1] < x)
{
prev = step;
step += sqrt(n);
if (prev >= n)
return -1;
}

// Doing a linear search for x in block


// beginning with prev.
while (arr[prev] < x)
{
prev++;

// If we reached next block or end of


// array, element is not present.
if (prev == min(step, n))
return -1;
}
// If element is found
if (arr[prev] == x)
return prev;

return -1;

[Type here]
29

// Driver program to test function


int main()
{
int arr[] = { 0, 1, 1, 2, 3, 5, 8, 13, 21,
34, 55, 89, 144, 233, 377, 610 };
int x = 55;
int n = sizeof(arr) / sizeof(arr[0]);

// Find the index of 'x' using Jump Search


int index = jumpSearch(arr, x, n);

// Print the index where 'x' is located


cout << "\nNumber " << x << " is at index " << index;
return 0;
}

Interpolation Search:
Given a looked after array of n uniformly dispensed values arr[], write a function
to look for a selected detail x inside the array.
Linear Search finds the element in O(n) time, Jump Search takes O(√ n) time and
Binary Search take O(Log n) time.
The Interpolation Search is an development over Binary Search for instances,
wherein the values in a sorted array are uniformly disbursed. Binary Search
usually goes to the center element to check. On the alternative hand,
interpolation search may match to one-of-a-kind locations in line with the fee of
the important thing being searched. For instance, if the value of the secret's

[Type here]
30

closer to the remaining detail, interpolation search is in all likelihood to begin


seek closer to the end facet.
Rest of the Interpolation set of rules is the identical besides the above partition
logic.
Step1: In a loop, calculate the price of “pos” the usage of the probe position
formula.
Step2: If it is a match, go back the index of the object, and exit.
Step3: If the item is less than arr[pos], calculate the probe role of the left sub-
array. Otherwise calculate the equal in the right sub-array.
Step4: Repeat till a match is observed or the sub-array reduces to 0.

// C++ program to implement interpolation search


#include<bits/stdc++.h>
using namespace std;

// If x is present in arr[0..n-1], then returns


// index of it, else returns -1.
int interpolationSearch(int arr[], int n, int x)
{
// Find indexes of two corners
int lo = 0, hi = (n - 1);

// Since array is sorted, an element present


// in array must be in range defined by corner
while (lo <= hi && x >= arr[lo] && x <= arr[hi])
{
if (lo == hi)
{
if (arr[lo] == x) return lo;
return -1;
}
// Probing the position with keeping
// uniform distribution in mind.
int pos = lo + (((double)(hi - lo) /
(arr[hi] - arr[lo])) * (x - arr[lo]));

// Condition of target found

[Type here]
31

if (arr[pos] == x)
return pos;

// If x is larger, x is in upper part


if (arr[pos] < x)
lo = pos + 1;

// If x is smaller, x is in the lower part


else
hi = pos - 1;
}
return -1;
}

// Driver Code
int main()
{
// Array of items on which search will
// be conducted.
int arr[] = {10, 12, 13, 16, 18, 19, 20, 21,
22, 23, 24, 33, 35, 42, 47};
int n = sizeof(arr)/sizeof(arr[0]);

int x = 18; // Element to be searched


int index = interpolationSearch(arr, n, x);

// If element was found


if (index != -1)
cout << "Element found at index " << index;
else
cout << "Element not found.";
return 0;
}

Exponential Search:
The name of this searching set of rules may be deceptive because it works in
O(Log n) time. The call comes from the manner it searches an element.

[Type here]
32

The concept is to start with subarray size 1, examine its closing element with x,
then try size 2, then four and so on till last element of a subarray is not extra.
Once we find an index i (after repeated doubling of i), we recognise that the detail
have to be present between i/2 and i (Why i/2? Because we could not find a
greater cost in previous iteration)
Time Complexity:
O(log n)
// C++ program to find an element x in a
// sorted array using Exponential search.
#include <bits/stdc++.h>
using namespace std;

int binarySearch(int arr[], int, int, int);

// Returns position of first occurrence of


// x in array
int exponentialSearch(int arr[], int n, int x)
{
// If x is present at firt location itself
if (arr[0] == x)
return 0;

// Find range for binary search by


// repeated doubling
int i = 1;
while (i < n && arr[i] <= x)
i = i*2;

// Call binary search for the found range.


return binarySearch(arr, i/2, min(i, n), x);
}

// A recursive binary search function. It returns


// location of x in given array arr[l..r] is
// present, otherwise -1
int binarySearch(int arr[], int l, int r, int x)
{

[Type here]
33

if (r >= l)
{
int mid = l + (r - l)/2;

// If the element is present at the middle


// itself
if (arr[mid] == x)
return mid;

// If element is smaller than mid, then it


// can only be present n left subarray
if (arr[mid] > x)
return binarySearch(arr, l, mid-1, x);

// Else the element can only be present


// in right subarray
return binarySearch(arr, mid+1, r, x);
}

// We reach here when element is not present


// in array
return -1;
}

// Driver code
int main(void)
{
int arr[] = {2, 3, 4, 10, 40};
int n = sizeof(arr)/ sizeof(arr[0]);
int x = 10;
int result = exponentialSearch(arr, n, x);
(result == -1)? printf("Element is not present in array")
: printf("Element is present at index %d",

result);
return 0;
}

[Type here]
34

Sub List Search:


Take first node of second listing.
Start matching the first list from this first node.
If whole lists suit return real.
Else smash and take first listing to the primary node once more.
And take 2nd listing to its 2nd node.
Repeat these steps until any of related lists turns into empty.
If first list becomes empty then listing observed else now not.

Divide and Conquer

Closest Pair of Point:


The trouble is to discover the closest pair of points in a fixed of points in x-y
aircraft. The hassle may be solved in O(n^2) time by means of calculating
distances of every pair of points and comparing the distances to find the
minimum. The Divide and Conquer set of rules clear up the problem in O(nLogn)
time.
// A divide and conquer program in C++
// to find the smallest distance from a
// given set of points.

#include <bits/stdc++.h>
using namespace std;

// A structure to represent a Point in 2D plane


class Point
{
public:

[Type here]
35

int x, y;
};

/* Following two functions are needed for library function qsort().


Refer: http://www.cplusplus.com/reference/clibrary/cstdlib/qsort/ */

// Needed to sort array of points


// according to X coordinate
int compareX(const void* a, const void* b)
{
Point *p1 = (Point *)a, *p2 = (Point *)b;
return (p1->x - p2->x);
}

// Needed to sort array of points according to Y coordinate


int compareY(const void* a, const void* b)
{
Point *p1 = (Point *)a, *p2 = (Point *)b;
return (p1->y - p2->y);
}

// A utility function to find the


// distance between two points
float dist(Point p1, Point p2)
{
return sqrt( (p1.x - p2.x)*(p1.x - p2.x) +
(p1.y - p2.y)*(p1.y - p2.y)
);
}

// A Brute Force method to return the


// smallest distance between two points
// in P[] of size n
float bruteForce(Point P[], int n)
{
float min = FLT_MAX;
for (int i = 0; i < n; ++i)

[Type here]
36

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


if (dist(P[i], P[j]) < min)
min = dist(P[i], P[j]);
return min;
}

// A utility function to find


// minimum of two float values
float min(float x, float y)
{
return (x < y)? x : y;
}

// A utility function to find the


// distance beween the closest points of
// strip of given size. All points in
// strip[] are sorted accordint to
// y coordinate. They all have an upper
// bound on minimum distance as d.
// Note that this method seems to be
// a O(n^2) method, but it's a O(n)
// method as the inner loop runs at most 6 times
float stripClosest(Point strip[], int size, float d)
{
float min = d; // Initialize the minimum distance as d

qsort(strip, size, sizeof(Point), compareY);

// Pick all points one by one and try the next points till the difference
// between y coordinates is smaller than d.
// This is a proven fact that this loop runs at most 6 times
for (int i = 0; i < size; ++i)
for (int j = i+1; j < size && (strip[j].y - strip[i].y) < min; ++j)
if (dist(strip[i],strip[j]) < min)
min = dist(strip[i], strip[j]);

[Type here]
37

return min;
}

// A recursive function to find the


// smallest distance. The array P contains
// all points sorted according to x coordinate
float closestUtil(Point P[], int n)
{
// If there are 2 or 3 points, then use brute force
if (n <= 3)
return bruteForce(P, n);

// Find the middle point


int mid = n/2;
Point midPoint = P[mid];

// Consider the vertical line passing


// through the middle point calculate
// the smallest distance dl on left
// of middle point and dr on right side
float dl = closestUtil(P, mid);
float dr = closestUtil(P + mid, n - mid);

// Find the smaller of two distances


float d = min(dl, dr);

// Build an array strip[] that contains


// points close (closer than d)
// to the line passing through the middle point
Point strip[n];
int j = 0;
for (int i = 0; i < n; i++)
if (abs(P[i].x - midPoint.x) < d)
strip[j] = P[i], j++;

// Find the closest points in strip.


// Return the minimum of d and closest

[Type here]
38

// distance is strip[]
return min(d, stripClosest(strip, j, d) );
}

// The main function that finds the smallest distance


// This method mainly uses closestUtil()
float closest(Point P[], int n)
{
qsort(P, n, sizeof(Point), compareX);

// Use recursive function closestUtil()


// to find the smallest distance
return closestUtil(P, n);
}

// Driver code
int main()
{
Point P[] = {{2, 3}, {12, 30}, {40, 50}, {5, 1}, {12, 10}, {3, 4}};
int n = sizeof(P) / sizeof(P[0]);
cout << "The smallest distance is " << closest(P, n);
return 0;
}

FFT Algorithm:
Cooley–Tukey Fast Fourier Transform (FFT) algorithm is the most not unusual set
of rules for FFT. It is a divide and conquer set of rules which goes in O(nlogn) time.
import numpy as np
def DFT_slow(x):
"""Compute the discrete Fourier Transform of the 1D array x"""
x = np.asarray(x, dtype=float)
N = x.shape[0]
n = np.arange(N)
k = n.reshape((N, 1))
M = np.exp(-2j * np.pi * k * n / N)
return np.dot(M, x)

[Type here]
39

5.DYNAMIC PROGRAMMING

5.1 Friends Pairing Problem


Given n companions, every one can stay single or can be combined up with
some other companion. Every companion can be matched just once.
Discover the all out number of manners by which companions can stay
single or can be matched up. f(n) = ways n people can remain single

or pair up.

For n-th person there are two choices:

1) n-th person remains single, we recur

for f(n - 1)

2) n-th person pairs up with any of the

remaining n - 1 persons. We get (n - 1) * f(n - 2)

Therefore we can recursively write f(n) as:

f(n) = f(n - 1) + (n - 1) * f(n - 2)


So this recursive formula can be used as dynamic programming.

Time Complexity : O(n)

// C++ program for solution of


// friends pairing problem
#include <bits/stdc++.h>
using namespace std;

// Returns count of ways n people


// can remain single or paired up.

[Type here]
40

int countFriendsPairings(int n)
{
int dp[n + 1];

// Filling dp[] in bottom-up manner using


// recursive formula explained above.
for (int i = 0; i <= n; i++) {
if (i <= 2)
dp[i] = i;
else
dp[i] = dp[i - 1] + (i - 1) * dp[i - 2];
}

return dp[n];
}

// Driver code
int main()
{
int n = 4;
cout << countFriendsPairings(n) << endl;
return 0;
}
5.2 Tiling Problem
Given a “2 x n” board and tiles of size “2 x 1”, count the
number of ways to tile the given board using the 2 x 1 tiles. A tile can
either be placed horizontally i.e., as a 1 x 2 tile or vertically i.e., as 2 x
1 tile.

Let “count(n)” be the count of ways to place tiles on a “2 x n” grid,


we have following two ways to place first tile.

1) If we place first tile vertically, the problem reduces to “count(n-1)”

2) If we place first tile horizontally, we have to place second tile also


horizontally. So the problem reduces to “count(n-2)”

Therefore, count(n) can be written as below.

[Type here]
41

count(n) = n if n = 1 or n = 2

count(n) = count(n-1) + count(n-2)

[Type here]

You might also like