快速排序算法(C语言实现)

自实现部分可参看慕课网陈越老师数据结构课程。

1. 快速排序——直接调用库函数

库函数函数原型:
void qsort(void *buf, size_t num, size_t size, int ( * compare)( const void *, const void *));
函数说明:
对buf指向对数据(包含num项,每项的大小为size)进行快速排序。
void *buf:无类型指针,如果要排序一个数组,则为指向数组第一个数据的指针;
size_t num:要排序的数据的项数,可理解为待排数组的元素个数;
size_t size:待排数据每项的大小,以字节Byte为单位;
int ( * compare)( const void *, const void *):
“函数指针”,用户自定义函数,函数名为compare,const void *:无类型常量指针,可以指向任意类型的数据,但是必须为常量。
compare函数规定待排数组的排序规则 :
a. 如果函数compare的第一个参数排在第二个前面,返回负值;
b. 如果函数compare的第一个参数和第二个位置不要求,返回零值;
c. 如果函数compare的第一个参数排在第二个后面,返回正值;

∗ ∗ 简 单 整 数 排 序 ∗ ∗ \color{#DC143C}{**简单整数排序**}
/*---------------简单整数排序--------------------*/
int compare(const void *a, const void *b)
{ /* 比较两整数。非降序排列 */return (*(int*)a - *(int*)b);
}
/* 调用接口 */ 
qsort(A, N, sizeof(int), compare);
/*---------------简单整数排序--------------------*/
∗ ∗ 结 构 体 数 组 N o d e 中 的 某 键 值 k e y 排 序 ∗ ∗ \color{#DC143C}{**结构体数组Node中的某键值key排序**} Nodekey
/*--------------- 一般情况下,对结构体Node中的某键值key排序 ---------------*/
struct Node {
    int key1, key2;
} A[MAXN];
  
int compare2keys(const void *a, const void *b)
{ /* 比较两种键值:按key1非升序排列;如果key1相等,则按key2非降序排列 */
    int k;
    if ( ((const struct Node*)a)->key1 >((const struct Node*)b)->key1 )
        k = 1;
    else if ( ((const struct Node*)a)->key1 < ((const struct Node*)b)->key1 )
        k = -1;
    else { /* 如果key1相等 */
        if ( ((const struct Node*)a)->key2 < ((const struct Node*)b)->key2 )
            k = -1;
        else
            k = 1;
    }
    return k;
}
/* 调用接口 */ 
qsort(A, N, sizeof(struct Node), compare2keys);
/*--------------- 一般情况下,对结构体Node中的某键值key排序 ---------------*/

2. 快速排序——自实现

/* 快速排序 */
 
ElementType Median3( ElementType A[], int Left, int Right )
{ 
    int Center = (Left+Right) / 2;
    if ( A[Left] > A[Center] )
        Swap( &A[Left], &A[Center] );
    if ( A[Left] > A[Right] )
        Swap( &A[Left], &A[Right] );
    if ( A[Center] > A[Right] )
        Swap( &A[Center], &A[Right] );
    /* 此时A[Left] <= A[Center] <= A[Right] */
    Swap( &A[Center], &A[Right-1] ); /* 将基准Pivot藏到右边*/
    /* 只需要考虑A[Left+1] … A[Right-2] */
    return  A[Right-1];  /* 返回基准Pivot */
}
 
void Qsort( ElementType A[], int Left, int Right )
{ /* 核心递归函数 */ 
     int Pivot, Cutoff, Low, High;
       
     if ( Cutoff <= Right-Left ) { /* 如果序列元素充分多,进入快排 */
          Pivot = Median3( A, Left, Right ); /* 选基准 */ 
          Low = Left; High = Right-1;
          while (1) { /*将序列中比基准小的移到基准左边,大的移到右边*/
               while ( A[++Low] < Pivot ) ;
               while ( A[--High] > Pivot ) ;
               if ( Low < High ) Swap( &A[Low], &A[High] );
               else break;
          }
          Swap( &A[Low], &A[Right-1] );   /* 将基准换到正确的位置 */ 
          Qsort( A, Left, Low-1 );    /* 递归解决左边 */ 
          Qsort( A, Low+1, Right );   /* 递归解决右边 */  
     }
     else InsertionSort( A+Left, Right-Left+1 ); /* 元素太少,用简单排序 */ 
}
 
void QuickSort( ElementType A[], int N )
{ /* 统一接口 */
     Qsort( A, 0, N-1 );
}

你可能感兴趣的:(学习笔记)