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

07 SortingAlgorithms

The document discusses various sorting algorithms and their analysis. It begins by defining sorting as organizing data into ascending or descending order. It then describes several common sorting algorithms like bubble sort, selection sort, insertion sort, and Shellsort. For each algorithm, it provides pseudocode and analyzes their time complexity, with most having a best, average, and worst case of O(n2). The document aims to analyze the performance of different sorting techniques.

Uploaded by

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

07 SortingAlgorithms

The document discusses various sorting algorithms and their analysis. It begins by defining sorting as organizing data into ascending or descending order. It then describes several common sorting algorithms like bubble sort, selection sort, insertion sort, and Shellsort. For each algorithm, it provides pseudocode and analyzes their time complexity, with most having a best, average, and worst case of O(n2). The document aims to analyze the performance of different sorting techniques.

Uploaded by

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

Sorting Algorithms

Sorting
• Sorting is a process that organizes a collection of data into either ascending or
descending order.
• An internal sort requires that the collection of data fit entirely in the
computer’s main memory.

• We can use an external sort when the collection of data cannot fit in the
computer’s main memory all at once but must reside in secondary storage such
as on a disk.

• We will analyze only internal sorting algorithms.

• Majority of programming projects use a sort somewhere, and in many cases,


the sorting cost determines the running time.
• A comparison-based sorting algorithm makes ordering decisions only on the
basis of comparisons.
Sorting Algorithms
• There are many sorting algorithms, such as:
– Bubble Sort
– Selection Sort
– Insertion Sort
– Shell Sort
– Radix Sort
– Merge Sort
– Quick Sort
– Heap Sort
• The first three are the foundations for faster
and more efficient algorithms.
Bubble Sort
• The list is divided into two sublists: sorted and
unsorted.
• The smallest element is bubbled from the unsorted
list and moved to the sorted sublist.
• After that, the wall moves one element ahead,
increasing the number of sorted elements and
decreasing the number of unsorted ones.
• Each time an element moves from the unsorted
part to the sorted part one sort pass is completed.
• Given a list of n elements, bubble sort requires up
to n-1 passes to sort the data.
Bubble Sort
23 78 45 8 32 56 Original List

8 23 78 45 32 56 After pass 1

8 23 32 78 45 56
After pass 2
8 23 32 45 78 56
After pass 3

8 23 32 45 56 78
After pass 4
Pass 1

23 78 45 8 32 56
23 78 45 8 32 56
23 78 8 45 32 56

23 8 78 45 32 56
8 23 78 45 32 56

8 23 78 45 32 56
Pass 2

8 23 78 45 32 56
8 23 78 32 45 56
8 23 32 78 45 56

8 23 32 78 45 56

8 23 32 78 45 56
Pass 3

8 23 32 78 45 56
8 23 32 45 78 56
8 23 32 45 78 56

8 23 32 45 78 56
Pass 4
8 23 32 45 78 56

8 23 32 45 56 78
8 23 32 45 56 78

8 23 32 45 56 78
Pass 5

8 23 32 45 56 78

