Download as pdf or txt
Download as pdf or txt
You are on page 1of 29

University of Science

FACULTY OF INFORMATION TECHNOLOGY

LABORATORY 3 REPORT
SORTING ALGORITHMS ANALYSIS

Student Name Student ID


DO KHAI HUNG 21120462

Lecturer in charge:
Ir. NGUYEN THANH PHUONG
Ir. BUI HUY THONG

Submission Date : 29/10/2022


Lab3: Sorting Algorithms 21120462 - Do Khai Hung

Contents
1 Introduction 2

2 Algorithms 2
2.1 Selection Sort . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2
2.2 Insertion Sort . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4
2.3 Bubble Sort . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
2.4 Shaker Sort . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6
2.5 Shell Sort . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7
2.6 Heap Sort . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8
2.7 Merge Sort . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10
2.8 Quick Sort . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12
2.9 Counting Sort . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14
2.10 Radix Sort . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15
2.11 Flash Sort . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17

3 Experiments 20
3.1 Result tables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20
3.2 Line graphs of running time . . . . . . . . . . . . . . . . . . . . . 22
3.3 Bar charts of comparisons . . . . . . . . . . . . . . . . . . . . . . 25
3.4 Overall comment . . . . . . . . . . . . . . . . . . . . . . . . . . . 26

4 Project organization and Programming notes 27


4.1 Project organization . . . . . . . . . . . . . . . . . . . . . . . . . 27
4.2 Programming notes . . . . . . . . . . . . . . . . . . . . . . . . . . 28

5 References 28

1
Lab3: Sorting Algorithms 21120462 - Do Khai Hung

1 Introduction
Algorithm plays a vitally important in computer science. It provides consis-
tency in solving similar tasks with a predictable and desirable outcome. Among
algorithms, sorting algorithms are regarded as the gateway to the world of al-
gorithms in programming. Various sorting algorithms require demand about
considering about the feasibility and effectiveness of each algorithm. In order to
address that requirements, this scientific work studies on sorting algorithms in
terms of:

• Time complexity

• Space complexity

Thereby, it objectively evaluate the applicability of algorithms for specific con-


texts.

2 Algorithms
2.1 Selection Sort
1. Idea: In computer science, selection sort is an in-place comparison sort-
ing algorithm. Idea of this algorithm has derived from separating input
list into twos part: a left part of sorted items and the rest part containing
unsorted items. By finding the smallest(greatest or depending specific con-
dition), pushing back the left sorted sublist, repeat this process with the
right rest part, sorted list will be built up from left to right.
2. Pseudo Code:

1: procedure selection sort(a[],size)


2: for i = 0 to size-1 do
3: minIndex ← i
4: for j = i + 1 to size do
5: if a[i] < a[minIndex] then
6: minIndex ← j
7: end if
8: end for
9: if minIndex! = i then
10: swap(a[i], a[minIndex])
11: end if
12: end for
13: end procedure

2
Lab3: Sorting Algorithms 21120462 - Do Khai Hung

3. Complexity and Stability

• Time complexity
– Worst case: O(n2 )
When we sort in ascending (descending) order and the list is in
descending(ascending) order , the worst case occurs.
– Best case: O(n2 )
It occurs when the list is sorted
– Average case: O(n2 )
when elements in the list order randomly
• Space complexity(auxiliary)
O(1) because two extra variables minIndex and temp(swap) are used.
• Stability: No.

4. Application

• In small list with elements nearly sorted


• Cost of swapping does not matter
• Auxiliary memory is limited

5. Enhancement

• We can use min max selection sort to ensure that in each iteration we
swap a[i] with max or min elements in the rest unsorted list and use
two pointer technique to reduce range need sorting.
• Heap sort (in 2.11 ).

3
Lab3: Sorting Algorithms 21120462 - Do Khai Hung

2.2 Insertion Sort


1. Idea: Insertion sort is based on idea that find correct position of element
in the left sorted list in each iteration. It compares the current element
with the left elements in the sorted array in turn. If the current element
is greater, then it leaves the element in its place and moves on to the next
element else it finds its correct position in the sorted array and moves it to
that position. This is done by shifting all the elements, which are larger
than the current element, in the sorted array to one position ahead.
2. Pseudo Code:
1: procedure insertion sort(a[],size)
2: for i = 1 to size do
3: key ← a[i]
4: j ←i−1
5: while a[j] > key do
6: arr[j + 1] ← arr[j]
7: j ←j−1
8: end while
9: a[j + 1] ← key
10: end for
11: end procedure

3. Complexity and Stability


• Time complexity
– Worst case: O(n2 )
When we sort in ascending (descending) order and the list is in
descending(ascending) order , the worst case occurs.
– Best case: O(n)
It occurs when the list is sorted. For each iteration in outer loop,
inner loop does not run at all.
– Average case: O(n2 )
when elements in the list order randomly
• Space complexity(auxiliary)
O(1) because an extra variable key is used.
• Stability: Yes

4. Application
• A list with small number of elements.
• The list nearly sorted (Just have a few elements placed in wrong posi-
tion)
• Auxiliary memory is limited
5. Enhancement
• Binary insertion sort: using binary search to find the correct position
of elements quickly and shift all elements to the right position.
• Shell sort

4
Lab3: Sorting Algorithms 21120462 - Do Khai Hung

2.3 Bubble Sort


