Sei sulla pagina 1di 10

0130 9

Data Structures & Algorithms


Assignment# 2
Submitted to: Dr. Anis ur Rehman

Ali Rahman BEE 4C 01309

Comb Sort:
Description:
The comb sort is an improvement of the bubble sort algorithm. In bubble sort, two adjacent elements are compared and swapped. Since they are adjacent to each other, those elements can be considered to have a gap of 1. In comb sort, the need to maintain a gap of 1 is overlooked and the gap can be of greater value than 1. This is done to overcome turtles. A turtle is a low value (relatively) located at or near to the end of a list. One pass of a bubble sort would result in a turtle moving up by one place only. This has a highly significant slowing down effect on the bubble sort algorithm. The use of a gap>1 in comb sort allows turtles to move up a number of places in one go. The gap in comb sort is not fixed (unlike bubble sort), it varies depending on the pass of the sort. For the first pass, the gap is the length of the data set to be sorted. For each pass after that, the gap is reduced by what is known as the shrink factor. The shrink factor used is 1.3, this figure was found out by the authors of the algorithm by testing various shrink factors between 1.15 and 1.45 and analyzing cornucopia plots. For a comb sort with a shrink factor less than 1.3, the sort becomes slow due too many comparisons while for a factor>1.3, the sort is slowed by less turtles being killed. Due to the shrink factor, there occurs a situation (after a number of passes) in which the gap becomes less than 1. To counter this, an if condition is used to set the gap to 1 if such situation arises. When the gap is 1, the comb sort essentially becomes a bubble sort, but since the list is pre-sorted for the bubble sort, it is efficient. Another thing to consider due to shrink factor being 1.3 is that gap varies and becomes 1 in one of the three ways: 964321 10 7 5 3 2 1 11 8 6 4 3 2 1 The third path results in an extra pass to which means 1 more round to kill turtles. The other two would not have killed all of the turtles prior to the gap reaching 1 which would have slowed down the overall sorting by 15 to 20 percent. References: http://cs.clackamas.cc.or.us/molatore/cs260Spr03/combsort.htm

Pseudocode:
The pseudocode mentioned below is taken from: http://en.wikipedia.org/wiki/Comb_sort

function combsort(array input) gap := input.size //initialize gap size loop until gap = 1 and swaps = 0 //update the gap value for a next comb. Below is an example gap := int(gap / 1.25) if gap < 1 //minimum gap is 1 gap := 1 end if i := 0 swaps := 0 //see Bubble Sort for an explanation //a single "comb" over the input list loop until i + gap >= input.size //see Shell sort for similar idea if input[i] > input[i+gap] swap(input[i], input[i+gap]) swaps := 1 // Flag a swap has occurred, so the // list is not guaranteed sorted end if i := i + 1 end loop end loop end function

Sample source code:


Code taken from: http://www.exforsys.com/tutorials/c-algorithms/comb-sort.html
#include < iostream > using namespace std; int newGap(int gap) { gap = (gap * 10) / 13; if (gap == 9 || gap == 10) gap = 11; if (gap < 1) gap = 1; return gap; } void combsort(int a[], int aSize) { int gap = aSize; for (;;) { gap = newGap(gap); bool swapped = false; for (int i = 0; i < aSize - gap; i++) { int j = i + gap; if (a[i] > a[j]) { std::swap(a[i], a[j]); swapped = true; } } if (gap == 1 && !swapped) break; } }

