You are on page 1of 22

BCSE 204L

DESIGN AND ANALYSIS OF ALGORITHMS

NAME: AAROHI MISHRA


REGISTER NUMBER: 21BCE5303
SCHOOL: SCOPE (SCHOOL OF COMPUTER SCIENCE AND
ENGINEERING)

DIGITAL ASSIGNMENT 1

1. Inputs required from the theory:

(a) Pseudocode of Insertion sort

procedure insertionSort(A: list of sortable items)


n = length(A)
for i = 1 to n - 1 do
j=i
while j > 0 and A[j-1] > A[j] do
swap(A[j], A[j-1])
j=j-1
end while
end for
end procedure

(b) T(n) of the insertion-sort

(c) Best-case, worst-case and average-case time-


complexity of the algorithm

• Worst case time complexity: O(n2)


• Average case time complexity: O(n2)
• Best case time complexity: O(n)

2. Design related problems

(a) Translate the Insertion-sort algorithm discussed in the


class into a program which takes n numbers (real or
integers). Inputs for the program is n and the n numbers.
CODE:
#include<iostream>
#include<vector>
using namespace std;
int main()
{
vector<int> elements(20,0);
int key,i,j,n;
//cout<<"Enter number of elements";
cin>>n;
for(i=0;i<n;i++)
cin>>elements[i];

for(j=1;j<n;j++)
{
key = elements[j];
i = j-1;
while((i>=0)&&(elements[i]>key))
{
elements[i+1] = elements[i];
i = i-1;
}
elements[i+1] = key;
}

for(i=0;i<n;i++)
{
cout<<elements[i]<<" ";
}
}

OUTPUT:

TABLE AND GRAPH:


(b) Given a sequence of n numbers (real or integers) and a
number k (k is one among the n numbers), write an
algorithm and the corresponding code to compute the
position of k if the given n numbers are arranged in an
increasing order, using insertion sort. If the 2, −1, 3, 0, 7
and 3 are the input, your program should output 4 since 3
will be in the fourth position (starting from 1), in the
sorted (increasing) order. You are expected to code the
problem two different ways, say, c1, c2 using two
different approaches. Decide whether c1 is efficient or c2
is efficient based on the running time T(n) of the
respective codes.

CODE:

APPROACH 1
#include <iostream>
#include <ctime>
using namespace std;

void LinearInsertionSort(int a[], int n)


{
int i, loc, j, k, selected;

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


{
j = i - 1;
selected = a[i];
loc = LinearSearch(a, selected, 0, j);

while (j >= loc)


{
a[j+1] = a[j];
j--;
}
a[j+1] = selected;
}
}

int main()
{
int a[] = {2,-1,3,0,7,3};
int n = sizeof(a)/sizeof(a[0]);

clock_t tStart = clock();

LinearInsertionSort(a, n);

double time1=(double)(clock() - tStart)/CLOCKS_PER_SEC;


cout<<"Time taken is "<<time1<<endl;

int n1=3;
cout << "Sorted array: \n";
for (int i = 0; i < n; i++)
cout << a[i] << " ";
cout<<"\n";
for(int i=0;i<n;i++)
{
if(a[i]==n1)
{ cout<<"Position of the element to be searched:
"<<i+1<<"\n";
break;
}
}
return 0;
}

APPROACH 2
#include <iostream>
#include <ctime>
using namespace std;

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;

if(item > a[mid])


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

void binaryInsertionSort(int a[], int n)


{
int i, loc, j, k, selected;

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


{
j = i - 1;
selected = a[i];

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

while (j >= loc)


{
a[j+1] = a[j];
j--;
}
a[j+1] = selected;
}
}

int main()
{
int a[] = {2,-1,3,0,7,3};
int n = sizeof(a)/sizeof(a[0]);

clock_t tStart = clock();

binaryInsertionSort(a, n);
int n1=3;

double time1=(double)(clock() - tStart)/CLOCKS_PER_SEC;


cout<<"Time taken is "<<time1<<endl;

cout << "Sorted array: \n";


for (int i = 0; i < n; i++)
cout << a[i] << " ";
cout<<"\n";

int c=binarySearch(a,n1,0,n);
cout<<"Position of the element to be searched: "<<c+1<<"\n";
return 0;
}
OUTPUT:

TABLE AND GRAPH:

EXPLANATION: Binary insertion sort employs a binary search to


determine the correct location to insert new elements, and therefore
performs ⌈log2(n)⌉ comparisons in the worst case, which is O(n log
n). Although Binary Search reduces the number of comparisons to in
the worst case, Binary Insertion Sort has a quadratic time complexity
just as Insertion Sort. Still, it is usually faster than Insertion Sort in
practice, which is apparent when comparison takes significantly more
time than swapping two elements.

Hence, approach 2 is better than one.

(c) All the alphabets (lower case) of English language a, b,


c, ..., y, z is assigned values 1, 2, 3, ..., 25, 26. Given a
sequence of n symbols from English alphabet (only lower
case), write a 2 insertion-sort based algorithm to arrange
the given n symbols, in an increasing order of their
values. You are expected to code the problem two
different ways, say, c1 , c2 using two different
approaches. Decide whether c1 is efficient or c2 is
efficient based on the running time T(n) of the respective
code.

CODE:

APPROACH 1