1. Idea: In the bubble sort technique, each of the elements in the list
is compared to its adjacent element. If they are in wrong placed order,
swap them. Therefore, in each iteration we ”bubble” the largest (smallest)
element of the right unsorted part .
2. Pseudo Code:

1: procedure bubble sort(a[],size)


2: for i = 0 to size do
3: for j = 0 to size - i -1 do
4: if a[j] > a[j + 1] then
5: swap(a[j], a[j + 1])
6: end if
7: end for
8:

3. Complexity and Stability

• Time complexity
– Worst case: O(n2 )
– Best case: O(n2 )
– Average case: O(n2 )
You can see here are two loops so time complexity is O(n2 )
• Space complexity(auxiliary)
O(1) because a few extra variables are used.
• Stability: Yes.

4. Application

• Simple and short code is preferred


• Auxiliary memory is limited
• In computer graphics, it is popular for its capability to detect a tiny
error (like a swap of just two elements) in almost-sorted arrays and fix
it with just linear complexity (2n).

5. Enhancement

• Using a flag checking whether swapping happens in iteration or not, if


not the list is sorted and break the loop.
• Shaker sort.
• Odd–even sort. It functions by comparing all odd/even indexed pairs
of adjacent elements in the list and and switched.Repeating this for
even/odd indexed pairs (of adjacent elements).Then it alternates be-
tween odd/even and even/odd steps until the list is sorted.

5
Lab3: Sorting Algorithms 21120462 - Do Khai Hung

2.4 Shaker Sort


1. Idea: Shaker Sort is a variation of Bubble sort. The Bubble sort al-
gorithm always traverses elements from left to right in order to find the
ith(st) largest and move it to the right position. With two pointers tech-
nique, shaker Sort traverses through a given array in both directions alter-
natively. Shaker sort does not go through the unnecessary iteration making
it efficient for large arrays, which make this algorithm stand out more than
Bubble sort.
2. Pseudo Code:

1: procedure shaker sort(a[],size)


2: lef t = 0, index = 0, right = size − 1
3: while lef t < right do
4: for i = lef t to right do
5: if a[i] > a[i + 1] then
6: swap(a[i], a[i + 1])
7: index ← i
8: end if
9: end for
10: right ← index
11: for i = right downto left do
12: if a[i] < a[i − 1] then
13: swap(a[i], a[i − 1])
14: index ← i
15: end if
16: end for
17: lef t ← index
18: end while
19: end procedure=0

3. Complexity and Stability

• Time complexity
– Worst case: O(n2 )
– Best case: O(n)
When this list is sorted, the best case occurs
– Average case: O(n2 )
– if every element is at a position that differs by at most k (k ≥
1) from the position it is going to end up in, the complexity of
cocktail shaker sort becomes O(kn).
• Space complexity(auxiliary)
O(1) because a few extra variables are used.
• Stability: Yes

4. Application

• A list with small number of elements.


• Auxiliary memory is limited

6
Lab3: Sorting Algorithms 21120462 - Do Khai Hung

2.5 Shell Sort


1. Idea: Shellsort, also known as Shell sort or Shell’s method, is an in-
place comparison sort. It can be seen as either a generalization of sorting
by exchange (bubble sort) or sorting by insertion (insertion sort).Initially,
It compare elements in list by pair with far distance and use insertion
movement (in insertion sort) and put it in right place and then gradually
reduce comparing distance down to 1.
2. Pseudo Code:

1: procedure shell sort(a[],size)


2: gap = size/2
3: while gap > 0 do
4: for i = gap to size do
5: temp ← a[i]
6: j=i
7: while j > gap and a[j − gap] > temp do
8: a[j] ← a[j − gap]
9: j ← j − gap
10: end while
11: a[j] ← temp
12: end for
13: gap ← gap/2
14: end while
15: end procedure

3. Complexity and Stability

• Time complexity
– Worst case: O(n2 )
Or O(n*log 2 n) with Pratt gap sequence
– Best case: O(n*log(n))
It occurs when the list is sorted. The total number of comparisons
for each gap is equal to the size of the list.
– Average case: O(n*log(n))
It is around O(n1.25 ).
– Besides, depending on the selected sequence we have different com-
plexity computations.
• Space complexity(auxiliary)
Space complexity is O(1) because a few extra variables are used.
• Stability: No

4. Application

• Shellsort performs more operations and has higher cache miss ratio
than quicksort. However, since it can be implemented using little code
and does not use the call stack, some implementations of the qsort
function in the C standard library targeted at embedded systems use
it instead of quicksort. Shellsort is, for example, used in the uClibc

7
Lab3: Sorting Algorithms 21120462 - Do Khai Hung

library. For similar reasons, in the past, Shellsort was used in the
Linux kernel
• Shellsort can also serve as a sub-algorithm of introspective sort, to sort
short subarrays and to prevent a slowdown when the recursion depth
exceeds a given limit. This principle is employed, for instance, in the
bzip2 compressor
• When recursion exceeds a particular limit, we use shell sort.

5. Enhancement

• There are many recommends about the way we choose gaps. Latest
suggestion is Marcin Ciura’s gap sequence in 2001.

2.6 Heap Sort


1. Idea: Heap sort is a comparison-based sorting technique based on
binary Heap data structure. This algorithm include two processes: heapify
and heap sort. The first process, we will build a max(min) heap and then
in the second process the highest element is removed (i.e., the one at the
tree root) and the remaining elements are used to create a new max heap
tree. Repeat the second process until tree has one node left. That is similar
to the selection sort where we first find the minimum element and place it
at the beginning and repeat for the remaining.
2. Pseudo Code:

1: procedure heapify(a[],root,size)
2: j = root ∗ 2
3: key = a[root]
4: while j < size do
5: if j < size − 1 and a[j + 1] > a[j] then
6: j ←j+1
7: end if
8: if a[i] ≤ key then break
9: end if
10: swap(a[j], a[root])
11: root ← j
12: j ←j∗2
13: end while
14: end procedure
15: procedure heap sort(a[],size)
16: for i = size/2 downto 0 do
17: heapify(a,i,size)
18: end for
19: for i = size − 1 downto 0 do
20: swap(a[0], a[i])
21: heapify(a,0,i)
22: end for
23: end procedure

8
Lab3: Sorting Algorithms 21120462 - Do Khai Hung

3. Complexity and Stability

• Time complexity
– Worst case: O(n*log(n))
Because the height of heap tree is log(n), every time we get the
root node and put it in the sorted list, we have to rebuild the
max(min)-heap tree with path has length equal to height of tree.
– Best case: O(n)
It occurs when all elements in the list is identical.
– Average case: O(n*log(n))
• Space complexity(auxiliary)
Space complexity is O(1) because a few extra variables are used.
• Stability: No

4. Application

• The list has a large number of elements


• Saving auxiliary memory
• Systems concerned with security and embedded systems such as Linux
Kernel use Heap Sort because of the O(nlogn) upper bound on Heap-
sort’s running time and constant O(1) upper bound on its auxiliary
storage.
• Besides, heap data structure is enormously used especially priorty
queue, heap implemented priority queues are used in Graph algorithms
like Prim’s Algorithm and Dijkstra’s algorithm.Order statistics: The
Heap data structure can be used to efficiently find the ith smallest (or
largest) element in an array.

9
Lab3: Sorting Algorithms 21120462 - Do Khai Hung

2.7 Merge Sort


1. Idea: The Merge Sort algorithm is a sorting algorithm that is based
on the Divide and Conquer paradigm. In this algorithm, the list is initially
divided into two equal halves and then they are combined in a sorted manner
and reassign to original list. In each part, it continuously repeat this process.
Finally, we have sorted list.
2. Pseudo Code:

1: procedure merge array(a[],b[],na,nb)


2: posa = posb = pos = 0
3: res ← ∅
4: while posa < na and posb < nb do
5: if a[posa] < b[posb] then
6: res[pos] ← a[posa]
7: posa ← posa + 1
8: else
9: res[pos] ← b[posb]
10: posb ← posb + 1
11: end if
12: pos ← pos + 1
13: end while
14: while posa < na do
15: res[pos] ← a[posa]
16: posa ← posa + 1
17: pos ← pos + 1
18: end while
19: while posb < nb do
20: res[pos] ← b[posb]
21: posb ← posb + 1
22: pos ← pos + 1
23: end while
24: a ← res
25: end procedure
26: procedure merge sort(a[],start,end)
27: if end == start then return
28: end if
29: mid = (start + end)/2
30: merge sort(a,start,mid)
31: merge sort(a,mid+1,end)
32: merge array(a+start,a+mid+1,mid-start+1,end-mid)
33: end procedure

10
Lab3: Sorting Algorithms 21120462 - Do Khai Hung

3. Complexity and Stability

• Time complexity : O(nlogn)


– Merge sort use divide and conquer algorithm. Each process divide
list into two part so complexity is O(nlogn) in every situation.
• Space complexity(auxiliary)
Space complexity is O(n) because res variable is used to store tempo-
rary merged list.
• Stability: Yes

4. Application

• Merge Sort is useful for sorting linked lists in O(N log N) time. In the
case of linked lists, the case is different mainly due to the difference in
memory allocation of arrays and linked lists. Unlike arrays, linked list
nodes may not be adjacent in memory.
• Drawbacks: Slower compared to the other sort algorithms in smaller
input, require O(n) addition memory space, loop over all list even if it
is sorted

5. Enhancement

• It requires equal amount of additional space as the unsorted array.


Hence its not at all recommended for searching large unsorted arrays.
• In all case, merge sort has time complexity of O(n*log(n)) so it is less
used than other efficient sorting algorithms.
• Use merge sort with linked list to optimize the disadvangtage of using
auxiliary memory.

11
Lab3: Sorting Algorithms 21120462 - Do Khai Hung

2.8 Quick Sort


1. Idea: The Quick Sort algorithm is a sorting algorithm that is based
on the Divide and Conquer paradigm. In this algorithm, the pivot is cho-
sen from the list (here is the median element) and then use two pointers
technique so as to divide the list into two parts: the left sublist including
elements smaller than pivot and the right sublist including elements larger
than pivot. The next step is to sort two that sublists and then process
repeats.

2. Pseudo Code:

1: procedure partition(a[],size)
2: pivot = a[size/2]
3: lef t = 0
4: right = size − 1
5: while lef t < right do
6: while a[lef t] < pivot do
7: lef t ← lef t + 1
8: end while
9: while a[right] > pivot do
10: right ← right − 1
11: end while
12: if lef t < right then
13: swap(a[lef t], a[right])
14: right ← right − 1
15: lef t ← lef t + 1
16: end if
17: end while
18: return size/2
19: end procedure
20: procedure sort(a[],size)
21: if size ≤ 1 then return
22: end if
23: pos = parition(a, size)
24: sort(a,pos)
25: sort(a + pos + 1, size - pos - 1)
26: end procedure