int main () { int n; int *a; cout << "Please insert the number of elements to be sorted: "; cin >> n; // The total number of elements

a = (int *)calloc(n, sizeof(int)); for(int i=0;i< n;i++) {

cout << "Input " << i << " element: "; cin >>a[i]; // Adding the elements to the array } cout << "Unsorted list:" << endl; for(int i=0;i< n;i++) { cout << a[i] << " "; } combsort(a,n); cout << "nSorted list:" << endl; for(int i=0;i < n;i++) { cout << a[i] << " "; } return 0; } // Display the sorted array // Displaying the unsorted array

My Implementation:
Integers only: Full source code:

#include < iostream > #include <conio.h> using namespace std; void combsort(int a[], int aSize) { int temp; int gap = aSize; for (;;) { gap=(gap*10)/13; if(gap==9||gap==10) {gap=11;} if(gap<1){ gap=1;} bool swapped = false; for (int i = 0; i < aSize - gap; i++) { int j = i + gap; if (a[i] > a[j]) { temp=a[i]; a[i]=a[j]; a[j]=temp; swapped = true; } } if (gap == 1 && !swapped) break; } } int main () { int data[]={23,45,2,1,56,25,17,15}; int n; n=sizeof(data)/sizeof(int); cout<<"Unsorted list:"<<endl; for(int c=0;c<n;c++) { cout<<data[c]<<" "; } combsort(data,n); cout << endl<<"Sorted list:" << endl; for(int i=0;i < n;i++) { cout << data[i] << " "; } getch(); return 0; }

Comb Sort function:

void combsort(int a[], int aSize) { int temp; int gap = aSize; for (;;) { gap=(gap*10)/13; if(gap==9||gap==10) {gap=11;} if(gap<1){ gap=1;} bool swapped = false; for (int i = 0; i < aSize - gap; i++) { int j = i + gap; if (a[i] > a[j]) { temp=a[i]; a[i]=a[j]; a[j]=temp; swapped = true; } } if (gap == 1 && !swapped) break; } }

Template:
template<class T> void combsort(T a[], int aSize) { T temp; int gap = aSize; for (;;) { gap=(gap*10)/13; if(gap==9||gap==10) {gap=11;} if(gap<1){ gap=1;} bool swapped = false; for (int i = 0; i < aSize - gap; i++) { int j = i + gap; if (a[i] > a[j]) { temp=a[i]; a[i]=a[j]; a[j]=temp; swapped = true; } } if (gap == 1 && !swapped) break; } }

Questions:
1 Refer to the description written earlier. For a better understanding, view the example given below. 3 21 1 4 17

length=5 thus, gap=5 gap=3 (refer to code) for first pass total number of comparisons made will be 5-3=2 After first pass: 3 gap=2 total number of comparisons made will be 5-2=3 After 2nd pass: 1 gap=1 total number of comparisons made will be 5-1=4 After 3rd pass: 1 3 4 17 21 4 3 17 21 17 1 4 21

2 O(nlogn) average case. O(n2) worst case. (Though coefficient is a very lowly 10-80 ) (http://en.wikipedia.org/?title=Talk:Comb_sort#Comb_sort_versus_Merge_Sort.2C_Quick_Sor t_and_Shell_Sort )

3 Practically, comb sort is better than quick sort since it does not have a worst case scenario( this is debatable since due to the controversy of the negligible coefficient of n^2 for comb sorts worst case input of completely random data set). (http://en.wikipedia.org/?title=Talk:Comb_sort#Comb_sort_versus_Merge_Sort.2C_Quick_Sor t_and_Shell_Sort) Compared to both quicksort and mergesort, combsort does not use recursive function calls, thus preventing the hazard of stack overflow. Comb sort is indeed an improvement over bubble sort since its average running time is lesser. For a general comparison with other algorithms, refer to the table below.

4 Best case scenario: Data set nearly sorted already Worst case scenario: Data set completely random. 5 Cyclomatic Complexity is 9. (Based upon the metrics given by the SourceMonitor application www.campwoodsw.com/sourcemonitor.html ) Space Complexity O(1). 6 No function calls. Number of comparisons & possible maximum number of swaps per pass= length of data set gap Note: gap varies after each pass. 7 Compared to the source code given, my implementation reduces the function calls. The code for finding out the gap after each pass is incorporated into the comb sort function. Furthermore, my implementation does not call the library function for swapping. My implementation uses a temporary object which is created once and assigned a new value for each pass. The inbuilt swapping action would have created a temporary object for each pass.

8 Comb sort is a relatively unknown sorting algorithm but considering its simplicity into mind, it is indeed a nifty one. It is inspace and its average running time is super linear. Its one disadvantage is that it is not stable.

Potrebbero piacerti anche