Exp 2 - Dsa Lab File
Exp 2 - Dsa Lab File
Exp 2 - Dsa Lab File
BUBBLE SORT
Bubble Sort is the simplest sorting algorithm that works by repeatedly swapping the
adjacent elements if they are in the wrong order. This algorithm is not suitable for
large data sets as its average and worst-case time complexity is quite high.
There are several theories and aspects associated with bubble sort:
1.Comparison-based Sorting: Bubble sort is a comparison-based sorting algorithm,
meaning it sorts elements by comparing them and swapping if necessary. It has a time
complexity of O(n^2), where n is the number of elements in the list.
2. Stable Sorting: Bubble sort is a stable sorting algorithm, which means that it maintains the
relative order of equal elements. If two elements have the same value, the one that appeared
first in the original list will still be first after sorting.
3.Adaptive Sorting: Bubble sort is an adaptive sorting algorithm. This means that its
performance can be better when the list is partially sorted. In a partially sorted list, bubble
sort can have a time complexity closer to O(n).
4.Inefficient for Large Lists: Bubble sort is not a practical sorting algorithm for large lists,
as its time complexity grows quadratically with the number of elements.
5.Implementation Variations: There are several variations of bubble sort, such as the
cocktail shaker sort, which sorts in both directions (from the beginning to the end and then
from the end to the beginning). These variations aim to reduce the number of passes through
the list.
In summary, bubble sort is a basic sorting algorithm that serves as a foundation for learning
about sorting algorithms and their characteristics. While it is not efficient for large datasets, it
is still an interesting concept in computer science and can help students grasp the
fundamental principles of sorting algorithms.
ALGORITHM:
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.
#include<stdio.h>
int main()
{
int arr[7]={64,34,25,12,22,11,90},n=7,i,j,temp;
for(i=0;i<7;i++)
{
printf("%d\t",arr[i]);
}
for (j=0;j<n-1;j++)
{
for (j=0;j<=n-2;j++)
{
if(arr[j]>arr[j+1])
{
int temp=arr[j];
arr[j]=arr[j+1];
arr[j+1]=temp;
}
}
}
printf("\n");
for (i=0;i<n;i++)
{
printf("%d\t",arr[i]);
}
return 0;
}
OUTPUT:-
CONCLUSION:-
It can be conducted that bubble sort is an effortless way of sorting the elements of
an array, thus having more time complexity. It is aa table and in-place algorithm
which is most used for introducing the concept of sorting algorithm. It is also used
in computer graphics because of its feature to detect the minute errors and fix them
in linear time.
QUICKSORT
[Quicksort is a sorting algorithm based on the Divide and Conquer algorithm that picks an
element as a pivot and partitions the given array around the picked pivot by placing the pivot
in its correct position in the sorted array.
The key process in quickSort is a partition(). The target of partitions is to place the pivot (any
element can be chosen to be a pivot) at its correct position in the sorted array and put all
smaller elements to the left of the pivot, and all greater elements to the right of the
pivot.Partition is done recursively on each side of the pivot after the pivot is placed in its
correct position and this finally sorts the array.
ALGORITHM:-
PARTITIONALGORITHM:-
#include <stdio.h>
void swap(int* a, int* b)
{
int t = *a;
*a = *b;
*b = t;
}
int partition(int arr[], int low, int high){
int pivot = arr[high];
int i = (low - 1);
int j;
for (j = low; j <= high - 1; j++) {
if (arr[j] < pivot) {
i++;
swap(&arr[i], &arr[j]);
}
}
swap(&arr[i + 1], &arr[high]);
return (i + 1);
}
void quickSort(int arr[], int low, int high)
{
if (low < high) {
int pi = partition(arr, low, high);
quickSort(arr, low, pi - 1);
quickSort(arr, pi + 1, high);
}
}
int main()
{
int arr[7] = { 8, 7, 2, 1, 0, 9, 6 };
int i;
int N = sizeof(arr) / sizeof(arr[0]);
quickSort(arr, 0, N - 1);
printf("Sorted array: \n");
for (i = 0; i < N; i++)
printf("%d ", arr[i]);
return 0;
}
OUTPUT:-
CONCLUSION:-
Quick sort method sorts the elements using the Divide and Conquer approach.
It has ana average O (n log n) complexity.
It can be implemented in both recursive and iterative ways.
Quicksort is in place, cache-friendly and also a tail recursive algorithm.
COMPARATIVE STUDY:
1. Efficiency:
- QuickSort:
- Average and best-case time complexity: O(n log n).
- Worst-case time complexity: O(n^2), but it's rare with good pivot selection strategies.
- BubbleSort:
- Average, best, and worst-case time complexity: O(n^2).
QuickSort is significantly more efficient than BubbleSort on average and for most practical
cases. It is a "divide and conquer" algorithm that tends to perform well, especially when
implemented with good pivot selection strategies. BubbleSort, on the other hand, has poor
performance, making it unsuitable for larger datasets.
2. Performance:
- QuickSort is generally faster and is considered one of the fastest general-purpose sorting
algorithms.
- BubbleSort is one of the slowest sorting algorithms, making it impractical for most real-
world applications.
3. Implementation:
- QuickSort uses a recursive or iterative approach, where it divides the array into smaller
sub-arrays and sorts them individually.
- BubbleSort is straightforward to implement with nested loops and swaps.
4. Stability:
- QuickSort is not inherently stable, meaning it might change the order of equal elements in
the sorted array.
- BubbleSort is a stable sorting algorithm; it preserves the order of equal elements.
5. Use cases:
- QuickSort is a practical choice for sorting large datasets or lists and is used in various
applications, including in sorting libraries and built-in functions of programming languages.
- BubbleSort is mainly used for educational purposes or for sorting very small lists due to
its simplicity. It's not used in practical applications where efficiency is critical.
When using Merge Sort, comparisons and swaps are used to determine the order of each
element. The time complexity of this algorithm is O(n log n), meaning it takes significantly
less time to sort larger arrays as compared to other algorithms. However, it does require more
memory usage than some other sorting algorithms due to the extra space needed for storing
temporary subarrays while they are being split and merged back together.
Merge Sort can be an extremely effective sorting solution when used correctly. Its improved
time complexity makes it best suited for sorting larger data sets and its fast execution time
can be an optimized solution when dealing with more complex tasks. However, this algorithm
may not be practical for small datasets since its memory usage could cause performance
issues if overused or misused.
To summarize, Merge Sort is a powerful algorithm that can be used with confidence by both
freshers and experienced professionals alike. It is ideal for sorting large datasets quickly and
efficiently by using the Divide and Conquer approach. While its higher memory usage may
not make it suitable for extremely small datasets or limited hardware resources, its improved
time complexity makes it a great choice for large data sets where speed matters most!
CONCLUSION:-
Merge sort is a powerful algorithm that can be used with confidence by both freshers and
expected professionals alike. It is ideal for sorting large datasets quickly and efficiently by
using Divide and Conquer approach. While its higher memory usage may not make it suitable
for extremely small datasets, its improved time complexity makes it a great choice for large
data sets were speed matters most.
COMPARATIVE STUDY:
Merge Sort, Quick Sort, and Bubble Sort are three different sorting algorithms used to
arrange elements in a specific order, most commonly in ascending or descending order. Each
of these algorithms has its own advantages and disadvantages. Let's compare them in terms of
their time complexity, space complexity, and their suitability for different scenarios:
1. Merge Sort:
- Time Complexity: Merge Sort has a time complexity of O(n log n) in the worst-case,
average case, and best-case scenarios. This makes it very consistent in its performance.
- Space Complexity: Merge Sort has a space complexity of O(n) because it requires
additional memory to store temporary arrays during the merging process.
- Stability: Merge Sort is a stable sort, meaning it maintains the relative order of equal
elements.
2. Quick Sort:
- Time Complexity: Quick Sort has an average-case time complexity of O(n log n), which
makes it very efficient in most cases. However, it can degrade to O(n^2) in the worst-case
scenario.
- Space Complexity: Quick Sort has an average space complexity of O(log n) due to its
recursive nature. In-place variations of Quick Sort can reduce this space complexity.
- Stability: Quick Sort is not a stable sort, as it may change the relative order of equal
elements.
3. Bubble Sort:
- Time Complexity: Bubble Sort has a worst-case and average-case time complexity of
O(n^2). It is not efficient for large lists and is primarily used for educational purposes.
- Space Complexity: Bubble Sort has a space complexity of O(1) because it doesn't require
additional memory.
- Stability: Bubble Sort is a stable sort, as it doesn't change the relative order of equal
elements.
Comparison:
- Merge Sort and Quick Sort are both divide-and-conquer algorithms and are typically much
faster than Bubble Sort.
- Merge Sort is more predictable and consistently performs well in various scenarios, making
it a good choice for general-purpose sorting when space usage is not a concern.
- Quick Sort is often faster than Merge Sort in practice for most input data. However, its
worst-case time complexity can be a concern.
- Bubble Sort is inefficient for large datasets and is mainly used for educational purposes or
for sorting very small lists.
- Merge Sort and Quick Sort both require additional memory for their operation, which may
not be suitable for applications with limited memory resources.
In summary, Merge Sort and Quick Sort are more efficient and practical sorting algorithms
than Bubble Sort. The choice between Merge Sort and Quick Sort depends on factors like the
specific use case, desired stability, and available memory resources.
INSERTION SORT:
Insertion sort is an algorithm used to sort a collection of elements in ascending or
descending order. The basic idea behind the algorithm is to divide the list into two parts: a
sorted part and an unsorted part.
Initially, the sorted part contains only the first element of the list, while the rest of the list
is in the unsorted part. The algorithm then iterates through each element in the unsorted
part, picking one at a time, and inserts it into its correct position in the sorted part.
To do this, the algorithm compares the current element with each element in the sorted
part, starting from the rightmost element. It continues to move to the left until it finds an
element that is smaller (if sorting in ascending order) or larger (if sorting in descending
order) than the current element.
Once the correct position has been found, the algorithm shifts all the elements to the right
of that position to make room for the current element, and then inserts the current element
into its correct position.
This process continues until all the elements in the unsorted part have been inserted into
their correct positions in the sorted part, resulting in a fully sorted list.
One of the advantages of insertion sort is that it is an in-place sorting algorithm, which
means that it does not require any additional storage space other than the original list.
Additionally, it has a time complexity of O(n^2), which makes it suitable for small
datasets, but not for large ones.
Overall, insertion sort is a simple, yet effective sorting algorithm that can be used for
small datasets or as a part of more complex algorithms.
ALGORITHM
The simple steps of achieving the insertion sort are listed as follows -
Step 1 - If the element is the first element, assume that it is already sorted. Return 1.
Step3 - Now, compare the key with all elements in the sorted array.
Step 4 - If the element in the sorted array is smaller than the current element, then move
to the next element. Else, shift greater elements in the array towards the right.
#include <stdio.h>
void insertionSort(int arr[], int n)
{
int i, key, j;
for (i = 1; i < n; i++) {
key = arr[i];
j = i - 1;
while (j >= 0 && arr[j] > key) {
arr[j + 1] = arr[j];
j = j - 1;
}
arr[j + 1] = key;
}
}
void printArray(int arr[], int n)
{
int i;
for (i = 0; i < n; i++)
printf("%d ", arr[i]);
printf("\n");
}
int main()
{
int arr[] = { 9, 2, 8, 4, 5, 61 };
int n = sizeof(arr) / sizeof(arr[0]);
insertionSort(arr, n);
printArray(arr, n);
return 0;
}
OUTPUT:
Simple implementation.
Effiecient for small data sets.
It is stable.
CONCLUSION:-
Insertion sort is another sorting algorithm suitable for small data sets. Insertion sort can
be used in combination with binary search to find the correct position to insert the
element in the sorted part. The number of comparisons might reduce but worst-case
complexity still remains the same. Onof the advantages of insertion sort is that it does
Not requir3 any additional storage space other than the original list. Additionally, it has a
time complexity of O(n2 ),which makes it suitable for small datasets, but not for large
ones.
COMPARATIVE STUDY:-
Insertion sort, merge sort, quick sort, and bubble sort are all sorting algorithms, but they
differ significantly in terms of their efficiency and the way they sort data. Here's a
comparison of these sorting algorithms:
1. Insertion Sort:
- Efficiency: It has an average and worst-case time complexity of O(n^2), where n is the
number of elements. It is inefficient for large datasets.
- Best Use Case: It is suitable for sorting small arrays or nearly sorted data, as it has low
overhead for small input sizes.
2. Merge Sort:
- Efficiency: It has a consistent time complexity of O(n log n), where n is the number of
elements. It is efficient for both small and large datasets.
- Best Use Case: It is a general-purpose sorting algorithm suitable for large datasets and
external sorting, but it has a higher space complexity due to the need for additional storage.
3. Quick Sort:
- Efficiency: It has an average-case time complexity of O(n log n), making it one of the
fastest sorting algorithms in practice. However, it can degrade to O(n^2) in the worst case.
- Best Use Case: Quick Sort is efficient for most practical scenarios and is often used as the
default sorting algorithm in programming languages.
4. Bubble Sort:
- Efficiency: It has a time complexity of O(n^2) in the average and worst case, making it
inefficient for larger datasets.
- Best Use Case: Bubble sort is primarily used for educational purposes and is not practical
for sorting large datasets.
In summary, insertion sort is suitable for small datasets, merge sort is efficient for general
sorting tasks, quick sort is a good choice for most practical scenarios, and bubble sort is not
recommended for large datasets but may be used for educational purposes to illustrate sorting
concepts.
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.
The algorithm repeatedly selects the smallest (or largest) element from the unsorted
portion of the list and swaps it with the first element of the unsorted part. This process is
repeated for the remaining unsorted portion until the entire list is sorted.
ALGORITHM:-
CONCUSION:-
Selection sort is an unstable algorithm that is good for sorting small datasets.Time taken by
this algorithm is more but it is beneficial to scenario where we have memory limitations.
SELECTION SORT IS SIMPLE AND EASY TO IMPLEMEMT .THE AVERAGE CASE
TIME COMPLEXITY OF THE SELECTION SORT IS O(n2 ).The worst-case time
complexity of selection sort,as well as the best-case time complexity comes out to be the
same as the average case time complexity of selection sort i.e. O(n2 ).
COMPARATIVE STUDY:-
Selection sort, insertion sort, merge sort, quick sort, and bubble sort are all sorting
algorithms, but they differ in terms of their efficiency, implementation, and use cases. Here's
a comparison of these sorting algorithms:
1. Selection Sort:
- Time Complexity: O(n^2) in the worst, average, and best cases.
- Description: Selection sort divides the input into two parts: the sorted and the unsorted. It
repeatedly selects the minimum element from the unsorted portion and moves it to the end of
the sorted portion.
- Best used for small datasets as it's simple to implement but inefficient for larger datasets
due to its quadratic time complexity.
2. Insertion Sort:
- Time Complexity: O(n^2) in the worst and average cases, O(n) in the best case.
- Description: Insertion sort builds a sorted portion of the array by iteratively inserting one
element at a time from the unsorted portion into its correct position in the sorted portion.
- Suitable for small datasets or when the input is already partially sorted.
3. Merge Sort:
- Time Complexity: O(n log n) in the worst, average, and best cases.
- Description: Merge sort is a divide-and-conquer algorithm that recursively divides the
input into smaller halves, sorts them, and then merges the sorted halves back together.
- Highly efficient and stable, making it a good choice for sorting large datasets.
4. Quick Sort:
- Time Complexity: O(n^2) in the worst case, O(n log n) in the average and best cases.
- Description: Quick sort is also a divide-and-conquer algorithm that selects a "pivot"
element and partitions the input into elements less than and greater than the pivot. It then
recursively sorts these partitions.
- Very efficient on average and widely used in practice. It's not stable.
5. Bubble Sort:
- Time Complexity: O(n^2) in the worst and average cases, O(n) in the best case (when the
input is already sorted).
- Description: Bubble sort repeatedly compares and swaps adjacent elements if they are in
the wrong order until the entire array is sorted.
- Inefficient for large datasets and is mostly used for educational purposes due to its
simplicity.
In summary, the choice of sorting algorithm depends on the specific requirements of your
task. Merge sort and quick sort are generally preferred for large datasets due to their O(n log
n) time complexity. Selection, insertion, and bubble sorts are simple but inefficient for larger
datasets and are usually avoided in favour of more efficient algorithms.
HEAP SORT
Heap sort in C is a sorting technique that uses a comparison technique and is based on a
Binary heap data structure. Similar to that of the selection sort where the first minimum
element is found and placed at the beginning and the process is repeated for other elements.
The concept of heap sort is to eliminate the elements one by one from the heap list and insert
them into the sorted part of the list. It is also called an in-place sorting algorithm.
ALGORITHM:-
First convert the array into heap data structure using heapify, then one by one delete the root
node of the Max-heap and replace it with the last node in the heap and then heapify the root
of the heap. Repeat this process until size of heap is greater than 1.
#include <stdio.h>
void swap(int* a, int* b)
{
OUTPUT:
ADVANTAGES OF HEAP SORT:-
Because of its efficiency ,this algorithm is widely used.
As it is an in-pace sorting algorithm,its memory usage is nominal.
CONCLUSION:-
Heap sort is a sorting algorithm that is based on the binary heap data structure. It has a time
complexity of O(nlogn) and is considered a stable sorting algorithm, meaning that the relative
order of equal elements is preserved in the sorted output. Heap sort is widely used due to its
versatility, performance, and low memory requirements. The algorithm consists of two main
steps: building a max heap from the input data, successively removing the maximum element,
and adjusting the heap until the input data is fully sorted. Heap sort has several important
applications in various fields, including computer science, engineering, and finance, and can
be optimized for specific use cases by using techniques such as building the heap bottom-up,
using a min-heap instead of a max heap, and using a hybrid approach that combines heap sort
with other sorting algorithms.
In summary, heap sort is a valuable tool for sorting large datasets and is an important
algorithm to understand for anyone studying data structures and algorithms.
COMPARATIVE STUDY:-
Heap sort is a comparison-based sorting algorithm, and it can be compared to other sorting
algorithms in terms of their time and space complexity, stability, and other characteristics.
Here's a comparison of heap sort with selection sort, insertion sort, merge sort, quick sort, and
bubble sort:
1. Time Complexity:
- Heap Sort: O(n log n) in the worst, average, and best cases.
- Selection Sort: O(n^2) in the worst, average, and best cases.
- Insertion Sort: O(n^2) in the worst and average cases, but O(n) in the best case (when the
input is nearly sorted).
- Merge Sort: O(n log n) in the worst, average, and best cases.
- Quick Sort: O(n^2) in the worst case, but O(n log n) in the average and best cases.
- Bubble Sort: O(n^2) in the worst, average, and best cases.
2. Stability:
- Heap Sort: Not stable.
- Selection Sort: Not stable.
- Insertion Sort: Stable.
- Merge Sort: Stable.
- Quick Sort: Not stable (but can be made stable with modifications).
- Bubble Sort: Stable.
3. Adaptive:
- An algorithm is said to be adaptive if its performance is better when the input is partially
sorted. None of these sorting algorithms are inherently highly adaptive, but insertion sort is
the most adaptive among them.
In summary, heap sort and merge sort are more efficient than selection sort, insertion sort,
quick sort, and bubble sort for large datasets, with heap sort being in-place and merge sort
being stable. Selection sort, insertion sort, and bubble sort are less efficient for large datasets
and are often used in scenarios where simplicity is more important than speed. Quick sort is
efficient for most cases but not stable, while heap sort is an efficient in-place sorting
algorithm, but it is not stable. The choice of sorting algorithm depends on the specific
requirements of the task and the characteristics of the data being sorted.