12
Lab3: Sorting Algorithms 21120462 - Do Khai Hung

3. Complexity and Stability

• Time complexity
– Worst case: O(n2 )
When pivot always the minimum(maximum) element in the sort-
ing list, the worst case occurs
– Best case: O(n*log(n))
The best-case occurs when the pivot element is the middle element
or near to the middle element of sorted list afterwards.
– Average case: O(n*log(n))
when elements in the list order randomly
• Space complexity(auxiliary)
Space complexity is O(n), sum of partition position variables returned
in sort function .
• Stability: No

4. Application

• The quick sort is in place as it does not require any additional storage.
• Numerical computations and in scientific research, for accuracy in
calculations most of the efficiently developed algorithm uses priority
queue and quick sort is used for sorting
• It is used to implement primitive type methods.
• The list is sorted.

5. Enhancement

• . Normally tail recursion is not preferable, but in this case tail re-
cursion is combined with the notion of solving the smallest partition
first, which drastically improves the space complexity to O(logn) from
O(n).
• Choose pivot randomly in range [left - right]
• There are many variants of quick sort with with distinct advantages:
Lomuto’s Partitioning, Hoare’s Partitioning, Three-way Partitioning,
Dutch National Flag, Multi-pivot quicksort, External quicksort, Three-
way radix quicksort, Quick radix sort, BlockQuicksort, and so on.

13
Lab3: Sorting Algorithms 21120462 - Do Khai Hung

2.9 Counting Sort


1. Idea: Counting sort is a non comparison sorting based on keys between
a specific range. It works by counting the number occurrences of elements
in array, and then accumulating elements from left to right(prefix sum tech-
nique) to map the count and find its correct position in the auxiliary array.

2. Pseudo Code:

1: procedure counting sort(a[],size)


2: max = max a
3: min = min a
4: countSize = max − min + 1
5: res ← ∅
6: count ← ∅
7: for i = 0 to size - 1 do
8: count[a[i] − min] ← count[a[i] − min] + 1
9: end for
10: for i = 0 to countSize do
11: count[i] ← count[i] + count[i − 1]
12: end for
13: for i = size − 1 downto 0 do
14: res[count[a[i] − min]] ← a[i]
15: count[a[i] − min] ← count[a[i] − min] − 1
16: end for
17: a ← res
18: end procedure

3. Complexity and Stability

• Time complexity
– Worst case: O(k)
With k = largest element - smallest element + 1(range of ele-
ments). When largest is significantly larger than others, k ¿¿ n,
the worst case occurs.
– Best case: O(n)
The best case occurs when the all elements have the same key so
k = 1, thus the total time complexity is O(n+1) i.e O(n) which is
linear.
– Average case: O(n+k)
As you can see, in this algorithm, the first loop we iterate n times,
and the second loop we use prefix sum and loop in k times, so if
neither value of n nor value of k are dominant, time complexity of
this algorithm O(n+k).
• Space complexity(auxiliary)
Space complexity is O(n+k), we need a list count ( with size = range
of elements) and a list res(with size = the elements number of list).
• Stability: Yes

14
Lab3: Sorting Algorithms 21120462 - Do Khai Hung

4. Application

• If the range of input data is not much bigger than the number of
objects to be sorted, counting sort is efficient.
• Counting sort is very efficient in the cases where range is comparable
to number of input elements as it performs sorting in linear time and
can be a advantage in such cases over other sorting algorithms such as
quick sort.
• Since counting sort is suitable for sorting numbers that belong to a
well-defined, finite and small range, it can be used as a subprogram in
other sorting algorithms like radix sort which can be used for sorting
numbers having a large range

5. Enhancement

• . We can be combined second and third loops.; in the second loop,


instead of calculating the position where items with key i should be
placed in the output, simply append Count[i] copies of the number i
to the output.
• For data in which the maximum key size is significantly smaller than
the number of data items, counting sort may be parallelized by split-
ting the input into subarrays of approximately equal size, processing
each subarray in parallel to generate a separate count array for each
subarray, and then merging the count arrays.

2.10 Radix Sort


1. Idea: Radix sort is a non comparison sorting which optimized disad-
vantage of counting sort if range of elements is too big. Instead loop for
range of elements, Radix sort is to do digit by digit sort starting from least
significant digit to most significant digit and use counting sort in each pro-
cess while preserving the ordering of the prior step. In this algorithm, to
sort with negative and positive numbers, I divide the list into two part and
using radix sort for each part and then merge them into root list.

2. Pseudo Code:

15
Lab3: Sorting Algorithms 21120462 - Do Khai Hung

1: procedure positive radix sort(a[],size)


2: exp = log10 (max a)
3: right = size − 1
4: div = 1
5: res ← ∅
6: while exp ≥ 0 do
7: count ← ∅
8: for i = 0 to size - 1 do
9: count[(a[i]/div) mod 10] ← count[(a[i]/div)mod10] + 1
10: end for
11: for i = 1 to 9 do
12: count[i] ← count[i] + count[i − 1]
13: end for
14: for i = size − 1 downto 0 do
15: res[count[ (a[i]/div) mod 10]] ← a[i]
16: res[count[ (a[i]/div) mod 10]] ← res[count[ (a[i]/div) mod 10]] − 1
17: end for
18: a ← res
19: exp ← exp − 1
20: div ← div ∗ 10
21: end while
22: end procedure
23: procedure radix sort(a[],size)
24: lef t = 0
25: right = size − 1
26: while lef t < right do
27: while lef t < right and a[lef t] < 0 do
28: lef t ← lef t + 1
29: end while
30: while right ≥ 0 and a[rightt] ≥ 0 do
31: right ← right + 1
32: end while
33: swap(a[lef t], a[right])
34: end while
35: swap(a[lef t], a[right])
36: positiveSize = size − lef t
37: positive radix sort(a + lef t,positiveSize)
38: a2 ← ∅
39: for i = 0 to left - 1 do
40: a2[i] ← −a[i]
41: end for
42: positive radix sort(a2,left)
43: for i = 0 to left - 1 do
44: a2[lef t − 1 − i] ← −a2[i]
45: end for
46: end procedure