#include <iostream>
#include <vector>
#include <ctime>
using namespace std;

void insertionSort(vector<char> &input) {


vector<char> output;
for (char c : input) {
int i = 0;
while (i < output.size() && c - 'a' + 1 > output[i] - 'a' + 1) {
i++;
}
output.insert(output.begin() + i, c);
}
input = output;
}

int main() {
int n;
cin>>n;
char ip;
vector<char> input;
for(int i=0;i<n;i++)
{
cin>>ip;
input.push_back(ip);
}

clock_t tStart = clock();

insertionSort(input);
double time1=(double)(clock() - tStart)/CLOCKS_PER_SEC;
cout<<"Time taken is "<<time1<<endl;

for (char c : input) {


cout << c << " ";
}
return 0;
}

APPROACH 2
#include <iostream>
#include <vector>
using namespace std;

void insertionSort(vector<char> &input) {


for (int i = 1; i < input.size(); i++) {
char key = input[i];
int j = i - 1;
while (j >= 0 && input[j] - 'a' + 1 > key - 'a' + 1) {
input[j + 1] = input[j];
j--;
}
input[j + 1] = key;
}
}
int main() {
int n;
cin>>n;
char ip;
vector<char> input;
for(int i=0;i<n;i++)
{
cin>>ip;
input.push_back(ip);
}

clock_t tStart = clock();

insertionSort(input);

double time1=(double)(clock() - tStart)/CLOCKS_PER_SEC;


cout<<"Time taken is "<<time1<<endl;

for (char c : input) {


cout << c << " ";
}
return 0;
}
OUTPUT:

TABLE AND GRAPH:

EXPLANATION:

Both approach have the same time complexity O(n^2) but method 1
uses extra memory to store the output sequence. So method 2 is
more efficient in terms of memory usage but the choice between
them depends on the specific use case.

(d) Given a sequence of n numbers (real or integers), write


an algorithm and the corresponding code to arrange the
given n numbers are arranged in such a way that all the
negative numbers (if any) are arranged in a descending
order and all the positive numbers are arranged in an
increasing order with zero (if it is in the input) appearing
between the smallest negative number and the smallest
positive number. If 7, 3, 2, 4 the output should be 2, 3, 4,
7. If −7, −3, 2, 4 the output should be −3, −7, 2, 4 should
be the output. If 7, 3, −1, 0, 2, 4 the output should be −1,
0, 3, 4, 7.

CODE:
#include <iostream>
#include <ctime>
using namespace std;

int *insertionSort(int *arr, int size) {


int negCount = 0;
for (int i = 0; i < size; i++)
{
for (int j = 0; j < size - 1; j++)
{
if (*(arr + j) > *(arr + j + 1))
{
if (*(arr + j) < 0)
{
negCount++;
}
int temp = *(arr + j);
*(arr + j) = *(arr + j + 1);
*(arr + j + 1) = temp;
}
}
}

int i = 0;
while (negCount > 0)
{
int temp = *(arr + i);
*(arr + i) = *(arr + negCount);
*(arr + negCount) = temp;
negCount--;
i++;
}

return arr;
}
int main()
{
int n;
cin>>n;
int arr[n];
for(int i=0;i<n;i++)
{
cin>>arr[i];
}

clock_t tStart = clock();

insertionSort(arr, n);

double time1=(double)(clock() - tStart)/CLOCKS_PER_SEC;


cout<<"Time taken is "<<time1<<endl;

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

OUTPUT:
TABLE AND GRAPH:

(e) Given n points P1, P2, ..., Pn with the coordinates (x1,
y1),(x2, y2), ...,(xn, yn) respectively, write an insertion-
sort based algorithm and the corresponding code to
arrange the points in an increasing order of the distance
of the point from the origin (with (0, 0) as the coordinates.
Distance between any two points (a1, b1) and (a2, b2) is p
(a1 − a2) 2 + (b1 − b2) 2 . Input for the code is : n and the
coordinates of the n points entered with x−coordinate
first and then the y−coordinate.

CODE:

#include <iostream>
#include <cmath>
#include <ctime>
using namespace std;
struct Point {
int x, y;
double distance;
};

void insertionSort(Point arr[], int n) {


for (int i = 1; i < n; i++) {
Point key = arr[i];
int j = i - 1;
while (j >= 0 && arr[j].distance > key.distance) {
arr[j + 1] = arr[j];
j--;
}
arr[j + 1] = key;
}
}

double calculateDistance(int x, int y) {


return sqrt(x * x + y * y);
}

int main() {
int n;
cout << "Enter the number of points: ";
cin >> n;
Point points[n];

cout << "Enter the coordinates of the points:" << endl;


for (int i = 0; i < n; i++) {
cin >> points[i].x >> points[i].y;
points[i].distance = calculateDistance(points[i].x, points[i].y);
}

clock_t tStart = clock();

insertionSort(points, n);

double time1=(double)(clock() - tStart)/CLOCKS_PER_SEC;


cout<<"Time taken is "<<time1<<endl;

cout << "Points in increasing order of distance from the origin:" <<
endl;
for (int i = 0; i < n; i++) {
cout << "(" << points[i].x << ", " << points[i].y << ")" << endl;
}

return 0;
}
OUTPUT:

TABLE AND GRAPH:

You might also like