1.2 实现
// #c---
/*==========================================================================*
* @Description:
* 插入排序
*
* @Param base
* @Param nmemb
* @Param size
* @Param compar
*==========================================================================*/
void Sort_insertSort(void *base, size_t nmemb, size_t size,
int(*compar)(const void *, const void *))
{
#define SWAP(a, b, t) ( (t)=(a), (a)=(b), (b)=(t) )
assert(base != NULL && nmemb >= 1 && size >= 1 && compar != NULL);
char *i, *j, t, *b, *e;
char *bot = (char*)base;
char *top = bot + nmemb * size;
for ( i = bot + size; i < top; i += size )
{
for ( j = i; (j-=size) >= bot && compar(i, j) < 0; )
{ }
if ( i != (j+=size) )
{
for ( b = j, e = i-1; b < e; b++, e-- )
SWAP(*b, *e, t);
for ( b = i, e = i+size-1; b < e; b++, e-- )
SWAP(*b, *e, t);
for ( b = j, e = i+size-1; b < e; b++, e-- )
SWAP(*b, *e, t);
}
}
#undef SWAP
}
// #c---end
// #c---
/*==========================================================================*
* @Description:
* 选择排序
*
* @Param base
* @Param nmemb
* @Param size
* @Param compar
*
*==========================================================================*/
void Sort_selectSort(void *base, size_t nmemb, size_t size,
int(*compar)(const void *, const void *))
{
#define SWAP(a, b, t) ( (t)=(a), (a)=(b), (b)=(t) )
assert(base != NULL && nmemb >= 1 && size >= 1 && compar != NULL);
int s;
char t, *i, *j, *min;
char *left = base;
char *right = left + (nmemb - 1) * size;
for ( i = left; i <= right - size; i += size )
{
min = i;
for ( j = i + size; j <= right; j += size )
{
if ( compar(j, min) < 0 )
min = j;
}
if ( i != min )
for ( s = 0; s < size; s++ )
SWAP(*(i+s), *(min+s), t);
}
#undef SWAP
}
// #c---end
// #c---
/*==========================================================================*
* @Description:
* 冒泡排序
*
* @Param base
* @Param nmemb
* @Param size
* @Param compar
*
*==========================================================================*/
void Sort_bubbleSort(void *base, size_t nmemb, size_t size,
int(*compar)(const void *, const void *))
{
#define SWAP(a, b, t) ( (t)=(a), (a)=(b), (b)=(t) )
assert(base != NULL && nmemb >= 1 && size >= 1 && compar != NULL);
int s, isSwap;
char t, *i, *j;
char *left = base;
char *right = base + (nmemb - 1) * size;
for ( i = left; i < right; i += size )
{
isSwap = 0;
for ( j = right; j > i; j -= size )
{
if ( compar(j, j-size) < 0 )
{
isSwap = 1;
for ( s = 0; s < size; s++ )
SWAP(*(j+s), *(j-size+s), t);
}
}
if ( isSwap == 0 )
break;
}
#undef SWAP
}
// #c---end
// #c---
/*==========================================================================*
* @Description:
* 合并排序之合并例程
*
* @Param left
* @Param center
* @Param right
* @Param size
* @Param compar
* @Param tmparray
*
*==========================================================================*/
static void SortST_memge(char *left, char *center, char *right, int size,
int(*compar)(const void *, const void *), char *tmparray)
{
#define COPY_SIZE(d, s) \
do { \
for ( i = 0; i < size; i++ ) \
*((d) + i) = *((s) + i); \
} while ( 0 )
int i;
char *Lright = center;
char *Rright = right;
char *Lpcur = left;
char *Rpcur = center + size;
char *Tpcur = tmparray;
for ( ; Lpcur <= Lright && Rpcur <= Rright; Tpcur += size )
{
if ( compar(Lpcur, Rpcur) < 0 )
{
COPY_SIZE(Tpcur, Lpcur);
Lpcur += size;
}
else
{
COPY_SIZE(Tpcur, Rpcur);
Rpcur += size;
}
}
for ( ; Lpcur <= Lright; Lpcur += size, Tpcur += size )
COPY_SIZE(Tpcur, Lpcur);
for ( ; Rpcur <= Rright; Rpcur += size, Tpcur += size )
COPY_SIZE(Tpcur, Rpcur);
for ( Lpcur = left; Lpcur <= right; Lpcur += size, tmparray += size )
COPY_SIZE(Lpcur, tmparray);
#undef COPY_SIZE
}
/*==========================================================================*
* @Description:
* 合并排序
*
* @Param left
* @Param right
* @Param size
* @Param compar
* @Param tmparray
*
*==========================================================================*/
static void Sort_mergeSort_priv(char *left, char *right, int size,
int(*compar)(const void *, const void *), char *tmparray)
{
if ( left < right )
{
char *center = left + ((right - left) / size / 2) * size;
Sort_mergeSort_priv(left, center, size, compar, tmparray);
Sort_mergeSort_priv(center + size, right, size, compar, tmparray);
SortST_memge(left, center, right, size, compar, tmparray);
}
}
/*==========================================================================*
* @Description:
* 合并排序驱动例程
*
* @Param base
* @Param nmemb
* @Param size
* @Param compar
*
*==========================================================================*/
void Sort_mergeSort(void *base, size_t nmemb, size_t size,
int(*compar)(const void *, const void *))
{
assert(base != NULL && nmemb >= 1 && size >= 1 && compar != NULL);
char *left = base;
char *right = base + (nmemb - 1) * size;
char *tmparray;
tmparray = malloc(nmemb * size);
if ( tmparray == NULL )
return;
Sort_mergeSort_priv(left, right, size, compar, tmparray);
free(tmparray);
}
// #c---end
// #c---
/*==========================================================================*
* @Description:
* 取三者间的中间值
*
* @Param left
* @Param right
* @Param size
* @Param compar
*
* @Returns:
*==========================================================================*/
static char* Sort_median3(char *left, char *right, int size,
int(*compar)(const void *, const void *))
{
#define SWAP(a, b, t) ( (t)=(a), (a)=(b), (b)=(t) )
int s;
char t;
// char *center = left + (right - left) / 2; // 错误!!
// 每一步计算都必须取整! 才不至于最后的结果位于字节内!
char *center = left + (((right - left) / size) / 2) * size;
if ( compar(left, center) > 0 )
for ( s = 0; s < size; s++ )
SWAP(*(left+s), *(center+s), t);
if ( compar(left, right) > 0 )
for ( s = 0; s < size; s++ )
SWAP(*(left+s), *(right+s), t);
if ( compar(center, right) > 0 )
for ( s = 0; s < size; s++ )
SWAP(*(center+s), *(right+s), t);
for ( s = 0; s < size; s++ )
SWAP(*(center+s), *(right-size+s), t);
return right - size;
#undef SWAP
}
/*==========================================================================*
* @Description:
* 快速排序
*
* @Param left
* @Param right
* @Param size
* @Param compar
*==========================================================================*/
static void Sort_quicklySort_priv(char *left, char *right, int size,
int(*compar)(const void *, const void *))
{
#define SWAP(a, b, t) ( (t)=(a), (a)=(b), (b)=(t) )
int s;
char t, *i, *j, *pivot;
if ( left + SORT_CUTOFF * size <= right )
{
pivot = Sort_median3(left, right, size, compar);
i = left;
j = right - size;
for ( ; ; )
{
for ( i += size; compar(i, pivot) < 0; i += size ) { }
for ( j -= size; compar(j, pivot) > 0; j -= size ) { }
if ( i < j )
{
for ( s = 0; s < size; s++ )
SWAP(*(i+s), *(j+s), t);
}
else
break;
}
for ( s = 0; s < size; s++ )
SWAP(*(i+s), *(right-size+s), t);
Sort_quicklySort_priv(left, i - size, size, compar);
Sort_quicklySort_priv(i + size, right, size, compar);
}
else
Sort_insertSort(left, (right-left)/size + 1, size, compar);
#undef SWAP
}
/*==========================================================================*
* @Description:
* 快速排序驱动例程
*
* @Param base
* @Param nmemb
* @Param size
* @Param compar
*==========================================================================*/
void Sort_quicklySort(void *base, size_t nmemb, size_t size,
int(*compar)(const void *, const void *))
{
assert(base != NULL && nmemb >= 1 && size >= 1 && compar != NULL);
if ( nmemb <= 1 )
return;
if ( nmemb >= SORT_CUTOFF )
Sort_quicklySort_priv(base, base + (nmemb-1)*size, size, compar);
else
Sort_insertSort(base, nmemb, size, compar);
}
// #c---end
快速排序算法也是运用分治思想, 其空间复杂度为 O(1), 时间复杂度为 O(NlogN).