比较函数可能需要根据具体的数组类型来重新实现,再调用
#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;
}