Unit-Iii DS
Unit-Iii DS
1)What is Search?
Search is a process of finding a value in a list of values. In other words, searching is
the process of locating given value position in a list of values.
Example
Consider the following list of elements and the element to be searched is 41.
Implementation of Linear Search Algorithm using C Programming Language:
#include<stdio.h>
#include<conio.h>
void main(){
int list[20],size,i,sElement;
Binary search algorithm finds a given element in a list of elements with O(log n)
time complexity where n is total number of elements in the list. The binary search
algorithm can be used with only a sorted list of elements. That means the binary
search is used only with a list of elements that are already arranged in an order. The
binary search can not be used for a list of elements arranged in random order. This
search process starts comparing the search element with the middle element in the
list. If both are matched, then the result is "element found". Otherwise, we check
whether the search element is smaller or larger than the middle element in the list. If
the search element is smaller, then we repeat the same process for the left sublist of
the middle element. If the search element is larger, then we repeat the same process
for the right sublist of the middle element. We repeat this process until we find the
search element in the list or until we left with a sublist of only one element. And if
that element also doesn't match with the search element, then the result is "Element
not found in the list".
#include<stdio.h>
#include<conio.h>
void main()
{
int first, last, middle, size, i, sElement, list[100];
clrscr();
first = 0;
last = size - 1;
middle = (first+last)/2;
2)Sorting:
a)Bubble Sort Algorithm:
Bubble Sort is a simple algorithm which is used to sort a given set of n elements
provided in form of an array with n number of elements. Bubble Sort compares all
the element one by one and sort them based on their values.
If the given array has to be sorted in ascending order, then bubble sort will start by
comparing the first element of the array with the second element, if the first element
is greater than the second element, it will swap both the elements, and then move on
to compare the second and the third element, and so on.
If we have total n elements, then we need to repeat this process for n-1 times.
It is known as bubble sort, because with every complete iteration the largest element
in the given array, bubbles up towards the last place or the highest index, just like a
water bubble rises up to the water surface.
Sorting takes place by stepping through all the elements one-by-one and comparing
it with the adjacent element and swapping them if required.
Starting with the first element(index = 0), compare the current element with the next
element of the array.
If the current element is greater than the next element of the array, swap them.
If the current element is less than the next element, move to the next element. Repeat
Step 1.
Let's consider an array with values {5, 1, 6, 2, 4, 3}
Below, we have a pictorial representation of how bubble sort will sort the given
array.
So as we can see in the representation above, after the first iteration, 6 is placed at
the last index, which is the correct position for it.
Similarly after the second iteration, 5 will be at the second last index, and so on.
int main()
{
int arr[100], i, n, step, temp;
// ask user for number of elements to be sorted
printf("Enter the number of elements to be sorted: ");
scanf("%d", &n);
// input elements if the array
for(i = 0; i < n; i++)
{
printf("Enter element no. %d: ", i+1);
scanf("%d", &arr[i]);
}
// call the function bubbleSort
bubbleSort(arr, n);
return 0;
}
In Bubble Sort, n-1 comparisons will be done in the 1st pass, n-2 in 2nd pass, n-3 in
3rd pass and so on. So the total number of comparisons will be,
Sum = n(n-1)/2
i.e O(n2)
The space complexity for Bubble Sort is O(1), because only a single additional
memory space is required i.e. for temp variable.
Also, the best case time complexity will be O(n), it is when the list is already
sorted.
Following are the Time and Space complexity for the Bubble Sort algorithm.
Consider you have 10 cards out of a deck of cards in your hand. And they are sorted,
or arranged in the ascending order of their numbers.
If I give you another card, and ask you to insert the card in just the right position,
so that the cards in your hand are still sorted. What will you do?
Well, you will have to go through each card from the starting or the back and find
the right position for the new card, comparing it's value with each card. Once you
find the right position, you will insert the card there.
Similarly, if more new cards are provided to you, you can easily repeat the same
process and insert the new cards and keep the cards sorted too.
This is exactly how insertion sort works. It starts from the index 1(not 0), and each
index starting from index 1 is like a new card, that you have to place at the right
position in the sorted subarray on the left.
1. It is efficient for smaller data sets, but very inefficient for larger lists.
2. Insertion Sort is adaptive, that means it reduces its total number of steps if a
partially sorted array is provided as input, making it efficient.
4. Its space complexity is less. Like bubble Sort, insertion sort also requires a
single additional memory space.
We start by making the second element of the given array, i.e. element at index 1,
the key. The key element here is the new card that we need to add to our existing
sorted set of cards(remember the example with cards above).
We compare the key element with the element(s) before it, in this case, element at
index 0:
If the key element is less than the first element, we insert the key element before the
first element.
If the key element is greater than the first element, then we insert it after the first
element.
Then, we make the third element of the array as key and will compare it with
elements to it's left and insert it at the right position.
And we go on repeating this, until the array is sorted.
Let's consider an array with values {5, 1, 6, 2, 4, 3}
Below, we have a pictorial representation of how bubble sort will sort the given
array.
As you can see in the diagram above, after picking a key, we start iterating
over the elements to the left of the key.
We continue to move towards left if the elements are greater than the key element
and stop when we find the element which is less than the key element.
And, insert the key element after the element which is less than the key element.
Note: You can learn the program for insertion sort which I have given in the
class.
Program:
#include <stdio.h>
int main() {
int arr[10000];
int n;
printf("Enter size of the array: ");
scanf("%d", &n);
printf("Enter the array elements: ");
for(int i = 0; i < n; i++)
scanf("%d", &arr[i]);
insertionSort(arr, n);
printf("After sorting, the array is: ");
printArray(arr, n);
}
Complexity Analysis of Insertion Sort:
Worst Case Time Complexity [ Big-O ]: O(n2)
Selection sort is conceptually the most simplest sorting algorithm. This algorithm
will first find the smallest element in the array and swap it with the element in the
first position, then it will find the second smallest element and swap it with the
element in the second position, and it will keep on doing this until the entire array is
sorted.
It is called selection sort because it repeatedly selects the next-smallest element and
swaps it into the right place.
Step 1 - Select the first element of the list (i.e., Element at first position in the list).
Step 2: Compare the selected element with all the other elements in the list.
Step 3: In every comparision, if any element is found smaller than the selected
element (for Ascending order), then both are swapped.
Step 4: Repeat the same procedure with element in the next position in the list till
the entire list is sorted.
Selection Sort Logic:
void main(){
int size,i,j,temp,list[100];
clrscr();
getch();
}
d)QuickSort:
Quick sort is a fast sorting algorithm used to sort a list of elements. Quick sort
algorithm is invented by C. A. R. Hoare.
The quick sort algorithm attempts to separate the list of elements into two parts and
then sort each part recursively. That means it use divide and conquer strategy. In
quick sort, the partition of the list is performed based on the element called pivot.
Here pivot element is one of the elements in the list.
The list is divided into two partitions such that "all elements to the left of pivot are
smaller than the pivot and all elements to the right of pivot are greater than or equal
to the pivot".
In Quick sort algorithm, partitioning of the list is performed using following steps...
Step 1 - Consider the first element of the list as pivot (i.e., Element at first position
in the list).
Step 2 - Define two variables i and j. Set i and j to first and last elements of the list
respectively.
Step 3 - Increment i until list[i] > pivot then stop.
Step 4 - Decrement j until list[j] < pivot then stop.
Step 5 - If i < j then exchange list[i] and list[j].
Step 6 - Repeat steps 3,4 & 5 until i > j.
Step 7 - Exchange the pivot element with list[j] element.
To sort an unsorted list with 'n' number of elements, we need to make ((n-1)+(n-
2)+(n-3)+......+1) = (n (n-1))/2 number of comparisions in the worst case. If the list
is already sorted, then it requires 'n' number of comparisions.
e)Mergesort:
In Merge Sort, the given unsorted array with n elements, is divided into n subarrays,
each having one element, because a single element is always sorted in itself. Then,
it repeatedly merges these subarrays, to produce new sorted subarrays, and in the
end, one complete sorted array is produced.
2. Conquer the subproblems by solving them. The idea is to break down the
problem into atomic subproblems, where they are actually solved.
3. Combine the solutions of the subproblems to find the solution of the actual
problem.
In merge sort, we break the given array midway, for example if the original array
had 6 elements, then merge sort will break it down into two subarrays
with 3 elements each.
But breaking the orignal array into 2 smaller subarrays is not helping us in sorting
the array.
So we will break these subarrays into even smaller subarrays, until we have multiple
subarrays with single element in them. Now, the idea here is that an array with a
single element is already sorted, so once we break the original array into subarrays
which has only a single element, we have successfully broken down our problem
into base problems.
And then we have to merge all these sorted subarrays, step by step to form one single
sorted array.
Below, we have a pictorial representation of how merge sort will sort the given array.
In merge sort we follow the following steps:
1. We take a variable p and store the starting index of our array in this. And we
take another variable r and store the last index of array in it.
2. Then we find the middle of the array using the formula (p + r)/2 and mark the
middle index as q, and break the array into two subarrays, from p to q and
from q + 1 to r index.
3. Then we divide these 2 subarrays again, just like we divided our main array
and this continues.
4. Once we have divided the main array into subarrays with single elements, then
we start merging the subarrays.
MergeSort Program:
/*
a[] is the array, p is starting index, that is 0,
and r is the last index of array.
*/
#include <stdio.h>
while(i <= q)
{
b[k++] = a[i++];
}
while(j <= r)
{
b[k++] = a[j++];
}
for(i=r; i >= p; i--)
{
a[i] = b[--k]; // copying back the sorted list to a[]
}
}
int main()
{
int arr[] = {32, 45, 67, 2, 7};
int len = sizeof(arr)/sizeof(arr[0]);
Merge Sort is quite fast, and has a time complexity of O(n*log n). It is also a stable
sort, which means the "equal" elements are ordered in the same order in the sorted
list.
In this section we will understand why the running time for merge sort is O(n*log
n).
As we have already learned in Binary Search that whenever we divide a number into
half in every step, it can be represented using a logarithmic function, which is log
n and the number of steps can be represented by log n + 1(at most)
Also, we perform a single step operation to find out the middle of any subarray,
i.e. O(1).
And to merge the subarrays, made by dividing the original array of n elements, a
running time of O(n) will be required.
Hence the total time for mergeSort function will become n(log n + 1), which gives
us a time complexity of O(n*log n).
• It requires equal amount of additional space as the unsorted array. Hence its
not at all recommended for searching large unsorted arrays.
What is a Heap ?
Heap is a special tree-based data structure, that satisfies the following special heap
properties:
Shape Property: Heap data structure is always a Complete Binary Tree, which
means all levels of the tree are fully filled.
Heap Property: All nodes are either greater than or equal to or less than or
equal to each of its children. If the parent nodes are greater than their child
nodes, heap is called a Max-Heap, and if the parent nodes are smaller than their
child nodes, heap is called Min-Heap.
How Heap Sort Works?
Initially on receiving an unsorted list, the first step in heap sort is to create a Heap
data structure(Max-Heap or Min-Heap). Once heap is built, the first element of the
Heap is either largest or smallest(depending upon Max-Heap or Min-Heap), so we
put the first element of the heap in our array. Then we again make heap using the
remaining elements, to again pick the first element of the heap and put it into the
array. We keep on doing the same repeatedly untill we have the complete sorted list
in our array.
In the below algorithm, initially heapsort() function is called, which
calls heapify() to build the heap.
#include <stdio.h>
void heapify(int arr[],int n,int i);
void heapsort(int arr[],int n);
int main() {
int arr[15], i, n;
printf("Enter array size : ");
scanf("%d", &n);
printf("Enter %d elements : ", n);
for (i = 0; i < n; i++) {
scanf("%d", &arr[i]);
}
printf("Before sorting the elements are : ");
for (i = 0; i < n; i++)
{
printf("%d ", arr[i]);
}
heapsort(arr,n);
printf("After sorting the elements are : ");
for (i = 0; i < n; i++)
{
printf("%d ",arr[i]);
}
return 0;
}
• Heap sort is not a Stable sort, and requires a constant space for sorting a list.