Skip to content

Instantly share code, notes, and snippets.

@dongguosheng
Last active December 29, 2015 15:29
Show Gist options
  • Save dongguosheng/7691055 to your computer and use it in GitHub Desktop.
Save dongguosheng/7691055 to your computer and use it in GitHub Desktop.
A quicksort implementation collection in C
#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