16
Lab3: Sorting Algorithms 21120462 - Do Khai Hung

3. Complexity and Stability


• Time complexity : O()
– Worst case: O(n*d)
– Best case: O(n*d)
– Average case: O(n*d)
With d is number of digits of maximum element. We loop from
least significant digit to most significant digit( d times) and sort
array with counting sort( n times)
– The above algorithm, i choose base 10 when we choose base n, it
turns out counting sort.
• Space complexity(auxiliary)
Space complexity is O(n+k+l), l is the number of negative elements,
n is the number of elements, k is the base chosen, here is 10.
• Stability: Yes
4. Application
• The numbers of list are in the large range.
• DC3 algorithm (Kärkkäinen-Sanders-Burkhardt) while making a suffix
array..
• Radix sort can be applied to data that can be sorted lexicographically,
such as words and integers. It is also used for stably sorting strings.
• It is a good option when the algorithm runs on parallel machines,
making the sorting faster. To use parallelization, we divide the in-
put into several buckets, and then sort each bucket because they are
independent each other.
5. Enhancement
• In-place MSD radix sort implementations.
Binary MSD radix sort, also called binary quicksort, can be imple-
mented in-place by splitting the input array into two bins - the 0s bin
and the 1s bin.Sort and move two pointers until the 0s bin and the 1s
bin reach each other.
• Hybrid approaches
Combine counting sort and insertion sort. A good implementation of
insertion sort is fast for small arrays, stable, in-place, and can signifi-
cantly speed up radix sort.
• Tree-based radix sort
Building a tree and using pre-order traversal.

2.11 Flash Sort


1. Idea: Flash sort is an in-place sorting algorithm which optimize sorting
speed with approximately linear time complexity . This algorithm include
steps: classify the data into sets, permute the elements to their correct
subclass in the order, and sort (here’s using insertion sort) according to
each subclass.
2. Pseudo Code:

17
Lab3: Sorting Algorithms 21120462 - Do Khai Hung

1: procedure flash sort(a[],size)


2: lSize = size ∗ 0.43
3: if lSize ≤ 1 then
4: lSize ← 2
5: end if
6: min ← min a
7: max ← max a
8: c ← (lSize − 1)/( max − min)
9: if max == min then
10: return
11: end if
12: L←∅
13: for i = 0 to size - 1 do
14: L[c ∗ (a[i] − min)] ← L[c ∗ (a[i] − min)] + 1
15: end for
16: for i = 1 to lSize - 1 do
17: L[i] ← L[i] + L[i − 1]
18: end for
19: count ← 0
20: i←0
21: k ← c ∗ (a[0] − min)
22: while count < size do
23: while i > L[k] − 1 do
24: k ← c ∗ (a[i] − min)
25: i←i+1
26: end while
27: x ← a[i]
28: while i < L[k] − 1 do
29: swap(x,a[L[k]])
30: L[k] ← L[k] − 1
31: k ← c ∗ (x − min)
32: count ← count + 1
33: end while
34: swap(x,a[L[k]])
35: L[k] ← L[k] − 1
36: count ← count + 1
37: end while
38: for k = 1 to lSize - 1 do
39: for k = L[k − 1] to L[k] - 1 do
40: key = a[i]
41: j =i−1
42: while j ≥ 0 and key < a[j] do
43: a[j + 1] ← a[j]
44: j =j−1
45: end while
46: a[j + 1] ← key
47: end for
48: end for
49: end procedure

18
Lab3: Sorting Algorithms 21120462 - Do Khai Hung

m is the number of classes which should be 0.43*n. And we have the formula
to define the class of the element ai :
 
(m − 1) (ai − mina )
kai = + 1.
maxa − mina

3. Complexity and Stability

• Time complexity
– Worst case: O(n2 )
When the maximum element has a large difference from the other
elements. So just a few classes(buckets) is used and insertion sort
with time complexity O(n2 ) lead time complexity in this case is
O(n2 )
– Best case: O(n)
When data set is balanced, most of the classes( buckets) have
elements, the best case occurs.
– Average case: O(n)
• Space complexity(auxiliary)
Space complexity is O(m), this algorithm doesn’t need auxiliary array.
• Stability: No. If stability is required, we can use an array to get
temporary output, and instead of step permutation, we map count
array to place elements in right positions. But space complexity in
this case is O(m + n).

4. Application

• The keys of elements doesn’t differ too much .

5. Enhancement

• In-placed flash sort.


This algorithm I mentioned above. The first and third steps are the
same as in flash sort. In the second step, an additional array is used
as a buffer to hold the permuted elements.

19
Lab3: Sorting Algorithms 21120462 - Do Khai Hung