8 23 32 45 56 78
Bubble Sort Algorithm
void bubleSort(int a[], int n)
{
for (int i = 0; i < n-1; i++){
for (int j = n-1; j > i; j--)
if (a[j-1] > a[j]){
swap(a[j],a[j-1]);
}
}
}
Function to check array is Sorted
void bubleSort(int a[], int n)
{
bool sorted = true;
for (int j=n-1; j > 0; j--)
if (a[j-1] > a[j]){
sorted = false;
}

if (sorted)
cout<<“Array is sorted\n”;
else
cout<<“Array is not sorted\n”;

}
Finally:- Bubble Sort Algorithm
void bubleSort(int a[], int n)
{
bool sorted = false;
int last = n-1;

for (int i = 0; (i < last) && !sorted; i++){


sorted = true;
for (int j=last; j > i; j--)
if (a[j-1] > a[j]{
swap(a[j],a[j-1]);
sorted = false; // signal exchange
}
}
}
Bubble Sort – Analysis
• Best-case:  O(n)
– Array is already sorted in ascending order.
– The number of moves: 0  O(1)
– The number of key comparisons: (n-1)  O(n)

• Worst-case:  O(n2)
– Array is in reverse order:
– Outer loop is executed n-1 times,
– The number of moves: 3*(1+2+...+n-1) = 3 * n*(n-1)/2  O(n2)
– The number of key comparisons: (1+2+...+n-1)= n*(n-1)/2  O(n2)

• Average-case:  O(n2)
– We have to look at all possible initial data organizations.

• So, Bubble Sort is O(n2)


Comparison of N, logN and N2
N O(LogN) O(N2)
16 4 256
64 6 4K
256 8 64K
1,024 10 1M
16,384 14 256M
131,072 17 16G
262,144 18 6.87E+10
524,288 19 2.74E+11
1,048,576 20 1.09E+12
1,073,741,824 30 1.15E+18
Selection Sort
• The list is divided into two sublists, sorted and unsorted,
which are divided by an imaginary wall.
• We find the smallest element from the unsorted sublist and
swap it with the element at the beginning of the unsorted
data.
• After each selection and swapping, the imaginary wall
between the two sublists move one element ahead,
increasing the number of sorted elements and decreasing
the number of unsorted ones.
• Each time we move one element from the unsorted sublist
to the sorted sublist, we say that we have completed a sort
pass.
• A list of n elements requires n-1 passes to completely
rearrange the data.
Sorted Unsorted

23 78 45 8 32 56 Original List

8 78 45 23 32 56 After pass 1

8 23 45 78 32 56
After pass 2

8 23 32 78 45 56
After pass 3

8 23 32 45 78 56
After pass 4
8 23 32 45 56 78
After pass 5
Selection Sort (cont.)
void selectionSort( int a[], int n) {
for (int i = 0; i < n-1; i++) {

int min = i;
for (int j = i+1; j < n; j++)
if (a[j] < a[min]) min = j;

swap(a[i], a[min]);
}
}

void swap( Object &lhs, Object &rhs )


{
Object tmp = lhs;
lhs = rhs;
rhs = tmp;
}
Selection Sort -- Analysis
• In general, we compare keys and move items (or exchange items)
in a sorting algorithm (which uses key comparisons).
 So, to analyze a sorting algorithm we should count the
number of key comparisons and the number of moves.
• Ignoring other operations does not affect our final result.

• In selectionSort function, the outer for loop executes n-1 times.


• We invoke swap function once at each iteration.
 Total Swaps: n-1
 Total Moves: 3*(n-1) (Each swap has three moves)
Selection Sort – Analysis (cont.)
• The inner for loop executes the size of the unsorted part minus 1
(from 1 to n-1), and in each iteration we make one key
comparison.
 # of key comparisons = 1+2+...+n-1 = n*(n-1)/2
 So, Selection sort is O(n2)
• The best case, the worst case, and the average case of the
selection sort algorithm are same.  all of them are O(n2)
– This means that the behavior of the selection sort algorithm does not depend on the
initial organization of data.
– Since O(n2) grows so rapidly, the selection sort algorithm is appropriate only for
small n.
– Although the selection sort algorithm requires O(n2) key comparisons, it only
requires O(n) moves.
– A selection sort could be a good choice if data moves are costly but key
comparisons are not costly (short keys, long records).
Insertion Sort
• Insertion sort is a simple sorting algorithm that is
appropriate for small inputs.
– Most common sorting technique used by card players.
• The list is divided into two parts: sorted and
unsorted.
• In each pass, the first element of the unsorted part
is picked up, transferred to the sorted sublist, and
inserted at the appropriate place.
• A list of n elements will take at most n-1 passes to
sort the data.
Sorted Unsorted

23 78 45 8 32 56 Original List

23 78 45 8 32 56 After pass 1

23 45 78 8 32 56
After pass 2

8 23 45 78 32 56
After pass 3

8 23 32 45 78 56
After pass 4
8 23 32 45 56 78
After pass 5
Pass 4
8 23 45 78 32 56

Temp 32

8 23 45 78 78 56
8 23 45 45 32 56

8 23 32 45 32 56

8 23 32 45 32 56
Insertion Sort Algorithm
void insertionSort(int a[], int n)
{
for (int i = 1; i < n; i++)
{
int tmp = a[i];

for (int j=i;tmp < a[j-1] && j>0; j--)


a[j] = a[j-1];

a[j] = tmp;
}
}
Insertion Sort – Analysis
• Running time depends on not only the size of the array but also
the contents of the array.
• Best-case:  O(n)
– Array is already sorted in ascending order.
– Inner loop will not be executed.
– The number of moves: 2*(n-1)  O(n)
– The number of key comparisons: (n-1)  O(n)
• Worst-case:  O(n2)
– Array is in reverse order:
– Inner loop is executed i-1 times, for i = 2,3, …, n
– The number of moves: 2*(n-1)+(1+2+...+n-1)= 2*(n-1)+ n*(n-1)/2  O(n2)
– The number of key comparisons: (1+2+...+n-1)= n*(n-1)/2  O(n2)
• Average-case:  O(n2)
– We have to look at all possible initial data organizations.
• So, Insertion Sort is O(n2)
Analysis of insertion sort
• Which running time will be used to characterize this
algorithm?
– Best, worst or average?
• Worst:
– Longest running time (this is the upper limit for the algorithm)
– It is guaranteed that the algorithm will not be worse than this.
• Sometimes we are interested in average case. But there are
some problems with the average case.
– It is difficult to figure out the average case. i.e. what is average
input?
– Are we going to assume all possible inputs are equally likely?
– In fact for most algorithms average case is same as the worst case.
Shellsort
• Reduce no items movements in insertion sort.
• Invented by Donald Shell in 1959.
• Also know diminishing-incrementing-sort.
• Elements of list viewed as sub-lists at a
particular distance.
• Each sub-list is sorted using insertion sort.
• Uses a sequence h1, h2, …, ht called the
increment sequence to create sub lists.
Shellsort
• Shellsort improves on the efficiency of
insertion sort by quickly shifting values to
their destination.
Shellsort
• The distance between comparisons
decreases as the sorting algorithm runs until
the last phase in which adjacent elements
are compared
Shellsort Examples

Sort: 18 32 12 5 38 33 16 2
8 Numbers to be sorted, Shell’s increment will be floor(n/2)
* floor(8/2)  floor(4) = 4

increment 4: 1 2 3 4 (visualize underlining)

18 32 12 5 38 33 16 2

Step 1) Only look at 18 and 38 and sort in order ;


