对于各种数据类型的多钟排序算法的统一实现——冒泡排序、插入排序、选择排序、基于hibbard序列的希尔排序、堆排序、快速排序、归并排序共7种排序实现...

  函数接口为 

void MyXxxxSort(void * base, int num, int width, int (*cmp)(void *, void *));
//base为数组第一个元素的地址
//num为数组元素数量
//width为数组元素的大小
//cmp为元素的比较函数

  这个函数库实现了对各种数据类型的多种比较常见的排序算法的实现,其中各种排序算法的实现可以供大家一块学习探讨。

  下面附上各种排序算法的时间复杂度、空间复杂度、以及稳定性。

排序法

最差时间分析平均时间复杂度稳定性空间复杂度
冒泡排序O(n2)O(n2)稳定O(1)
快速排序O(n2)O(n*log2n)不稳定O(log2n)~O(n)
选择排序O(n2)O(n2)稳定O(1)
二叉树排序O(n2)O(n*log2n)不一顶O(n)

插入排序

O(n2)O(n2)稳定O(1)
堆排序O(n*log2n)O(n*log2n)不稳定O(1)
希尔排序OO不稳定O(1)

  以下为源代码:

#ifndef _M_SORT_H
#define _M_SORT_H

#include"m_sort.h"
#include<stdlib.h>
#include<math.h>
#include<stdio.h>
#include<string.h>
/*
typedef struct HeapStruct *MaxHeap;
struct HeapStruct{
    void *elements;
    int size;
    int maxsize;
};
*/

/*
 * 这些函数是实现某些复杂排序算法所需要调用的
 * 
 */
void Swap(void *a, void *b, int width);
int Hibbard(int num);
void ModifyDown(void *base, int begin, int end, int width, int cmp(const void *, const void *));
void MergeS(void *base,void *tmpBase, int num, int length, int width, int cmp(const void *, const void *));
void *Median(void *base, int left, int right, int width, int cmp(const void *, const void *));
void QuickSort(void *base, int cutoff, int left, int right, int width, int cmp(const void *, const void *));
/*MaxHeap HeapCreate(int maxsize);
void HeapInsert(MaxHeap H, void * item, int width, int (*cmp)(void *, void *));
void *HeapDelete(MaxHeap H);*/

/*
 * 这些函数是较为简单的排序算法
 */
void MySelectionSort(void *base, int num, int width, int cmp(const void *, const void *));
void MyInsertionSort(void *base, int num, int width, int cmp(const void *, const void *));
void MyBubbleSort(void *base, int num, int width, int cmp(const void *, const void *));

/*
 *这些函数是较为高级的排序算法
 */
void MyShellSort(void *base, int num, int width, int cmp(const void *, const void *));
void MyHeapSort(void *base, int num, int width, int cmp(const void *, const void *));
void MyMergeSort(void *base, int num, int width, int cmp(const void *, const void *));
void MyQuickSort(void *base, int num, int width, int cmp(const void *, const void *));


#endif
#include "m_sort.h"

void ModifyDown(void *base, int begin, int end, int width, int cmp(const void *, const void *))
{
    int parent, child;
    void *temp = (void *)malloc(width);
    memcpy(temp, base + (begin)*width,width);
    for (parent = begin; parent * 2 + 1 < end; parent = child) {
        child = 2 * parent + 1;
        if (child != (end -1) && cmp(base + child * width, base + (child + 1) * width) < 0) {
            child++;
        }
        if (cmp(temp , base + child * width) >= 0) 
            break;
        else
            memcpy(base + parent * width, base + child * width, width);
    }
    memcpy(base + parent * width, temp, width);
    free(temp);
}


void MergeS(void *base,void *tmpBase, int num, int length, int width, int cmp(const void *, const void *))
{
    int i, l, r, tmp;
    for (i = 0; i <= num - 2 * length; i += 2 * length ) {
        l = i; r = i + length; tmp = l;
        while (l < i + length && r < i + 2 * length) {
            if(cmp(base + l * width, base + r * width) > 0)
                memcpy(tmpBase + (tmp++) * width, base + (r++) * width, width);
            else
                memcpy(tmpBase + (tmp++) * width, base + (l++) * width, width);
        }
        while (l < i + length)
            memcpy(tmpBase + (tmp++) * width, base + (l++) * width, width);
        while (r < i + 2*length)
            memcpy(tmpBase + (tmp++) * width, base + (r++) * width, width);
    }

    if (i + length >= num) {
        tmp = i;
        while (i < num)
            memcpy(tmpBase + (tmp++) * width, base + (i++) * width, width);
    }
    else {
        l = i; r = i + length; tmp = l;
        while (l < i + length && r < num) {
            if(cmp(base + l * width, base + r * width) > 0)
                memcpy(tmpBase + (tmp++) * width, base + (r++) * width, width);
            else
                memcpy(tmpBase + (tmp++) * width, base + (l++) * width, width);
        }
        while (l < i + length)
            memcpy(tmpBase + (tmp++) * width, base + (l++) * width, width);
        while (r < num)
            memcpy(tmpBase + (tmp++) * width, base + (r++) * width, width);

    }

}

void *Median(void *base, int left, int right, int width, int cmp(const void *, const void *))
{
    int middle = (left + right) / 2;
    if (cmp(base + left * width, base + middle * width) > 0)
        Swap(base + left * width, base + middle * width, width);
    if (cmp(base + middle * width, base + right * width) > 0)
        Swap(base + right * width, base + middle * width, width);
    if (cmp(base + left * width, base + middle * width) > 0)
        Swap(base + left * width, base + middle * width, width);
    Swap(base + middle * width, base + (right-1) * width, width);
    return base + (right-1)*width;
}

void QuickSort(void *base, int cutoff, int left, int right, int width, int cmp(const void *, const void *))
{
    int i, j;
    void *pivot;
    pivot = (void *)malloc(width);
    if (right - left < cutoff) {
        MyInsertionSort(base + left * width, right - left + 1, width, cmp);
    }
    else {
        memcpy(pivot, Median(base, left, right, width, cmp), width);
        i = left;
        j = right - 1;
        while (1) {     
            while( cmp(base + (++i) * width, pivot) < 0);
            while( cmp(base + (--j) * width, pivot) > 0);
            if ( i < j) {
                Swap(base + i * width, base + j * width, width);
            }
            else
                break;
        }
        Swap(base + i * width, base + (right-1) * width, width);
        QuickSort(base, cutoff, left, i-1, width, cmp);
        QuickSort(base, cutoff, i+1, right, width, cmp);
    }
}

/*
 *if we choose to create a new heap, we can use these code.
 *however, we choose to modify the existing array to a maxheap.
 *
MaxHeap Create(int maxsize, int width)
{
    MaxHeap H = (MaxHeap)malloc(sizeof(struct HeapStruct));
    H->elements = (void *)malloc((maxsize + 1) * width);
    H->size = 0;
    H->maxsize = maxsize;
    
    return H;
}

void Insert(MaxHeap H, void * item, int width, int (*cmp)(void *, void *))
{
    int i;
    if (H->maxsize == H->size)) {
        printf("The heap is full!\n");
        return;
    }

    for (i = ++(H->size);i>1 && cmp(H->elements + i/2 * width, item) < 0; i /=2 )
        memcpy(H->elements + i * width, H->elements + i/2 * width);
    memcpy(H->elements + i * width, item, width);
}

void *HeapDelete(MaxHeap H, int width, int (*cmp)(void *, void *))
{
    int parent, child;
    void *maxitem, *tmp;
    if (H->size == 0) {
        printf("The heap is empty!\n");
        return;
    }
    maxitem = H->elements + width;
    H->size--;
    tmp = H->elements + H->size * width;
    for(parent = 1; parent*2 <= H->size; parent = child) {
        child = parent * 2;
        if ( child != H->size && cmp(H->elements + child * width, H->elements + (child + 1) * width) < 0)
            child++;
        if (cmp(tmp, H->elements + child * width) >= 0) 
            break;
        else
            memcpy(H->elements + parent * width, H->elements + child * width, width);
    }
    memcpy(H->elements + parent * width, tmp)
}

*/

void Swap(void *a, void *b, int width)
{
    void *tmp;
    tmp = (void *)malloc(width);
    memcpy(tmp, a, width);
    memcpy(a, b, width);
    memcpy(b, tmp, width);
    free(tmp);
}

int Hibbard(int num)
{
    int result, i;
    for (i = 0; pow(2, i) - 1 <= num; i++);
    result = pow(2, i - 1) - 1;
    return result;
}

void MyBubbleSort(void *base, int num, int width, int (*cmp)(const void *, const void *))
{
    int i, j, flag;
    for(i = num -1; i > 0; i--){
        flag = 0;
        for(j = 0; j < i; j++){
            if (cmp(base + j * width, base + (j+1)*width) > 0) {
                Swap(base + j * width, base + (j+1)*width, width);
                flag = 1;
            }
        }
        if (flag == 0)
            break;        
    }  
}

void MySelectionSort(void *base, int num, int width, int cmp(const void *, const void *))
{
    int i, j, tmp;
    for(i = num - 1; i > 0; i--){
        tmp = i;
        for(j = i - 1; j >= 0; j--){
            if(cmp(base + j * width, base + tmp * width) > 0){
                tmp = j;
            }
        }
        Swap(base + i * width, base + tmp * width, width);
    }
}

void MyInsertionSort(void *base, int num, int width, int cmp(const void *, const void *))
{
    int i, j, tmp;
    void *temp;
    temp = (void *)malloc(width);
    for (i = 1; i < num; i++) {
        memcpy(temp, base + i * width, width);
        for(j = i; j > 0 && cmp(base + (j - 1)*width, temp) > 0; j--)
            memcpy(base + j * width, base + (j - 1) * width, width);
        memcpy(base + j * width, temp, width);
    }
    free(temp);
}

void MyShellSort(void *base, int num, int width, int cmp(const void *, const void *))
{
    int i, j, k, tmp;
    void *temp;
    temp = (void *)malloc(width);
    for (i = Hibbard(num); i > 0; i /= 2) {
        for (j = i; j < num; j++) {
            memcpy(temp, base + j * width, width);
            for(k = j; k >= i && cmp(base + (k - i) * width, temp) > 0; k -= i)
                memcpy(base + k * width, base + (k - i) * width, width);
            memcpy(base + k * width, temp, width);
        }
    }
    
}

void MyHeapSort(void *base, int num, int width, int cmp(const void *, const void *))
{
    int i, j, k;
    for (i = num/2; i >= 0; i--) {
        ModifyDown(base, i, num, width, cmp);
    }
    for (i = num - 1; i > 0; i--) {
        Swap(base + 0 * width, base + i * width, width);
        ModifyDown(base, 0, i, width, cmp);
    }
}

void MyMergeSort(void *base, int num, int width, int cmp(const void *, const void *))
{
    int length = 1;
    void *tmpBase;
    tmpBase = (void *)malloc(num * width);
    if (tmpBase != NULL ) {
        while (length < num) {
            MergeS(base, tmpBase, num, length, width, cmp);
            length *= 2;
            MergeS(tmpBase, base, num, length, width, cmp);
            length *= 2;
        }
        free(tmpBase);
    }
    else{
        printf("ERROR! The memory is out of use!\n");
        return;
    }
}

void MyQuickSort(void *base, int num, int width, int cmp(const void *, const void *))
{
    int cutoff = 100;//cutoff must be bigger than 2
    QuickSort(base, cutoff, 0, num - 1, width, cmp);    
}

 

转载于:https://www.cnblogs.com/zjuhaotong/p/9626296.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值