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

Maham Dsa 1

The document provides code and explanations for bubble sort, selection sort, insertion sort, merge sort, and quick sort algorithms. It includes C++ code for each sorting algorithm, a dry run example showing the steps for sorting a sample array of 4 elements, advantages and disadvantages of each algorithm, and a comparison of the algorithms.

Uploaded by

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

Maham Dsa 1

The document provides code and explanations for bubble sort, selection sort, insertion sort, merge sort, and quick sort algorithms. It includes C++ code for each sorting algorithm, a dry run example showing the steps for sorting a sample array of 4 elements, advantages and disadvantages of each algorithm, and a comparison of the algorithms.

Uploaded by

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

DR ABDUL QADEER KHAN INSTITUTE OF COMPUTER

SCIENCE AND INFORMATION TECHNOLOGY

Data Structure & Algorithm

SUBMITTED BY: Maham Fatima

CLASS: BSCS-3

REGISTRATION No.222201002

SUBMITTED TO:

MADAM RIDA BAJWA

Question no. 1) Make a report on bubble sort, selection sort, insertion sort, merge sort and quick
sort algorithms. The report must include
C++ code of sorting algorithm
Dry run of sorting algorithms for an array (n=4)
Advantages and disadvantages of sorting algorithms
Comparison of sorting algorithms

BUBBLE SORT:

Code:

#include<iostream>

using namespace std;

//ascending order

void bubble_sort(int *arr,int size)

{int temp;

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

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

if(arr[i]>arr[j])

temp=arr[i];

arr[i]=arr[j];

arr[j]=temp;}}}}

int main()

int *arr , size ;

cout << " Enter size of array : " ;

cin >> size ;

arr = new int[size] ;

cout<<" Enter "<<size<<" elements of array: \n";

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

cin>>arr[i];

bubble_sort(arr,size);

cout<<" \n\t\t---> SORTED ARRAY <---\n";

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

cout<<arr[i]<<" ";

return 0;

OUTPUT:
Dry run:

Array : 8 5 9 1

i j Arr[I]>arr[j](swap) array
0 1 8>5(true) 5 , 8 ,9 , 11
2 5>9(false) No change
3 5>1(true) 1,8,9,5
1 2 8>9(false) No change
3 8>5(true) 1,5,9,8
2 3 9>8(true) 1,5,8,9

Advantages:
1)Easy to implement.
2)Suitable for small arrays .

Disadvantages:
1)Not appropriate for large arrays due to its huge time complexity(O(n2)).

SELECTION SORT:
CODE:

#include<iostream>

using namespace std;

void selection_sort(int *arr,int size)

int min,temp;
for(int i=0;i<size-1;i++)

min=i;

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

if(arr[min]>arr[j])

min=j;}}

if(min!=i)

temp=arr[i];

arr[i]=arr[min];

arr[min]=temp;}}}

int main()

int *arr,size;

cout << " Enter size of array : " ;

cin >> size ;

arr = new int[size] ;

cout<<" Enter "<<size<<" elements of array: \n ";

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

cin>>arr[i];}

selection_sort(arr,size);

cout<<" \n\t---> SORTED ARRAY <---\n ";

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

cout<<arr[i]<<" ";}

return 0;}

Output:
Dry run:

Array: 8 5 9 1 , min=0

i j Arr[min]>arr[j] min array


0 1 8>5 (true) 1 No change
2 5>9(false) No change No change
3 5>1(true) 3 No change
Swapping min with I
array : 1 , 5 , 9 , 8
min = 1

1 2 5>9 (false) 1(no change) No change


3 5>8(false) No change No change
No swapping as min and i are same
array : 1 , 5 , 9 , 8
min = 2

2 3 9>8(true) 3 No change
Swapping min and I index

Array : 1 , 5 , 8 , 9

Advantages:

1)more optimized as compared to bubble sort due to swapping after complete iteration of inner
loop .

2)Efficient for small arrays .

Disadvantages:
1) The selection sort requires n-squared number of steps for sorting n elements.

2) The primary disadvantage of the selection sort is its poor efficiency when dealing with a huge list
of items.

INSERTION SORT
CODE:

#include<iostream>

using namespace std;

void insertion_sort(int *arr,int size)

