通用数组的插入排序与Shell排序

比较函数可能需要根据具体的数组类型来重新实现,再调用

#include <cstdio>
#include <cstdlib>
#include <string.h>

// 定义比较结果的枚举类型
typedef enum
{
    LESS  = -1,   // 表示第一个元素小于第二个元素
    EQUAL = 0,    // 表示两个元素相等
    GREATER       // 表示第一个元素大于第二个元素
} Compare_Value_t;

// 定义排序顺序的枚举类型
typedef enum
{
    ASCENDING = 0,   // 表示升序排序
    DESCENDING       // 表示降序排序
} Sort_Order_t;      // 获取数组中第 num 个元素的指针

void* GetPoint(void* FirstPoint, size_t Elem_size, size_t num)
{
    return (char*)FirstPoint + Elem_size * num;
}

// 比较两个元素的值
Compare_Value_t Compare_Elem(void* e1, void* e2)
{
    return *(int*)e1 == *(int*)e2 ? EQUAL : *(int*)e1 > *(int*)e2 ? GREATER
                                                                  : LESS;
}


// 插入排序函数
void Insert_Sort(void* SortArray, size_t Elem_size, size_t num, Compare_Value_t Compare(void* e1, void* e2), Sort_Order_t order)
{
    void* temp = malloc(Elem_size);   // 分配临时存储空间
    int   i, j;

    for (i = 1; i < num; i++)
    {
        // 如果排序顺序为降序且当前元素大于前一个元素
        if (order == DESCENDING && Compare(GetPoint(SortArray, Elem_size, i), GetPoint(SortArray, Elem_size, i - 1)) == GREATER)
        {
            memcpy(temp, GetPoint(SortArray, Elem_size, i), Elem_size);   // 将当前元素复制到临时存储
            for (j = i - 1; j >= 0 && Compare(GetPoint(SortArray, Elem_size, j), temp) == LESS; j--)
            {
                memcpy(GetPoint(SortArray, Elem_size, j + 1), GetPoint(SortArray, Elem_size, j), Elem_size);   // 将前一个元素向后移动
            }
            memcpy(GetPoint(SortArray, Elem_size, j + 1), temp, Elem_size);   // 将临时存储的元素放到正确位置
        }
        // 如果排序顺序为升序且当前元素小于前一个元素
        if (order == ASCENDING && Compare(GetPoint(SortArray, Elem_size, i), GetPoint(SortArray, Elem_size, i - 1)) == LESS)
        {
            memcpy(temp, GetPoint(SortArray, Elem_size, i), Elem_size);   // 将当前元素复制到临时存储
            for (j = i - 1; j >= 0 && Compare(GetPoint(SortArray, Elem_size, j), temp) == GREATER; j--)
            {
                memcpy(GetPoint(SortArray, Elem_size, j + 1), GetPoint(SortArray, Elem_size, j), Elem_size);   // 将前一个元素向后移动
            }
            memcpy(GetPoint(SortArray, Elem_size, j + 1), temp, Elem_size);   // 将临时存储的元素放到正确位置
        }
    }
    free(temp);   // 释放临时存储空间
}


// Shell排序函数
void Shell_Sort(void* SortArray, size_t Elem_size, size_t num, Compare_Value_t Compare(void* e1, void* e2), Sort_Order_t order, int* gap, int gapnum)
{
    void* temp = malloc(Elem_size);   // 分配临时存储空间
    if (temp == NULL) return;         // 检查 malloc 是否成功

    int d, i, j, index, loop;

    // 如果 gap 数组为空,使用默认的 gap 序列
    if (gap == NULL)
    {
        // 使用默认的 gap 序列,从 num/2 开始,每次减半
        for (d = num / 2; d >= 1; d /= 2)
        {
            // 对每个 gap 进行排序
            for (i = 0; i < d; i++)
            {
                // 对每个子序列进行插入排序
                for (j = i + d; j < num; j += d)
                {
                    memcpy(temp, GetPoint(SortArray, Elem_size, j), Elem_size);   // 将当前元素复制到临时存储
                    if (order == DESCENDING)
                    {
                        // 如果排序顺序为降序且当前元素小于前一个元素
                        for (loop = j - d; loop >= 0 && Compare(GetPoint(SortArray, Elem_size, loop), temp) == LESS; loop -= d)
                        {
                            memcpy(GetPoint(SortArray, Elem_size, loop + d), GetPoint(SortArray, Elem_size, loop), Elem_size);   // 将前一个元素向后移动
                        }
                    }
                    else if (order == ASCENDING)
                    {
                        // 如果排序顺序为升序且当前元素大于前一个元素
                        for (loop = j - d; loop >= 0 && Compare(GetPoint(SortArray, Elem_size, loop), temp) == GREATER; loop -= d)
                        {
                            memcpy(GetPoint(SortArray, Elem_size, loop + d), GetPoint(SortArray, Elem_size, loop), Elem_size);   // 将前一个元素向后移动
                        }
                    }
                    memcpy(GetPoint(SortArray, Elem_size, loop + d), temp, Elem_size);   // 将临时存储的元素放到正确位置
                }
            }
        }
    }
    else
    {
        // 使用用户提供的 gap 序列
        for (index = 0; index < gapnum && (d = gap[index]) >= 1; index++)
        {
            // 对每个 gap 进行排序
            for (i = 0; i < d; i++)
            {
                // 对每个子序列进行插入排序
                for (j = i + d; j < num; j += d)
                {
                    memcpy(temp, GetPoint(SortArray, Elem_size, j), Elem_size);   // 将当前元素复制到临时存储
                    if (order == DESCENDING)
                    {
                        // 如果排序顺序为降序且当前元素小于前一个元素
                        for (loop = j - d; loop >= 0 && Compare(GetPoint(SortArray, Elem_size, loop), temp) == LESS; loop -= d)
                        {
                            memcpy(GetPoint(SortArray, Elem_size, loop + d), GetPoint(SortArray, Elem_size, loop), Elem_size);   // 将前一个元素向后移动
                        }
                    }
                    else if (order == ASCENDING)
                    {
                        // 如果排序顺序为升序且当前元素大于前一个元素
                        for (loop = j - d; loop >= 0 && Compare(GetPoint(SortArray, Elem_size, loop), temp) == GREATER; loop -= d)
                        {
                            memcpy(GetPoint(SortArray, Elem_size, loop + d), GetPoint(SortArray, Elem_size, loop), Elem_size);   // 将前一个元素向后移动
                        }
                    }
                    memcpy(GetPoint(SortArray, Elem_size, loop + d), temp, Elem_size);   // 将临时存储的元素放到正确位置
                }
            }
        }
    }

    free(temp);   // 释放分配的内存
}

void Info_Array_Integer(void* array, size_t num)
{
    printf("---------------------------\n");
    for (int i = 0; i < num; i++)
    {
        printf("%d ", *(int*)((char*)array + sizeof(int) * i));
    }
    printf("\n");
    printf("---------------------------\n");
}

int sortArray[5] = {10, 0, 2, -1, -8};
int arr[15]      = {23, 45, 12, 67, 34, 89, 10, 56, 78, 90, 33, 21, 44, 55, 66};
int main(int argc, char* argv[])
{
    Info_Array_Integer((void*)arr, 15);
    Shell_Sort(arr, sizeof(int), 15, Compare_Elem, ASCENDING, NULL, 0);
    Info_Array_Integer((void*)arr, 15);
    Shell_Sort(arr, sizeof(int), 15, Compare_Elem, DESCENDING, NULL, 0);
    Info_Array_Integer((void*)arr, 15);
    return 0;
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值