3 Experiments
In this experiment, I will test on data sizes set: 10,000, 30,000, 50,000, 100,000,
300,000, and 500,000 elements in term of running time(ms) and comparisons fre-
quency.
The hardware I use to measure the experiment is below:

3.1 Result tables


Data order: Randomized
Data size 10,000 30,000 50,000
Resulting statics Running time Comparison Running time Comparison Running time Comparison
Selection sort 54.264 100,019,998 473.633 900,059,998 1316.49 2,500,099,998
Insertion sort 34.98 24,968,422 316.846 224,584,641 874.203 623,797,685
Bubble sort 405.209 100,010,001 3814.47 900,030,001 12307.9 2,500,050,001
Shaker sort 359.99 67,176,645 3380.09 600,798,217 9323.93 1,667,488,761
Shell sort 1.308 656,667 4.367 2,273,280 8.185 4,594,145
Heap sort 2.914 409,608 8.386 1,370,731 14.216 2,396,574
Merge sort 4.275 573,634 12.929 1,907,122 20.424 3,333,614
Quick sort 1.005 181,362 2.795 592,769 4.332 1,062,341
Counting sort 0.151 90,001 0.899 270,003 0.964 415,539
Radix sort 1.419 160,065 5.655 570,079 8.549 950,079
Flash sort 0.888 116,314 2.426 345,210 2.561 578,163

Table 1: Data order: Randomized - 1

Data order: Randomized


Data size 100,000 300,000 500,000
Resulting statics Running time Comparison Running time Comparison Running time Comparison
Selection sort 5385.63 10,000,100,001 88975.9 90,000,300,001 243066 250,000,500,001
Insertion sort 3626.07 2,500,234,668 50176.4 22,464,031,246 151803 62,536,305,959
Bubble sort 47698.9 10,000,162,752 455597 89,999,461,512 1168770 250,000,847,901
Shaker sort 44679.8 6,675,237,202 348108 60,089,270,904 959505 166,558,232,256
Shell sort 17.512 10,044,334 56.268 34,552,099 98.488 63,914,833
Heap sort 30.728 5,094,869 99.587 16,697,055 182.04 28,919,442
Merge sort 44.385 7,065,912 129.602 23,082,823 224.234 39,882,535
Quick sort 9.593 2,275,499 28.3 7,281,639 47.222 12,463,689
Counting sort 2.391 765,539 3.868 2,165,539 5.894 3,565,539
Radix sort 17.254 1,900,079 50.119 5,700,079 84.122 9,500,079
Flash sort 5.495 1,163,015 15.042 3,258,823 29.143 5,807,117

Table 2: Data order: Randomized - 2

20
Lab3: Sorting Algorithms 21120462 - Do Khai Hung

Data order: Sorted


Data size 10,000 30,000 50,000
Resulting statics Running time Comparison Running time Comparison Running time Comparison
Selection sort 52.824 100,019,998 477.691 900,059,998 1327.55 2,500,099,998
Insertion sort 0.019 19,999 0.056 59,999 0.094 99,999
Bubble sort 59.49 100,010,001 531.906 900,030,001 1498.6 2,500,050,001
Shaker sort 0.013 20,002 0.032 60,002 0.053 100,002
Shell sort 0.257 360,042 0.83 1,170,050 1.48 2,100,049
Heap sort 2.184 425,953 7.071 1,417,079 12.263 2,481,839
Merge sort 3.506 465,243 10.339 1,529,915 17.028 2,672,827
Quick sort 0.353 154,960 1.025 501,930 1.956 913,851
Counting sort 0.122 90,003 0.361 270,003 0.623 450,003
Radix sort 1.33 160,065 5.026 570,079 8.272 950,079
Flash sort 0.386 137,196 1.156 411,596 1.945 685,996

Table 3: Data order: Sorted - 1

Data order: Sorted


Data size 100,000 300,000 500,000
Resulting statics Running time Comparison Running time Comparison Running time Comparison
Selection sort 11597.2 10,000,199,998 91081.3 90,000,599,998 275764 250,000,999,998
Insertion sort 0.2 199,999 0.722 599,999 1.014 999,999
Bubble sort 6595.39 10,000,100,001 72605.1 90,000,300,001 219263 250,000,500,001
Shaker sort 0.251 200,002 0.347 600,002 0.591 1,000,002
Shell sort 3.22 4,500,051 10.857 15,300,061 18.171 25,500,058
Heap sort 25.871 5,263,213 83.718 17,198,473 142.9 29,758,469
Merge sort 34.519 5,645,659 105.274 18,345,947 177.304 31,517,851
Quick sort 3.984 1,927,692 11.009 6,058,229 18.106 10,310,734
Counting sort 1.268 900,003 4.04 2,700,003 7.591 4,500,003
Radix sort 17.081 1,900,079 61.642 6,600,093 103.925 11,000,093
Flash sort 3.86 1,371,996 11.965 4,115,996 20.181 6,859,996

Table 4: Data order: Sorted - 2

Data order: Reversed


Data size 10,000 30,000 50,000
Resulting statics Running time Comparison Running time Comparison Running time Comparison
Selection sort 57.058 100,019,998 504.089 900,059,998 1447.01 2,500,099,998
Insertion sort 72.178 50,014,999 646.505 450,044,999 1920.5 1,250,074,999
Bubble sort 611.76 100,010,001 5539.27 900,030,001 15291.3 2,500,050,001
Shaker sort 571.522 100,005,001 5182.27 900,015,001 14387.8 2,500,025,001
Shell sort 0.376 475,175 1.25 1,554,051 2.359 2,844,628
Heap sort 2.089 393,723 6.784 1,323,591 11.951 2,316,897
Merge sort 3.709 466,442 10.696 1,543,466 18.12 2,683,946
Quick sort 0.407 164,957 1.214 531,927 2.281 963,848
Counting sort 0.125 90,003 0.608 270,003 0.884 450,003
Radix sort 1.351 160,065 4.923 570,079 8.319 950,079
Flash sort 0.378 124,999 1.166 374,999 2.092 624,999

