Last active
December 29, 2015 15:29
-
-
Save dongguosheng/7691055 to your computer and use it in GitHub Desktop.
A quicksort implementation collection in C
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdio.h> | |
#include <stdlib.h> | |
#include <time.h> | |
void qsort_last(int s[], int start_index, int end_index); //select the last element as the pivot | |
void qsort_first(int s[], int start_index, int end_index); //select the first element as the pivot | |
void qsort_mid(int s[], int start_index, int end_index); //select the middle element as the pivot | |
void qsort_rand(int s[], int start_index, int end_index); //select a random index's value as the pivot | |
void qsort_mot(int s[], int start_index, int end_index); //median of three partitioning + insertion sort | |
void qsort_clrs(int s[], int start_index, int end_index); //select the last element as the pivot, CLRS version | |
int partition(int s[], int start_index, int end_index); | |
int getPivot(int s[], int start_index, int end_index); | |
int medianOfThree(int s[], int start_index, int end_index); | |
void insertionSort(int s[], int start_index, int end_index); | |
void bubbleSort(int s[], int start_index, int end_index); | |
int main() | |
{ | |
int i; | |
int s[100]; | |
srand(time(0)); | |
for(i = 0; i < 100; ++i){ | |
s[i] = rand() % 100; | |
} | |
// int s[] = {1, 8, 5, 6, 9, 7, 1, 2, 3, 2, 0, 19}; | |
// int s[] = {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}; | |
// int s[] = {12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1}; | |
// int s[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12}; | |
// qsort_mot(s, 0, 99); | |
// qsort_first(s, 0, 99); | |
// qsort_last(s, 0, 99); | |
// qsort_mid(s, 0, 99); | |
// qsort_rand(s, 0, 99); | |
qsort_mot(s, 0, 99); | |
// insertionSort(s, 0, 99); | |
// bubbleSort(s, 0, 99); | |
for(i = 0; i < 100; ++i){ | |
printf("%d ", s[i]); | |
if(i % 10 == 9){ | |
printf("\n"); | |
} | |
} | |
return 0; | |
} | |
void qsort_last(int s[], int start_index, int end_index){ | |
if(start_index < end_index){ | |
//the number of elements in s larger than 2 | |
//get the pivot | |
int pivot = s[end_index]; //select the last element as the pivot(needn't to consider i out of range) | |
//split s into two pieces | |
int i = start_index, j = end_index - 1; | |
int temp; | |
while(i <= j){ | |
while(s[i] < pivot){ i++; } | |
// printf("i = %d\n", i); | |
while(s[j] > pivot && i < j){ j--; } | |
// printf("j = %d\n", j); | |
// printf("\n"); | |
//swap the elements where i, j stop | |
if(i < j){ | |
temp = s[j]; | |
s[j] = s[i]; | |
s[i] = temp; | |
i++; | |
j--; | |
}else { | |
break; | |
} | |
} | |
//swap the pivot to middle | |
s[end_index] = s[i]; | |
s[i] = pivot; | |
//recursion | |
qsort_last(s, start_index, i - 1); | |
qsort_last(s, i + 1, end_index); | |
} | |
} | |
void qsort_first(int s[], int start_index, int end_index){ | |
if(start_index < end_index){ | |
int pivot = s[start_index]; //no need to consider j out of range | |
int i = start_index + 1, j = end_index; | |
int temp; | |
while(i <= j){ | |
while(s[i] < pivot && i < j){ i++; } | |
// printf("i = %d ", i); | |
while(s[j] > pivot){ j--; } | |
// printf("j = %d ", j); | |
// printf("\n"); | |
if(i < j){ | |
temp = s[j]; | |
s[j] = s[i]; | |
s[i] = temp; | |
i++; | |
j--; | |
}else { | |
break; | |
} | |
} | |
s[start_index] = s[j]; | |
s[j] = pivot; | |
//recursion | |
qsort_first(s, start_index, j - 1); | |
qsort_first(s, j + 1, end_index); | |
} | |
} | |
void qsort_mid(int s[], int start_index, int end_index){ | |
if(start_index < end_index){ | |
int pivot = s[(start_index + end_index) / 2]; //select the middle element as the pivot | |
int i = start_index, j = end_index; | |
int temp; | |
while(i <= j){ | |
while(s[i] < pivot && i <= j){ i++; } //no need to consider i & j out of range | |
while(s[j] > pivot && i <= j){ j--; } | |
if(i <= j){ | |
temp = s[j]; | |
s[j] = s[i]; | |
s[i] = temp; | |
i++; | |
j--; | |
}else { | |
break; | |
} | |
} | |
// printf("i = %d j = %d\n", i, j); | |
qsort_mid(s, start_index, j); | |
qsort_mid(s, i, end_index); | |
} | |
} | |
int getPivot(int s[], int start_index, int end_index){ | |
srand(time(0)); | |
int index = (rand() % (end_index - start_index + 1)) + start_index; | |
// printf("index = %d ", index); | |
return s[index]; | |
} | |
void qsort_rand(int s[], int start_index, int end_index){ | |
if(start_index < end_index){ | |
int pivot = getPivot(s, start_index, end_index); | |
// printf("pivot = %d\n", pivot); | |
int i = start_index, j = end_index; | |
int temp; | |
while(i <= j){ | |
while(s[i] < pivot && i <= j){ i++; } | |
while(s[j] > pivot && i <= j){ j--; } | |
if(i <= j){ | |
temp = s[j]; | |
s[j] = s[i]; | |
s[i] = temp; | |
i++; | |
j--; | |
}else { | |
break; | |
} | |
} | |
qsort_rand(s, start_index, j); | |
qsort_rand(s, i, end_index); | |
} | |
} | |
int medianOfThree(int s[], int start_index, int end_index){ | |
int temp; | |
if(s[start_index] > s[(start_index + end_index) / 2]){ | |
temp = s[(start_index + end_index) / 2]; | |
s[(start_index + end_index) / 2] = s[start_index]; | |
s[start_index] = temp; | |
} | |
if(s[(start_index + end_index) / 2] > s[end_index]){ | |
temp = s[(start_index + end_index) / 2]; | |
s[(start_index + end_index) / 2] = s[end_index]; | |
s[end_index] = temp; | |
} | |
if(s[start_index] > s[(start_index + end_index) / 2]){ | |
temp = s[(start_index + end_index) / 2]; | |
s[(start_index + end_index) / 2] = s[start_index]; | |
s[start_index] = temp; | |
} | |
//swap the pivot to end_index - 1 positon | |
// temp = s[end_index - 1]; | |
// s[end_index - 1] = s[(start_index + end_index) / 2]; | |
// s[(start_index + end_index) / 2] = temp; | |
// return s[end_index - 1]; | |
return s[(start_index + end_index) / 2]; | |
} | |
void qsort_mot(int s[], int start_index, int end_index){ | |
int cutoff = 3; | |
int pivot = medianOfThree(s, start_index, end_index); | |
//printf("pivot = %d\n", pivot); | |
if(start_index + cutoff <= end_index){ | |
int i = start_index + 1, j = end_index - 1; | |
int temp; | |
while(i <= j){ | |
while(s[i] < pivot && i <= j){ i++; } | |
while(s[j] > pivot && i <= j){ j--; } | |
if(i <= j){ | |
temp = s[j]; | |
s[j] = s[i]; | |
s[i] = temp; | |
i++; | |
j--; | |
}else { | |
break; | |
} | |
} | |
//swap pivot back | |
// s[end_index - 1] = s[i]; | |
// s[i] = pivot; | |
qsort_mot(s, start_index, j); | |
qsort_mot(s, i, end_index); | |
}else { | |
//insertionSort(s, start_index, end_index); | |
insertionSort(s, start_index, end_index); | |
} | |
} | |
void insertionSort(int s[], int start_index, int end_index){ | |
if(start_index < end_index){ | |
int i = start_index + 1, j; | |
int temp; | |
while(i <= end_index){ | |
temp = s[i]; | |
j = i - 1; | |
while(j >= start_index && s[j] > temp){ | |
s[j + 1] = s[j]; | |
j--; | |
} | |
s[j + 1] = temp; | |
i++; | |
} | |
} | |
} | |
void bubbleSort(int s[], int start_index, int end_index){ | |
int i, j; | |
int temp; | |
for(i = start_index; i < end_index; i++){ | |
for(j = start_index; j < end_index - i; j++){ | |
if(s[j] > s[j + 1]){ | |
temp = s[j + 1]; | |
s[j + 1] = s[j]; | |
s[j] = temp; | |
} | |
} | |
} | |
} | |
void qsort_clrs(int s[], int start_index, int end_index){ | |
if(start_index < end_index){ | |
//partition | |
int pivot_index = partition(s, start_index, end_index); | |
// printf("pivot_index = %d\n", pivot_index); | |
//recursion | |
qsort_clrs(s, start_index, pivot_index - 1); | |
qsort_clrs(s, pivot_index + 1, end_index); | |
} else if(start_index == end_index) { | |
// only one element | |
return; | |
} else { | |
printf("IndexError."); | |
return; | |
} | |
} | |
int partition(int s[], int start_index, int end_index){ | |
int i, j = start_index, temp; | |
int pivot = s[end_index]; //select the last element as pivot | |
for(i = start_index; i < end_index; i++){ | |
//j表示最靠左的>=pivot的位置 | |
//发现s[i] < pivot, 则把s[i]和最靠左的>=pivot交换,以保证start_index到i - 1是分割好的。 | |
if(s[i] < pivot){ | |
//swap s[i] and s[j] | |
temp = s[j]; | |
s[j] = s[i]; | |
s[i] = temp; | |
j++; | |
} | |
} | |
//swap the pivot to middle (j) | |
s[end_index] = s[j]; | |
s[j] = pivot; | |
return j; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment