software engineering Chapter 5 System modeling.pptx
shell and merge sort
1. Shell Sort is a generalized version of insertion sort. It is an
in–place comparison sort. Shell Sort is also known as
diminishing increment sort, it is one of the oldest sorting
algorithms invented by Donald L. Shell (1959.)
This algorithm uses insertion sort on the large interval of
elements to sort. Then the interval of sorting keeps on
decreasing in a sequence until the interval reaches 1. These
intervals are known as gap sequence.
This algorithm works quite efficiently for small and medium
size array as its average time complexity is near to O(n).
OVERVIEW
2. • Shell Sort is a comparison based sorting.
• Time complexity of Shell Sort depends on gap sequence . Its best case time
complexity is O(n* logn) and worst case is O(n* log2n). Time complexity of Shell
sort is generally assumed to be near to O(n) and less than O(n2) as determining its
time complexity is still an open problem.
• The best case in shell sort is when the array is already sorted. The number of
comparisons is less.
• It is an in-place sorting algorithm as it requires no additional scratch space.
• Shell Sort is unstable sort as relative order of elements with equal values may
change.
• It is been observed that shell sort is 5 times faster than bubble sort and twice faster
than insertion sort its closest competitor.
• There are various increment sequences or gap sequences in shell sort which
produce various complexity between O(n) and O(n2).
FEATURES:
3. 78 15 6 91 88 12 7 32 5 111 47
n = 11
gap = floor(n / 2) = floor(11/2) = 5
gap = 5
78156 918812 7 325 11147
gap = 5
78156 918812 7 325 11147
gap = 2
4. SHELL-SORT(A,n)
// we take gap sequence in order of |N/2|, |N/4|, |N/8|...1
for gap=n/2; gap=0; gap/=2 do:
//Perform gapped insertion sort for this gap size.
for i=gap; i<n; i+=1 do: temp=A[i]
// shift earlier gap-sorted elements up until
// the correct location for a[i] is found
for j=i; j>=gap && A[j-gap]>temp;j-=gap
do:
A[j]= A[j-gap]
end for
// put temp in its correct location
A[j]= temp;
end for
end for
end func
PSEUDOCODE
5. void shellSort(int A[], int n)
{
int gap,i;
// Start with a larger gap, then reduce the gap to 1
// we take gap sequence in order of |N/2|, |N/4|, |N/8|...1
for (gap = n/2; gap > 0; gap /= 2)
{
// we performe gapped insertion sort for this gap size.
// The first gap elements a[0..gap-1] are already in gapped order
// keep adding one more element until the entire array is gap sorted
for (i = gap; i < n; i += 1) {
// store a[i] in temp and make a hole at position i
int temp = A[i];
// shift earlier gap-sorted elements up until the correct
// location for a[i] is found
int j;
for (j = i; j >= gap && A[j - gap] > temp; j -= gap)
A[j] = A[j - gap];
// put temp (the original a[i]) in its correct location
A[j] = temp;
}
}
}
C-Implementation
6. Since in this algorithm insertion sort is applied in the large interval of elements
and then interval reduces in a sequence, therefore the running time of Shell sort
is heavily dependent on the gap sequence it uses .Summarising all this –
Worst Case Time complexity: O (n2)
Average Case Time complexity: depends on gap sequence.
Best Case Time complexity: O(n*logn)
Worst Case Space Complexity: O(n) total, O(1) auxiliary
Data Structure: Array
Sorting In Place: Yes
Stable: No
Asymptotic Analysis
7. Merge Sort is a divide and conquers algorithm in which original data is divided
into a smaller set of data to sort the array.
In merge sort the array is firstly divided into two halves, and then further sub-
arrays are recursively divided into two halves till we get N sub-arrays, each
containing 1 element.
Then, the sub-arrays are repeatedly merged, to produce new array until there is
one array remaining. This will be our sorted array at the end.
OVERVIEW
8. • Merge Sort is a type of recursive algorithm.
• We can express time complexity of merge sort by this recurrence relation: T(n) =
2T(n/2) + O(n)
Using Masters Theorem, we get -> T(n)=O(n*logn).
• Time complexity of Merge Sort is O(n*logn) in all 3 cases (worst, average and best)
as in merge sort , array is recursively divided into two halves and take linear time to
merge two halves.
• It is not an in-place sorting algorithm as it requires additional scratch space
proportional to the size of the input array.
• It requires an equal amount of additional space as the unsorted list. Hence, it’s not
at all recommended for sorting large size list.
• Merge Sort is a stable sort, which means the “equal” elements appear in the same
order in the sorted array as they were in the unsorted array.
• Merge Sort is a best-sorting technique for sorting Linked Lists. Because in linked
list it can be implemented without extra space as elements can be inserted in the
middle in O(1) extra space and O(1) time.
FEATURES:
9. //A->array, l->left most index, r->right most index
MERGE-SORT(A, l, r)
if l < r
mid = (l+(r-l)/2)
MERGE-SORT(A, l, mid)
MERGE-SORT (A, mid+1, r)
MERGE(A, l, mid ,r)
end func
MERGE(A, l, m, r)
nL = m-l+1
nR = r-m
Create arrays L[1..nL+1] and R[1..nR+1]
for i=0 to nL-1
L[i] = A[l+i]
end for
for j=0 to nR-1
R[j] = A[m+l+j]
end for
i=0; j=0; k=l;
while i < nL and j < nR
if L[i] <= R[j]
A[k]=L[i]; i=i+1; k=k+1;
else
A[k]=R[j]; j=j+1; k=k+1;
end while
while i < nL
A[k]=L[i]; i=i+1; k=k+1;
end while
while j < nR
A[k]=R[j]; j=j+1; k=k+1;
end while
end func
PSEUDOCODE
10. void merge_sort(int *a,int len_a,int *b,int len_b) {
if (len_a > 1) {
int mid_a = len_a >> 1;
merge_sort(a,mid_a,a+mid_a,len_a-mid_a);
}
if (len_b > 1) {
int mid_b = len_b >> 1;
merge_sort(b,mid_b,b+mid_b,len_b-mid_b);
}
int curr_a=0, curr_b=0, *temp_arr,k=0;
temp_arr = (int*)malloc((len_a+len_b)*sizeof(int));
while (curr_a < len_a && curr_b < len_b) {
if (a[curr_a] <= b[curr_b]) {
temp_arr[k]=a[curr_a];
curr_a++;
}
else {
temp_arr[k]=b[curr_b];
curr_b++;
}
k++;
}
while (curr_a < len_a) {
temp_arr[k] = a[curr_a];
curr_a++;
k++;
}
while (curr_b < len_b) {
temp_arr[k] = b[curr_b];
curr_b++;
k++;
}
for (int k=0;k<len_a+len_b;k++){
a[k] = temp_arr[k];
}
free(temp_arr);
}
C-IMPLEMENTATION
11. Since in this algorithm array is recursively divided into two halves and take linear
time to merge two halves, so the complexity of this algorithm id O(n*logn) in all
the cases. Summarizing all this-
Worst Case Time complexity: O (n*logn)
Average Case Time complexity: O(n*logn)
Best Case Time complexity: O(n*logn)
Space Complexity: O(n) Auxiliary space
Algorithmic Paradigm: Divide and Conquer
Sorting In Place: No
Space Complexity: O(n)
Stable: Yes
Asymptotic Analysis