Table 5: Data order: Reversed - 1

Data order: Reversed


Data size 100,000 300,000 500,000
Resulting statics Running time Comparison Running time Comparison Running time Comparison
Selection sort 7955.78 10,000,199,998 99869.9 90,000,599,998 270001 250,000,999,998
Insertion sort 11321.3 5,000,149,999 111872 45,000,449,999 327706 125,000,749,999
Bubble sort 79920.1 10,000,100,001 665506 90,000,300,001 1953010 250,000,500,001
Shaker sort 60076.2 10,000,050,001 578294 90,000,150,001 1768820 250,000,250,001
Shell sort 4.86 6,089,190 16.126 20,001,852 26.972 33,857,581
Heap sort 24.774 4,929,161 79.911 16,216,257 138.909 28,117,301
Merge sort 34.62 5,667,898 105.155 18,408,314 180.343 31,836,410
Quick sort 4.598 2,027,689 12.952 6,358,226 21.129 10,810,731
Counting sort 1.256 900,003 3.529 2,700,003 6.303 4,500,003
Radix sort 17.105 1,900,079 62.202 6,600,093 103.868 11,000,093
Flash sort 3.664 1,249,999 11.063 3,749,999 18.973 6,249,999

Table 6: Data order: Reversed - 2

21
Lab3: Sorting Algorithms 21120462 - Do Khai Hung

Data order: Nearly Sorted


Data size 10,000 30,000 50,000
Resulting statics Running time Comparison Running time Comparison Running time Comparison
Selection sort 55.708 100,019,998 475.16 900,059,998 1380.71 2,500,099,998
Insertion sort 0.103 77,779 0.42 310,607 0.417 325,303
Bubble sort 60.371 100,010,001 578.53 900,030,001 1588.08 2,500,050,001
Shaker sort 0.792 175,119 2.448 550,996 3.084 699,039
Shell sort 0.344 401,066 1.224 1,327,751 1.955 2,299,900
Heap sort 2.164 425,885 7.127 1,417,021 12.289 2,481,547
Merge sort 3.75 499,460 10.957 1,637,882 17.509 2,776,579
Quick sort 2.756 154,996 1.033 501,966 1.939 913,887
Counting sort 0.492 90,003 0.639 270,003 0.597 450,003
Radix sort 1.307 160,065 4.853 570,079 8.25 950,079
Flash sort 0.383 137,176 1.148 411,576 1.919 685,976

Table 7: Data order: Nearly Sorted - 1


Data order: Nearly Sorted
Data size 100,000 300,000 500,000
Resulting statics Running time Comparison Running time Comparison Running time Comparison
Selection sort 10652.1 10,000,199,998 106295 90,000,599,998 276310 250,000,999,998
Insertion sort 0.633 452,723 1.429 833,643 1.618 1,180,173
Bubble sort 7826.34 10,000,100,001 86051.9 90,000,300,001 222587 250,000,500,001
Shaker sort 2.776 675,037 2.824 1,061,700 3.317 1,519,037
Shell sort 4.562 4,745,776 15.122 15,482,595 19.579 25,686,319
Heap sort 26.934 5,263,193 89.442 17,198,433 143.025 29,757,509
Merge sort 42.614 5,741,519 104.425 18,435,873 225.035 31,620,461
Quick sort 8.361 1,927,724 14.082 6,058,273 23.722 10,310,782
Counting sort 2.812 900,003 8.425 2,700,003 14.643 4,500,003
Radix sort 17.539 1,900,079 70.927 6,600,093 105.78 11,000,093
Flash sort 3.878 1,371,976 11.99 4,115,976 20.129 6,859,976

Table 8: Data order: Nearly Sorted - 2

3.2 Line graphs of running time

Figure 1: Line graph of running time for randomized input

22
Lab3: Sorting Algorithms 21120462 - Do Khai Hung

- In term of randomize order input, there are four algorithms which are com-
pletely different from all other algorithms. In particular, Bubble sort runs the
slowest (because it takes time for swapping action). Shaker sort, although im-
proved over Bubble sort, is still very slow and then selection sort and insertion
sort are both time complexity O(n2 ) algorithms. Time complexity O(nlogn) and
O(n) algorithms have negligible running time when compared to the above 4
algorithms .

Figure 2: Line graph of running time for sorted input

- In term of sorted order input, two algorithms, bubble sort and selection sort,
have a much longer running time than the other algorithms. Selection sort is
”stably higher” with selection of elements moved. Although in best case, Bubble
sorted is still very low when compared to others algorithms. Besides, sorted order
input is also the best case of insertion sort and shaker sort algorithms with time
complexity O(n). Time complexity O(nlogn) and O(n) algorithms have negligible
running time when compared to the bubble sort and selection sort.

23
Lab3: Sorting Algorithms 21120462 - Do Khai Hung

Figure 3: Line graph of running time for reversed input

- In term of reversed order input, there are four algorithms which are
completely different from all other algorithms. The worst case of selection sort,
bubble sort, shaker sort, insertion sort occurs with time complexity O(n2 ).

Figure 4: Line graph of running time for nearly sorted input

In general, the chart of the running time with nearly sorted order input is
quite similar to the one with sorted order input.

24
Lab3: Sorting Algorithms 21120462 - Do Khai Hung

3.3 Bar charts of comparisons

Figure 5: Bar graph of comparison frequency for randomized input

- In term of randomized order input, there are four algorithms which are com-
pletely different from all other algorithms. Selection sort and Bubble sort have
largest the number of comparisons because they have n2 of base comparisons in
loops. Shaker sort and Insertion sort are optimized a bit but it they all are not
significant with other algorithms having fewer comparisons.

Figure 6: Bar graph of comparison frequency for sorted input

- The sorted order input is the best case of Insertion sort and Shaker sort with
time complexity O(n) so their number of comparisons are much smaller than
Selection sort and Bubble sort.

25
Lab3: Sorting Algorithms 21120462 - Do Khai Hung

Figure 7: Bar graph of comparison frequency for reversed input

- The reversed order input is the worst case of Insertion sort and Shaker sort
with time complexity O(n2 ) so their number of comparisons are increase, but the
number of insertion sort is just about a half of three rest O(n2 ) time complexity
algorithms.

Figure 8: Bar graph of comparison frequency for nearly sorted input

In general, the bar of the running time with nearly sorted order input is kind of
similar to the one with sorted order input.
3.4 Overall comment
- Through testing with data sets, we can objectively evaluate the effective-
ness of the algorithms. From my point of views, Flash sort the the best sorting
algorithms with ”flash” speed with time complexity O(n) in most cases, whereas
the Bubble is always the worst one with comparisons frequency and time run-
ning with overwhelming numbers. In addition, insertion sort is fairly good when
compared average time complexity O(n2 ).

26
Lab3: Sorting Algorithms 21120462 - Do Khai Hung

• Stable algorithms:

– Selection sort. With fixed cost for two loops, selection sort is a sta-
ble algorithm notwithstanding the giant number of time running and
comparisons.
– Shell sort. Not use recursion and sort quickly in various input order
cases.
– Heap sort. Application of heap data structure, the stability is shown
with time complexity O(nlogn) in every case.
– Merge sort. Divide and conquer approach make this algorithms sta-
bility in all case. However, it need additional memory with O(n).
– Radix sort. Sorting the elements by processing them in multiple passes,
digit by digit, the overall cost is O(d*n).
– Flash sort. This distribution sorting algorithm shows linear computa-
tional complexity O(n) for uniformly distributed data sets, that’s why
i think it’s stable and effective algorithm.

• Unstable algorithms:

– Insertion sort. It has shown inefficiency when the data is reversed and
randomized. However, by taking advantage of the available sorting
of the data, I thinks insertion sort is adequate algorithm and easy to
implement, well-suited for sorting with small datasets.
– Bubble sort. Substantial difference regarding running time between
data order randomized, reversed and sorted, nearly sorted make this
algorithms is truly not stable. Besides, the time running is too low to
apply in practice.
– Shaker sort. Pretty similar to Bubble sort, but it is surpass in sorted
and nearly sorted input order case with time complexity O(n).
– Quick sort. Although it has quite good performance in this experiment,
If pivot chosen is median of list, the program become disastrous with
time running and stack memory consumed.
– Counting sort. As well as Quick sort, if the difference of the largest
and smallest elements is much more than size of list, it will cost a lot
of additional memory and the time running will be very low.

4 Project organization and Programming notes


4.1 Project organization
• The whole project is organized according to the object-oriented program-
ming structure.

– Each sort is a class, and the unique class Sort implements all sort-
ing algorithm including two function: calculating running time and
counting comparison frequency in specified algorithms.
– Class Helper for small tasks, such as read, write file, generate data,
swap items.

27
Lab3: Sorting Algorithms 21120462 - Do Khai Hung

– Class Comparison Mode and Algorithm Mode to run specified


command.
– Class Dictionary is responsible for validating input for command
entered from user.
– Constants Converter header file, define options to integer values.

4.2 Programming notes


• IDE I use in this project is Visual Studio Community 2019, C++ 14.

• The library Regex, check if input is number.

• The library Map. Key is command input string and value is equivalent
integer value.

5 References
[1] Selection sort - Wikipedia https://en.wikipedia.org/wiki/Selection_
sort

[2] Cocktail (Shaker) Sort - GeeksforGeeks https://www.geeksforgeeks.org/


cocktail-sort/.

[3] Odd-Even sort - Wikipedia https://en.wikipedia.org/wiki/Odd%E2%80%


93even_sort.

[4] Bubble sort - GeeksforGeeks https://www.geeksforgeeks.org/


bubble-sort/

[5] Shell sort - Wikipedia https://en.wikipedia.org/wiki/Shellsort

[6] Applications of Heap Data Structure https://www.geeksforgeeks.org/


applications-of-heap-data-structure/

[7] Improvement on the Quick Sort Algorithm - GeeksforGeeks https://www.


geeksforgeeks.org/improvement-on-the-quick-sort-algorithm/

[8] Quick Sort - Wikipedia https://en.wikipedia.org/wiki/Quicksort

[9] Counting Sort - Wikipedia https://en.wikipedia.org/wiki/Counting_


sort

[10] Flash Sort - Wikipedia https://en.wikipedia.org/wiki/Flashsort

28

You might also like