int temp,j;

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

temp=arr[i];

for(j=i-1;j>=0&&temp<arr[j];j--)

arr[j+1]=arr[j];

arr[j+1]=temp;

int main()

int *arr,size;

cout << " Enter size of array : " ;

cin >> size ;

arr = new int[size] ;

cout<<" Enter "<<size<<" elements of array: \n ";

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

cin>>arr[i];

}
insertion_sort(arr,size);

cout<<" \n\t---> SORTED ARRAY <---\n ";

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

cout<<arr[i]<<" ";

return 0;

OUTPUT:

DRY RUN:

ARRAY : 9 0 7 2

i j Temp = arr[i] j>=0&&temp<arr array


[j]
1 0 0 0>=0&0<9 T 9972
-1 0 -1>=0&0<0 F 0972
arr[j+1]=temp
i j Temp = arr[i] j>=0&&temp<arr array
[j]
2 1 7 1>=0&7<9 T 0992
0 7 0>=0&7<0 F 0792
Arr[j+1]=temp
i j Temp=arr[i] j>=0&&temp<arr array
[j]
3 2 2 2>=0&2<9 T 0799
1 2 1>=0&2<7 T 0779
0 2 0>=0&2<0 F 0279
Arr[j+1]=temp
Advantages:
The main advantage of the insertion sort is its simplicity

Disadvantages:
The disadvantage of the insertion sort is that it does not perform as well as other, better sorting
algorithms .

MERGE SORT:
CODE:

#include<iostream>

using namespace std;

void merge(int *arr,int low,int mid, int up)

int i=low,j=mid+1,arr2[up-low+1],k=0,check=up-low+1;

while(i<=mid&&j<=up)

if(arr[i]<arr[j])

arr2[k]=arr[i];

k++;

i++;

else

arr2[k]=arr[j];

k++;

j++;

while(i<=mid)
{

arr2[k]=arr[i];

i++;

k++;

while(j<=up)

arr2[k]=arr[j];

j++;

k++;

for(i=low;i<=up;i++)

arr[i]=arr2[i-low];

void merge_sort(int *arr,int low,int up)

if(low<up)

int mid=low+up;

mid=mid/2;

merge_sort(arr,low,mid);

merge_sort(arr,mid+1,up);

merge(arr , low , mid ,up);

int main()

int *arr,size;
cout << " Enter size of array : " ;

cin >> size ;

arr = new int[size] ;

cout<<" Enter "<<size<<" elements of array: \n ";

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

cin>>arr[i];

merge_sort(arr,0,size-1);

cout<<" \n\t---> SORTED ARRAY <---\n ";

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

cout<<arr[i]<<" ";

return 0;

OUTPUT:

DRY RUN:
Array : 7 0 9 1

Merge_sort is called

Low =0 , up =3 ,mid =1

Function calls
Merge_sort(arr , 0 , 1) call 1
Merge_sort(arr , 2 , 3) call 2
Merge (arr , 0 , 1 , 3) merge call 1
Call 1:

Low =0 , up =1 , mid =0

Function Calls
Merge_sort(arr , 0 , 0) if condition false (0<0)
Merge_sort(arr,1,1) if condition false (1<1)
Merge(arr , 0 , 0 , 1) merge call 2
Call 2:

Low =2 , up =3 , mid =2

Function Calls
Merge_sort(arr , 2 , 2) if condition false (2<2)
Merge_sort(arr,3,3) if condition false (3<3)
Merge(arr , 2 , 2 , 3) merge call 3
Merge call 3:

Low = 2 , mid = 2 , up = 3 , array = 7 0 9 1

I= low J=mid +1 K=0 arr2


2 3 0 cmp 9 and 1 Arr2[0]=1
4 F (j<=up) 1 Arr2[1]=9
Copy this in array from low to high in original array

So array become 0 7 1 9

Merge call 2:

Low = 0 , mid = 0 , up = 1 , array = 7 0 1 9

I= low J=mid +1 K=0 arr2


0 1 0 Arr2[0]=0
2 F (j<=up) 1 Arr2[1]=7
Copy this in array

So array become 0 7 1 9

Merge call 1:

Low = 0 , mid = 1 , up = 3 , array = 7 0 1 9

Sub array 1 {0 7} and subarray 2 {1 9}

I= low J=mid +1 K=0 (a[I],a[j]) arr2


0 2 0 (0,1) for 7 Arr2[0]= , i++,k++
1 2 1 (7 , 1) for 1 Arr2[1]=1
j++ , k++
1 3 2 (7 , 9) for 7 Arr2[2]=7 I++,k++
2 out of bound 3 3 (9) Arr2[3]=9
(I<=mid) J++,k++
4 out of bound 4 -
(j<=up)
Copy this in array

So array become 0 1 7 9

Advantages:

it has a relatively low time complexity (O(n log n))

Disadvantages:

its space complexity is high (O(n)). This can make it difficult to implement when working with
large data sets or in cases where memory storage is an issue.

QUICK SORT:
CODE:

#include<iostream>

using namespace std;

void swap(int *arr,int pos1,int pos2)

int temp=arr[pos1];

arr[pos1]=arr[pos2];

arr[pos2]=temp;

int partition(int *arr,int low,int high,int pivot)

int i=low,j=low;

while(i<=high)

if(arr[i]>pivot)

i++;

}
else

swap(arr,i,j);

i++;

j++;

return j-1;

void quick_sort(int * arr ,int low,int high)

if(low<high)

int pivot=arr[high];

int pos=partition(arr,low,high,pivot);

quick_sort(arr,low,pos-1);

quick_sort(arr,pos+1,high);//as pos is sorted at this point

int main()

int *arr,size;

cout << " Enter size of array : " ;

cin >> size ;

arr = new int[size] ;

cout<<" Enter "<<size<<" elements of array: \n ";

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

cin>>arr[i];
}

quick_sort(arr,0,size-1);

cout<<" \n\t---> SORTED ARRAY <---\n ";

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

cout<<arr[i]<<" ";

return 0;

OUTPUT:

DRY RUN:

Array 5 9 0 6

Low = 0 , high = 3 , pivot =arr[high]=6


partition :

i j pivot Condition array


arr[I]>pivot
0 0 6 swap I ,j 5 , 9 , 0 ,6
I++ , j++ I==j no change
1 1 6 9>6 true
I++
2 1 6 Swap I , j 5,0,9,6
I++ , j++
3 2 6 Swap I , j 5,0,6,9
I++, j++
4 false (I<=high) 3
Pos = 2

Now quick_sort(arr,0 , 1)and quick_sort(arr , 3 , 3)

In quick_sort(arr , 3 , 3) there would be no change

In Quick_sort(arr , 0 , 1)

partiotion:

Low=0 , high = 1 pivot = arr[1]=0 , array : 5 0 6 9

i j pivot Condition array


arr[I]>pivot
0 0 0 5>0 true 5069
i++ (no change)
1 0 0 Swap I , j 0569
I++ , j++
2 false(I<=high) 2 (sorted)
Advantages:

Quick sort is fast, easy to implement, and in-place, which means that it does not
require extra space.
Disadvantages:

Quicksort also has some disadvantages, such as being unstable, sensitive to the
choice of the pivot, and vulnerable to the worst case.

Comparison:
Sorting algorithms Time complexity Space complexity
Best Average Worst
case case case
Bubble sort O(N) O (N^2) O (N^2) O(1)
Selection sort O (N^2) O (N^2) O (N^2) O(1)
Insertion sort O(N) O (N^2) O (N^2) O(1)
Quick sort O(N O(N O (N^2) O(N)
logN) logN)
Merge sort O(N O(N O(N O(N)
logN) logN) logN)

Question no. 2) You have been hired by a university to implement a course registration system using
C++. The university offers a wide range of courses, each with a unique ID and name. The
registration system should allow students to add and drop courses. To implement the registration
system, you have decided to use a Doubly and Circular linked list to store the courses.
Your implementation should have the following features:
A constructor that initializes an empty list
A method to add a course to the front of the list
A method to add a course to the back of the list
A method to remove a course from the front of the list
A method to remove a course from the back of the list
A method to retrieve the course at a given index
A method to return the size of the list

The linked list should allow for efficient addition and removal of courses from either end of the list.
When a course is dropped, the node containing the course should be removed from the list and the
links between the adjacent nodes should be updated to maintain the circular nature of the list.

