快速排序代码复用的方法(未实践)

来源:互联网 发布:java如何定义一个函数 编辑:程序博客网 时间:2024/05/16 10:03
深入剖析qsort()库函数:    http://blog.pfan.cn/accelerator/14298.html    

结合《数据结构与算法分析——C语言描述》中给出用递归实现的快速排序,
和VC++中的qsort.c源码分析,对比学习。

尝试对《数据结构与算法分析——C语言描述》的快速排序代码做以下改进:

1: 改变Qsort(ElementType A[], int Left, int Right)中的形参ElementType A[ ]为qsort.c源码中的void *指针,达到代码的最大通用性。虽然通过定义 typedef ElementType 也有代码复用的功能,但在通用性上不如void *完美,因为只能定义一组类型的快速排序。若程序中需要对不同类型进行排序,则ElementType 有心无力。

同时把Swap()函数换成qsort.c源码中的形式,同样也是出于代码通用和扩展考虑。
回调函数::如果qsort()函数中形参没有回调函数cmp,而仅仅是在函数内部进行比较,则不能调用不同类型的比较含数据,也就是说,如果qsort()函数嵌套一个cmp()函数,那么必定是一个具体类型的函数,也就达不到通用类型的作用。


后来:由于修改的东西实在太多,而且怕递归的效率不够好(尤其在嵌入式系统中),因此直接将VC++中的qsort.c源码作为自己的库调用,以达到使用目的。





疑惑:qsort.c源码中,
void __cdecl qsort (
    void *base,
    unsigned num,
    unsigned width,
    int (__cdecl *comp)(const void *, const void *)
    )
{
    char *lo, *hi;              /* ends of sub-array currently sorting */
    char *mid;                  /* points to middle of subarray */
    char *loguy, *higuy;        /* traveling pointers for partition step */
    unsigned size;              /* size of the sub-array */
    char *lostk[30], *histk[30];
    int stkptr;                 /* stack for saving sub-array to be processed */

//    int *pp;

    /* Note: the number of stack entries required is no more than
       1 + log2(size), so 30 is sufficient for any array */

    if (num < 2 || width == 0)
        return;                 /* nothing to do */

    stkptr = 0;                 /* initialize stack */

//pp = lo;                //提示出错,赋值类型不兼容
    lo = base;        //疑惑,为什么base指针作为void *指针可以直接对char *类型的lo指针赋值而没有警告????
    hi = (char *)base + width * (num-1);        /* initialize limits */

    /* this entry point is for pseudo-recursion calling: setting
       lo and hi and jumping to here is like recursion, but stkptr is
       prserved, locals aren't, so we preserve stuff on the stack */
recurse: