📄 qksort.c
字号:
/*****************************************************************************
* *
* ------------------------------- qksort.c ------------------------------- *
* *
*****************************************************************************/
#include <stdlib.h>
#include <string.h>
#include "sort.h"
/*****************************************************************************
* *
* ------------------------------ compare_int ----------------------------- *
* *
*****************************************************************************/
static int compare_int(const void *int1, const void *int2) {
/*****************************************************************************
* *
* Compare two integers (used during median-of-three partitioning). *
* *
*****************************************************************************/
if (*(const int *)int1 > *(const int *)int2)
return 1;
else if (*(const int *)int1 < *(const int *)int2)
return -1;
else
return 0;
}
/*****************************************************************************
* *
* ------------------------------- partition ------------------------------ *
* *
*****************************************************************************/
static int partition(void *data, int esize, int i, int k, int (*compare)
(const void *key1, const void *key2)) {
char *a = data;
void *pval,
*temp;
int r[3];
/*****************************************************************************
* *
* Allocate storage for the partition value and swapping. *
* *
*****************************************************************************/
if ((pval = malloc(esize)) == NULL)
return -1;
if ((temp = malloc(esize)) == NULL) {
free(pval);
return -1;
}
/*****************************************************************************
* *
* Use the median-of-three method to find the partition value. *
* *
*****************************************************************************/
r[0] = (rand() % (k - i + 1)) + i;
r[1] = (rand() % (k - i + 1)) + i;
r[2] = (rand() % (k - i + 1)) + i;
issort(r, 3, sizeof(int), compare_int);
memcpy(pval, &a[r[1] * esize], esize);
/*****************************************************************************
* *
* Create two partitions around the partition value. *
* *
*****************************************************************************/
i--;
k++;
while (1) {
/**************************************************************************
* *
* Move left until an element is found in the wrong partition. *
* *
**************************************************************************/
do {
k--;
} while (compare(&a[k * esize], pval) > 0);
/**************************************************************************
* *
* Move right until an element is found in the wrong partition. *
* *
**************************************************************************/
do {
i++;
} while (compare(&a[i * esize], pval) < 0);
if (i >= k) {
/***********************************************************************
* *
* Stop partitioning when the left and right counters cross. *
* *
***********************************************************************/
break;
}
else {
/***********************************************************************
* *
* Swap the elements now under the left and right counters. *
* *
***********************************************************************/
memcpy(temp, &a[i * esize], esize);
memcpy(&a[i * esize], &a[k * esize], esize);
memcpy(&a[k * esize], temp, esize);
}
}
/*****************************************************************************
* *
* Free the storage allocated for partitioning. *
* *
*****************************************************************************/
free(pval);
free(temp);
/*****************************************************************************
* *
* Return the position dividing the two partitions. *
* *
*****************************************************************************/
return k;
}
/*****************************************************************************
* *
* -------------------------------- qksort -------------------------------- *
* *
*****************************************************************************/
int qksort(void *data, int size, int esize, int i, int k, int (*compare)
(const void *key1, const void *key2)) {
int j;
/*****************************************************************************
* *
* Stop the recursion when it is not possible to partition further. *
* *
*****************************************************************************/
if (i < k) {
/**************************************************************************
* *
* Determine where to partition the elements. *
* *
**************************************************************************/
if ((j = partition(data, esize, i, k, compare)) < 0)
return -1;
/**************************************************************************
* *
* Recursively sort the left partition. *
* *
**************************************************************************/
if (qksort(data, size, esize, i, j, compare) < 0)
return -1;
/**************************************************************************
* *
* Recursively sort the right partition. *
* *
**************************************************************************/
if (qksort(data, size, esize, j + 1, k, compare) < 0)
return -1;
}
return 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -