常规排序算法C语言实现- linux、GCC

Table of Contents

sort.h

sort.c


sort.h

#ifndef __CRTL_SORT_H
#define __CRTL_SORT_H 1


#include "crtl/crtl_types.h"


void crtl_sort_cocktailshaker(void *base, size_t num, size_t size, int (*cmp)(const void *, const void *));
void crtl_sort_heap(void *base, size_t num,size_t size, int (*cmp)(const void *, const void *));
void crtl_sort_insertion(void *base, size_t num, size_t size, int (*cmp)(const void *, const void *));
void crtl_sort_qsort3way(void *base, size_t n, size_t size, int (*cmp)(const void *, const void *));
void crtl_sort_qsortH(void *base,size_t lo,size_t hi,size_t size,int (*cmp)(const void *, const void *));
void crtl_sort_qsortL(void *base,size_t lo,size_t hi,size_t size,int (*cmp)(const void *, const void *));
void crtl_sort_selection(void *base,size_t num,size_t size,int (*cmp)(const void *, const void *));
void crtl_sort_shell(void *base,size_t num,size_t size,int (*cmp)(const void *, const void *));





#endif /*<__CRTL_SORT_H>*/

sort.c

#include "crtl/crtl_log.h"
#include "crtl/crtl_assert.h"
#include "crtl/crtl_types.h"
#include "crtl/crtl_alloc.h"
#include "crtl/crtl_string.h"
#include "crtl/easy/macro.h"



void crtl_sort_cocktailshaker(void *base, size_t num, size_t size, int (*cmp)(const void *, const void *))
{
    crtl_byte *pbBase = (crtl_byte *)base;
    size_t i;
    int swapped;

    if(num) {
        do {
            swapped = false;
            for(i = 0; i < num - 2; i++)
                if(cmp(pbBase + (i + 1) * size, pbBase + i * size) > 0) {
                    crtl_memswap(pbBase + (i + 1) * size, pbBase + i * size, size);
                    swapped = true;
                }

            if(!swapped) break;

            swapped = false;
            for(i = num - 2; i > 0; i--)
                if(cmp(pbBase + (i + 1) * size, pbBase + i * size) > 0) {
                    crtl_memswap(pbBase + (i + 1) * size, pbBase + i * size, size);
                    swapped = true;
                }
        } while(swapped);
    }
}


void crtl_sort_heap(void *base, size_t num,size_t size, int (*cmp)(const void *, const void *))
{
    crtl_byte *pbBase = (crtl_byte *)base;
    int i = (num / 2 - 1) * size;
    int n = num * size;
    int c, r;

    while(i >= 0) {
        for(r = i; r * 2 + size < n; r = c) {
            c = r * 2 + size;
            if(c < n - size && cmp(pbBase + c, pbBase + c + size) >= 0) c += size;
            if(cmp(pbBase + r, pbBase + c) < 0) break;
            crtl_memswap(pbBase + r, pbBase + c, size);
        }
        i -= size;
    }

    for(i = n - size; i > 0; i -= size) {
        crtl_memswap(pbBase, pbBase + i, size);

        for(r = 0; r * 2 + size < i; r = c) {
            c = r * 2 + size;
            if(c < i - size && cmp(pbBase + c, pbBase + c + size) >= 0) c += size;
            if(cmp(pbBase + r, pbBase + c) < 0) break;
            crtl_memswap(pbBase + r, pbBase + c, size);
        }
    }
}



void crtl_sort_insertion(void *base, size_t num, size_t size, int (*cmp)(const void *, const void *))
{
    crtl_byte *pbBase = (crtl_byte *)base;
    size_t i, j;

    if(num)
        for(i = 1; i < num; i++)
            for(j = i; j > 0 && cmp(pbBase + j * size, pbBase + (j - 1) * size) > 0; j--)
                crtl_memswap(pbBase + j * size, pbBase + (j - 1) * size, size);
}


void crtl_sort_qsort3way(void *base, size_t n, size_t size, int (*cmp)(const void *, const void *))
{
    crtl_byte *ptr = (crtl_byte *)base;

    while(n > 1) {
        int i = 1, lt = 0, gt = n;
        while(i < gt) {
            int c = cmp(ptr + lt * size, ptr + i * size);
            if(c < 0) {
                crtl_memswap(ptr + lt * size, ptr + i * size, size);
                lt++;
                i++;
            } else if(c > 0) {
                gt--;
                crtl_memswap(ptr + i * size, ptr + gt * size, size);
            } else {
                i++;
            }
        }

        if(lt < n - gt) {
            crtl_sort_qsort3way(ptr, lt, size, cmp);
            ptr += gt * size;
            n -= gt;
        } else {
            crtl_sort_qsort3way(ptr + gt * size, n - gt, size, cmp);
            n = lt;
        }
    }
}



static size_t __partition(void *base, size_t lo,size_t hi,size_t size,int (*cmp)(const void *, const void *))
{
    crtl_byte *pbBase = (crtl_byte *)base;
    crtl_byte *v = (crtl_byte *)base;

    size_t i = lo;
    size_t j = hi + 1;

    //log_debug("lo = %ld, hi = %ld\n", lo, hi);

    while(true) 
    {
        while(cmp(pbBase + (++i) * size, v + lo * size) > 0)
            if(i == hi) break;
        while(cmp(v + lo * size, pbBase + (--j) * size) > 0)
            if(j == lo) break;
        if(i >= j) break;
        
        crtl_memswap(pbBase + i * size, pbBase + j * size, size);
    }
    crtl_memswap(pbBase + lo * size, pbBase + j * size, size);
    //log_debug("\n");
    
    return j;
}

void crtl_sort_qsortH(void *base,size_t lo,size_t hi,size_t size,int (*cmp)(const void *, const void *))
{
    size_t p;

    if((long)hi <= (long)lo)
    {
        return;
    }
    else 
    {
        p = __partition(base, lo, hi, size, cmp);
        crtl_sort_qsortH(base, lo, p - 1, size, cmp);
        crtl_sort_qsortH(base, (p + 1), hi, size, cmp);
    }
}



static size_t __LomutoPartition(void *base,size_t lo,size_t hi,size_t size,int (*cmp)(const void *, const void *))
{
  crtl_byte *ptr = (crtl_byte *)base;
  crtl_byte *p = ptr + hi * size;

  int i = lo - 1;
  size_t j;

  for(j = lo; j < hi; j++)
    if(cmp(ptr + j * size, p) > 0)
      crtl_memswap(ptr + (++i) * size, ptr + j * size, size);

  crtl_memswap(ptr + (i + 1) * size, ptr + j * size, size);

  return i + 1;
}

void crtl_sort_qsortL(void *base,size_t lo,size_t hi,size_t size,int (*cmp)(const void *, const void *))
{
    size_t p;

    if((long)hi <= (long)lo)
        return;
    else {
        p = __LomutoPartition(base, lo, hi, size, cmp);
        crtl_sort_qsortL(base, lo, p - 1, size, cmp);
        crtl_sort_qsortL(base, (p + 1), hi, size, cmp);
    }
}


void crtl_sort_selection(void *base,size_t num,size_t size,int (*cmp)(const void *, const void *))
{
    crtl_byte *pvBase = (crtl_byte *)base;
    size_t i, j;
    size_t m;

    if(num) {
        for(i = 0; i < num; i++) {
            m = i;

            for(j = i + 1; j < num; j++)
                if(cmp(pvBase + j * size, pvBase + m * size) > 0) 
                    m = j;

            crtl_memswap(pvBase + i * size, pvBase + m * size, size);
        }
    }
}


void crtl_sort_shell(void *base,size_t num,size_t size,int (*cmp)(const void *, const void *))
{
    crtl_byte *pbBase = (crtl_byte *)base;
    size_t i, j;
    size_t h = 1;

    if(num) {
        while(h < num / 3)
            h = 3 * h + 1;

        while(h >= 1) {
            for(i = 1; i < num; i++)
                for(j = i; j > 0 && cmp(pbBase + j * size, pbBase + (j - 1) * size) > 0; j--)
                    crtl_memswap(pbBase + j * size, pbBase + (j - 1) * size, size);
            h /= 3;
        }
    }
}

发布了632 篇原创文章 · 获赞 325 · 访问量 57万+

猜你喜欢

转载自blog.csdn.net/Rong_Toa/article/details/105302068
今日推荐