In addition to the basic functionality, the registration system should also prevent duplicate courses
from being added to the list. If a student attempts to add a course that is already in the list, an error
message should be displayed, and the course should not be added.

CODE:
#include<iostream>
using namespace std;

struct node{
int id;
string name;
node *prev, *next; //doubly
};
class linkedlist{ //circular
node *head,*tail;
public:
linkedlist()
{
head=NULL;
tail=NULL;
}
void addfront(int id , string name)
{
if(checkid(id)==false)
{
cout<<"\n id already exist ";
return ;
}
node *tmp=new node();
tmp->id=id;
tmp->name=name;
if(head==NULL)
{
head=tmp;
tail=tmp;
tmp->prev=tmp->next=tmp;
return;
}
tmp->next=head;
head->prev=tmp;
head=tmp;
tail->next=head;
tmp->prev=tail;
}
void addback(int id,string name)
{
if(checkid(id)==false)
{
cout<<"\n id already exist ";
return ;
}
node *tmp=new node();
tmp->id=id;
tmp->name=name;
if(head==NULL)
{
head=tmp;
tail=tmp;
tmp->prev=tmp->next=tmp;
return;
}
tmp->next=head;
tmp->prev=tail;
tail->next=tmp;
tail=tmp;
head->prev=tail;
}
void removefront()
{
if(head==NULL)
{
cout<<"\n List is empty . \n";
return;
}
else if(head==tail)
{
head=NULL;
tail=NULL;
return;
}
node *tmp;
tmp=head;
head=head->next;
head->prev=tail;
tail->next=head;
delete tmp;
}
void removeback()
{
if(head==NULL)
{
cout<<"\n List is empty . \n";
return;
}
else if(head==tail)
{
head=NULL;
tail=NULL;
return ;
}
node *tmp;
tmp=tail;
tail=tail->prev;
tail->next=head;
head->prev=tail;
delete tmp;
}
void print(int check)//retrive by id
{
if(head==NULL)
{
cout<<"\nlist is empty \n";
return ;
}
node *tmp=head;
do{
if(tmp->id==check)
{
cout<<"\n id : "<<tmp->id<<" , name : "<<tmp->name<<" ... found ";
return;
}
tmp=tmp->next;
}while(tmp->next!=head);
cout<<" \n id "<<check <<" ... not found ";
}
int size()
{
int num=0;
if(head!=NULL)
{
node *tmp=head;
do{
num++;
}while(tmp->next!=NULL);
}
return num;
}
bool checkid(int check)//retrive by id
{
if(head==NULL)
{
return true;
}
node *tmp=head;
do{
if(tmp->id==check)
{
return false;
}
tmp=tmp->next;
}while(tmp->next!=head);
return true;
}
void printlist()
{
if(head==NULL)
{
cout<<"\n list is empty \n";
}
else
{
node *tmp=head;
cout<<"\n ---> Entire list <--- \n";
do
{
cout<<" id : "<<tmp->id<<" , name : "<<tmp->name<<endl;
tmp=tmp->next;
}while(tmp!=head);
}
}

};

int main()
{
linkedlist list;
int num,id;string name;

cout<<"Press following integer for respective option ";


cout<<"\n1 for adding node at begining ";
cout<<"\n2 for adding node at last ";
cout<<"\n3 for deleting node from begining ";
cout<<"\n4 for deleting node from end ";
cout<<"\n5 for printing node with id ";
cout<<"\n6 for prining entire list ";
cout<<"\nany other number for exit \n";
label:
cout<<"Enter choice : ";
cin>>num;
if(num==1||num==2)
{
cout<<" Enter id and name (2 OOP) : ";
cin>>id>>name;
if(num==1)
{
list.addfront(id,name);
}
else
{
list.addback(id,name);
}
}
else if(num==3)
{
list.removefront();
}
else if(num==4)
{
list.removeback();
}
else if(num==5)
{
cout<<" Enter id to search or print data ";
cin>>id;
list.print(id);
}
else if(num==6)
{
list.printlist();
}
else
{
exit(0);
}
goto label;
return 0;
}
OUTPUT:

You might also like