18 and 38 stays at its current position because they are in order.
Step 2) Only look at 32 and 33 and sort in order ;
32 and 33 stays at its current position because they are in order.
Shellsort Examples

Sort: 18 32 12 5 38 33 16 2
8 Numbers to be sorted, Shell’s increment will be floor(n/2)
* floor(8/2)  floor(4) = 4

increment 4: 1 2 3 4 (visualize underlining)

18 32 12 5 38 33 16 2

Step 3) Only look at 12 and 16 and sort in order ;


12 and 16 stays at its current position because they are in order.
Step 4) Only look at 5 and 2 and sort in order ;
2 and 5 need to be switched to be in order.
Shellsort Examples (con’t)
Sort: 18 32 12 5 38 33 16 2
Resulting numbers after increment 4 pass:
18 32 12 2 38 33 16 5
* floor(4/2)  floor(2) = 2

increment 2: 1 2

18 32 12 2 38 33 16 5
Step 1) Look at 18, 12, 38, 16 and sort them in their appropriate location:

12 32 16 2 18 33 38 5
Step 2) Look at 32, 2, 33, 5 and sort them in their appropriate location:
12 2 16 5 18 32 38 33
Shellsort Examples (con’t)

Sort: 18 32 12 5 38 33 16 2

* floor(2/2)  floor(1) = 1
increment 1: 1
12 2 16 5 18 32 38 33

2 5 12 16 18 32 33 38

The last increment or phase of Shellsort is basically an Insertion


Sort algorithm.
Implementation
void intervalInsertionSort(int begin, int inc){
int j;
for (int i = begin+inc; i < size; i = i + inc){
int tmp = arr[i];
for (j=i; tmp < arr[j-inc] && j>0; j = j - inc)
arr[j] = arr[j-inc];
arr[j] = tmp;
}
cout<<"Inc ="<<inc<<", Begin ="<<begin<<": "; disp();

void shellsort(){
int inc = size/2;
do{
for (int begin = 0; begin < inc; begin ++)
intervalInsertionSort(begin, inc);
inc = inc/2;
}while(inc>0);
}
void disp (){
for (int i = 0; i<size; i++) cout<<arr[i]<<" ";
cout<<endl;
}
Testing ShellSort
#include<iostream>
using namespace std; 

int arr[] = {18, 32, 12, 5, 38, 33, 16, 2};


int size = 8;

void intervalInsertionSort(int begin, int inc);


void shellsort();
void disp ();

void main()
{
cout<<"Actual Array : "; disp();
shellsort();
system("pause");
}
 
Output
Empirical Analysis of Shellsort
(Advantage)
• Advantage of Shellsort is that its only
efficient for medium size lists. For bigger
lists, the algorithm is not the best choice.
Fastest of all O(N^2) sorting algorithms.
• 5 times faster than the bubble sort and a
little over twice as fast as the insertion sort,
its closest competitor.
• The number of moves in the range ().
Empirical Analysis of Shellsort
(Disadvantage)
• It is a complex algorithm and its not nearly as
efficient as the merge, heap and quick sorts.
• It is significantly slower than the merge, heap and
quick sorts, but its relatively simple algorithm
makes it a good choice for sorting lists of less than
5000 items unless speed important.
Shellsort Best Case
• Best Case: The best case in the shell sort is
when the array is already sorted in the right
order. The number of comparisons is less
Shellsort Worst Case
• The running time of Shellsort depends on
the choice of increment sequence.
• The problem with Shell’s increments is that
pairs of increments are not necessarily
relatively prime and smaller increments can
have little effect.
Additional Online References
• Spark Notes (From Barnes & Noble):
– http://www.sparknotes.com/cs/

You might also like