探索 Sort.h:多功能排序算法模板库

发布于:2025-07-15 ⋅ 阅读:(15) ⋅ 点赞:(0)

在算法的世界里,排序算法是基础且关键的一部分。无论是处理大规模数据,还是进行简单的列表整理,合适的排序算法都能让我们的程序高效运行。今天,我要向大家介绍一个我自己写的强大的排序算法模板库 ——Sort.h,它提供了 10 种不同的排序算法,能满足各种场景下的排序需求。

一、Sort.h 概述

Sort.h 是一个用 C++ 编写的模板类库,它封装了多种常见的排序算法。这个库的核心是一个模板类 Sort,它可以处理不同数据类型的排序任务,只要这些数据类型支持 <> 、=(含拷贝构造)和 == 运算符。通过这个库,我们可以方便地选择不同的排序算法,并指定排序的顺序(升序或降序)。

二、核心功能

1. 多种排序算法支持

Sort.h 提供了以下 10 种排序算法:

  • 快速排序(Quick Sort):平均时间复杂度为 O(nlogn),在大规模随机数据上表现出色。
  • 归并排序(Merge Sort):时间复杂度稳定在 O(nlogn),并且是稳定排序算法。
  • 迭代归并排序(Iterative Merge Sort):避免了递归调用的栈开销,同样适用于大规模数据。
  • 冒泡排序(Bubble Sort):简单易懂,适合小规模数据或接近有序的数据。
  • 选择排序(Selection Sort):每次选择最小(或最大)元素,空间复杂度为 O(1)。
  • 插入排序(Insertion Sort):在小规模数据或接近有序的数据上效率较高。
  • 希尔排序(Shell Sort):对插入排序的改进,性能优于简单的插入排序。
  • 简单计数排序(Easy Counting Sort):适用于非负整数的排序,时间复杂度为 O(n+k)。
  • 计数排序(Counting Sort):适用于非负整数的排序,通过偏移量处理更广泛的数据范围。
  • 基数排序(Radix Sort):按位排序,适合处理非负整数数据,时间复杂度接近线性。

2. 灵活的排序顺序

Sort 类的构造函数允许我们指定排序顺序,通过 isAscending 参数,我们可以轻松实现升序或降序排序。

3. 模板类设计

由于采用了模板类设计,Sort.h 可以处理不同数据类型的排序任务,提高了代码的复用性。

三、模板库完整代码(复制即用)

//Sort.hpp
#pragma once
#include<functional>

/**
 * @brief 排序模板类,支持多种排序算法,可指定升序或降序
 * @tparam Data 待排序数据类型,该类型需要重载 <、>、== 、=(及拷贝构造)运算符以支持比较操作
 */
template<class Data>
class Sort
{

public:
    /**
     * @brief 比较函数指针类型,用于指向具体的比较函数
     * @param Data 第一个比较元素
     * @param Data 第二个比较元素
     * @return bool 比较结果(满足排序条件返回true,否则返回false)
     */
    using PCompare = bool (*)(Data, Data);

    /**
     * @brief 构造函数,初始化排序相关参数
     * @param data 指向待排序数组的指针
     * @param size 待排序数组的元素个数
     * @param isAscending 排序方式(true为升序,false为降序,默认升序)
     */
    Sort(Data* data, int size, bool isAscending = true);

    /**
     * @brief 快速排序接口
     */
    void sort_quick();

    /**
     * @brief 归并排序接口
     */
    void sort_merge();

    /**
     * @brief 迭代归并排序接口
     */
    void sort_merge_iter();

    /**
     * @brief 冒泡排序接口
     */
    void sort_bubble();

    /**
     * @brief 选择排序接口
     */
    void sort_select();

    /**
     * @brief 插入排序接口
     */
    void sort_insert();

    /**
     * @brief 希尔排序接口
     */
    void sort_shell();

    /**
     * @brief 计数排序(简化版)接口(直接寻址表排序)
     */
    void sort_count_easy();

    /**
     * @brief 计数排序接口
     */
    void sort_count();

    /**
     * @brief 基数排序接口
     */
    void sort_radix();
private:

    /**
     * @brief 归并操作的辅助函数,将两个有序数组合并为一个有序数组
     * @param c 存储合并结果的数组
     * @param d_size 结果数组的大小(冗余参数,实际为lena+lenb)
     * @param a 第一个有序数组
     * @param lena 第一个数组的长度
     * @param b 第二个有序数组
     * @param lenb 第二个数组的长度
     */
    void _merge(Data* c, int d_size, Data* a, int lena, Data* b, int lenb);

    /**
     * @brief 快速排序的内部递归实现
     * @param data 待排序的子数组
     * @param start 子数组的起始索引(包含)
     * @param end 子数组的结束索引(包含)
     */
    void _sort_quick(Data* data, int start, int end);

    /**
     * @brief 归并排序的内部递归实现
     * @param data 待排序的数组
     * @param size 待排序数组的元素个数
     */
    void _sort_merge(Data* data, int size);

    /**
     * @brief 归并排序的内部递归实现
     * @param data 待排序的数组
     * @param size 待排序数组的元素个数
     */
    void _merge_iter(Data* data, Data* temp, int left, int mid, int right);

    /**
     * @brief 判断第一个元素是否小于第二个元素(基于Data类型的<运算符)
     * @param t1 第一个比较元素
     * @param t2 第二个比较元素
     * @return bool 若t1 < t2返回true,否则返回false
     */
    bool _isLess(Data t1, Data t2);

    /**
     * @brief 判断第一个元素是否大于第二个元素(基于Data类型的>运算符)
     * @param t1 第一个比较元素
     * @param t2 第二个比较元素
     * @return bool 若t1 > t2返回true,否则返回false
     */
    bool _isGreater(Data t1, Data t2);
    
    /**
     * @brief 查找元素中的最大值
     * @param data 待排序的数组
     * @param size 待排序数组的元素个数
     */
    int _findMax(Data* data, int size);
    int _findMin(Data* data, int size, Data maxVal);
private:
    Data* data;          // 指向待排序数组的指针
    int size;            // 待排序数组的元素个数
    bool isAscending;    // 排序方向标志(true为升序,false为降序)
    PCompare p_com;      // 指向比较函数的指针(根据排序方向动态绑定)
};

/**
 * @brief 归并排序接口实现,调用内部递归函数
 */
template<class Data>
void Sort<Data>::sort_merge()
{
    _sort_merge(data, size);
}

/**
 * @brief 构造函数实现,初始化成员变量并设置比较函数
 * @note 升序时绑定_isLess函数,降序时绑定_isGreater函数
 */
template<class Data>
Sort<Data>::Sort(Data* data, int size, bool isAscending)
{
    this->data = data;
    this->size = size;
    this->isAscending = isAscending;
    if (isAscending)//升序
    {
        p_com = isless;
    }
    else
    {
        p_com = isgreater;
    }
    this->isAscending = isAscending;
}

/**
 * @brief 快速排序内部递归实现,采用挖坑法
 * @note 以区间首元素为基准,通过左右指针交换实现分区
 */
template<class Data>
void Sort<Data>::_sort_quick(Data* data, int start, int end)
{
    // 终止条件:区间无效时直接返回
    if (start >= end) return;

    int pivot = data[start];  // 选取区间首元素作为基准值(优化点:可改用三数取中法)
    int left = start;
    int right = end;

    while (left < right) {
        // 从右向左找第一个小于基准的元素
        while (left < right && (p_com(pivot, data[right]) || data[right] == pivot)) right--;
        if (left < right) data[left++] = data[right];  // 移动基准坑到左边

        // 从左向右找第一个大于基准的元素
        while (left < right && (p_com(data[left], pivot) || data[right] == pivot)) left++;
        if (left < right) data[right--] = data[left];  // 移动基准坑到右边
    }

    // 基准值归位
    data[left] = pivot;

    // 递归排序左右子区间(注意边界检查)
    if (start < left - 1) _sort_quick(data, start, left - 1);  // 左子区间至少2个元素
    if (left + 1 < end) _sort_quick(data, left + 1, end);      // 右子区间至少2个元素
};

/**
 * @brief 归并操作辅助函数,合并两个有序数组
 * @note 通过标记剩余元素减少循环次数,优化合并效率
 */
template<class Data>
void Sort<Data>::_merge(Data* c, int d_size, Data* a, int lena, Data* b, int lenb)
{
    // 标记是否需要将数组 a 或 b 的剩余元素直接连接到结果数组 c 中
    bool IsConnect_a = false, IsConnect_b = false;
    // 分别作为数组 a、b 和 c 的索引
    int i = 0, j = 0, k = 0;

    // 当数组 a 和 b 都还有元素未处理时,进行比较合并操作
    while (i < lena && j < lenb) {
        if (p_com(a[i], b[j]) || a[i] == b[j]) {
            // 如果 a[i] 小于等于 b[j],则将 a[i] 放入结果数组 c 中
            if (i + 1 == lena) {
                // 如果数组 a 只剩下当前元素,标记需要将数组 b 的剩余元素连接到结果数组 c 中
                IsConnect_b = true;
                c[k++] = a[i++];
                // 跳出循环,因为后续可以直接处理数组 b 的剩余元素
                break;
            }
            else {
                // 正常将 a[i] 放入结果数组 c 中,并更新索引
                c[k++] = a[i++];
            }
        }
        else {
            // 如果 a[i] 大于 b[j],则将 b[j] 放入结果数组 c 中
            if (j + 1 == lenb) {
                // 如果数组 b 只剩下当前元素,标记需要将数组 a 的剩余元素连接到结果数组 c 中
                IsConnect_a = true;
                c[k++] = b[j++];
                // 跳出循环,因为后续可以直接处理数组 a 的剩余元素
                break;
            }
            else {
                // 正常将 b[j] 放入结果数组 c 中,并更新索引
                c[k++] = b[j++];
            }
        }
    }

    // 处理数组 a 或 b 中剩余的元素
    if (IsConnect_a) {
        // 如果标记为需要连接数组 a 的剩余元素,则将数组 a 剩余元素依次放入结果数组 c 中
        while (i < lena) c[k++] = a[i++];
    }
    else if (IsConnect_b) {
        // 如果标记为需要连接数组 b 的剩余元素,则将数组 b 剩余元素依次放入结果数组 c 中
        while (j < lenb) c[k++] = b[j++];
    }
}

/**
 * @brief 归并排序内部递归实现,采用分治思想
 * @note 先将数组二分,递归排序子数组,最后合并有序子数组
 */
template<class Data>
void Sort<Data>::_sort_merge(Data* data, int size)
{
    // 计算数组的中间位置
    int mid = size / 2;
    // 左子数组的长度
    int left = mid;
    // 右子数组的长度
    int right = size - mid;
    // 用于遍历原数组的索引
    int k = 0;

    // 动态分配内存给左子数组
    Data* a = new Data[left];
    // 初始化左子数组的元素为 0
    for (int i = 0; i < left; i++) a[i] = 0;
    // 动态分配内存给右子数组
    Data* b = new Data[right];
    // 初始化右子数组的元素为 0
    for (int j = 0; j < right; j++) b[j] = 0;

    // 将原数组 data 的前 left 个元素复制到左子数组 a 中
    for (int i = 0; i < left; i++) *(a + i) = *(data + k++);
    // 将原数组 data 的剩余元素复制到右子数组 b 中
    for (int j = 0; j < right; j++) *(b + j) = *(data + k++);

    // 如果左子数组的长度大于 1,递归调用 MergeSort 函数对左子数组进行排序
    if (left > 1) _sort_merge(a, left);
    // 如果右子数组的长度大于 1,递归调用 MergeSort 函数对右子数组进行排序
    if (right > 1) _sort_merge(b, right);

    // 调用 Merge 函数将排好序的左子数组和右子数组合并到原数组 data 中
    _merge(data, size, a, left, b, right);

    // 释放动态分配给左子数组的内存,避免内存泄漏
    delete[] a;
    // 释放动态分配给右子数组的内存,避免内存泄漏
    delete[] b;
}

/**
 * @brief 快速排序接口实现,调用内部递归函数
 * @note 排序范围为整个数组(0到size-1)
 */
template<class Data>
void Sort<Data>::sort_quick()
{
    _sort_quick(data, 0, size - 1);
}

/**
 * @brief 冒泡排序实现,通过相邻元素比较交换完成排序
 * @note 每轮将最大/小元素"冒泡"到数组末尾
 */
template<class Data>
void Sort<Data>::sort_bubble()
{
    //2,4,8,6,5,3,9,1,7
    for (int i = 0; i < size; i++)
    {
        for (int j = 1; j < size - i; j++)
        {
            if (p_com(data[j], data[j - 1]))
            {
                Data temp = data[j - 1];
                data[j - 1] = data[j];
                data[j] = temp;
            }
        }
    }
}

/**
 * @brief 选择排序实现,每轮选择最小/大元素放到指定位置
 * @note 通过索引记录目标元素位置,减少交换次数
 */
template<class Data>
void Sort<Data>::sort_select()
{
    int index;
    Data temp;
    for (int i = 0; i < size - 1; i++)
    {
        //查找
        index = i;
        for (int j = i + 1; j < size; j++)
        {
            if (p_com(data[j], data[index]))
                index = j;
        }
        temp = data[i];
        data[i] = data[index];
        data[index] = temp;
    }
}

/**
 * @brief 插入排序实现,将元素插入到已排序部分的合适位置
 * @note 从第二个元素开始,依次插入到左侧有序区间
 */
template<class Data>
void Sort<Data>::sort_insert()
{
    int j;
    for (int i = 1; i < size; i++)//第一个本身就是有序的
    {
        //得到插入的数据
        Data temp = data[i];//右边数组i对应的的a[i]就是要插入的
        //把要插入数据之前的数组中需要移动版那个的部分后移一个下标
        for (j = i - 1; j >= 0 && p_com(temp, data[j]); j--)//左边有序数组倒序遍历,只要当前的a[j]比temp大,j就向前移动
        {
            data[j + 1] = data[j];//a[j+1]本质上就是a[i],即temp,所以覆盖掉不会丢失数据
        }
        //覆盖完以后
        data[j + 1] = temp;//运行到这一步时,
        //a[j] a[j+1] a[j+2]   ---- a[j+2]==a[j+1]
        //相当于a[j+1]的值已经备份,可以直接用要插入的数据覆盖a[j+1]进行插入
    }
}

/**
 * @brief 判断第一个元素是否小于第二个元素
 * @return bool 若t1 < t2返回true,否则返回false
 * @note 依赖Data类型的<运算符
 */
template<class Data>
bool Sort<Data>::_isLess(Data t1, Data t2)
{
    return t1 < t2;
}

/**
 * @brief 判断第一个元素是否大于第二个元素
 * @return bool 若t1 > t2返回true,否则返回false
 * @note 依赖Data类型的>运算符
 */
template<class Data>
bool Sort<Data>::_isGreater(Data t1, Data t2)
{
    return t1 > t2;
}

/**
 * @brief 归并排序接口实现,调用内部递归函数(迭代版)
 */
template<class Data>
void Sort<Data>::sort_merge_iter() {
    if (size <= 1) return;
    Data* temp = new Data[size];  // 仅分配一次辅助数组
    // 自底向上合并:子数组长度从1开始,每次翻倍
    for (int step = 1; step < size; step *= 2) {
        // 按当前step合并相邻子数组
        for (int left = 0; left < size; left += 2 * step) {
            int mid = left + step - 1;          // 左子数组终点
            int right = std::min(left + 2 * step - 1, size - 1);  // 右子数组终点(避免越界)
            if (mid >= right) break;  // 右子数组为空时跳过
            _merge_iter(data, temp, left, mid, right);  // 合并[left,mid]和[mid+1,right]
        }
    }
    delete[] temp;
}

// 迭代版合并函数(简化逻辑,复用辅助数组)
template<class Data>
void Sort<Data>::_merge_iter(Data* data, Data* temp, int left, int mid, int right) {
    int i = left, j = mid + 1, k = left;
    // 合并两个有序子数组到temp
    while (i <= mid && j <= right) {
        if (p_com(data[i], data[j])) {
            temp[k++] = data[i++];
        }
        else {
            temp[k++] = data[j++];
        }
    }
    // 处理剩余元素
    while (i <= mid) temp[k++] = data[i++];
    while (j <= right) temp[k++] = data[j++];
    // 从temp复制回原数组
    for (i = left; i <= right; i++) {
        data[i] = temp[i];
    }
}

/**
 * @brief 希尔排序接口实现
 */
template<class Data>
void Sort<Data>::sort_shell() {
    int step = size / 2;
    while (step > 0)
    {
        for (int m = 0; m < step; m++)
        {
            int j = 0;
            Data temp = 0;
            for (int i = m + step; i < size; i += step)//插入排序处理
            {
                temp = data[i];//要插入的数据
                for (j = i - step; j >= 0 && p_com(temp, data[j]); j -= step)
                {
                    data[j + step] = data[j];//元素后移
                }
                data[j + step] = temp;//插入元素
            }
        }
        step /= 2;
    }
}

template<class Data>
int Sort<Data>::_findMax(Data* data, int size)
{
    int max = -1;
    for (int i = 0; i < size; i++)
    {
        if (data[i] > 0)
        {
            max = data[i] > max ? data[i] : max;
        }
        else
        {
            throw "基数排序中的数据必须为不重复的正整数";
        }
    }
    return max;
}

template<class Data>
int Sort<Data>::_findMin(Data* data, int size,Data maxVal)
{
    int min = maxVal;
    for (int i = 0; i < size; i++)
    {
        if (data[i] > 0)
        {
            min = data[i] < min ? data[i] : min;
        }
    }
    return min;
}

/**
 * @brief 计数排序(简化版)(直接寻址表排序)接口实现 请注意:不要有重复的数据和非正整数!
 */
template<class Data>
void Sort<Data>::sort_count_easy()//计数排序_简化版
{
    //用一个数组存储数组a的值,存储在下标中,下标天然有序
    int maxSize = _findMax(data, size) + 1;
    Data* arr = new Data[maxSize];
    memset(arr, 0, sizeof(Data) * maxSize);
    for (int i = 0; i < size; i++)
    {
        arr[data[i]] = data[i];//将数据值按下标存储
    }
    if (isAscending==true)
    {
        int k = 0;
        for (int i = 0; i < maxSize; i++)
        {
            if (arr[i] != 0)data[k++] = arr[i];
        }
    }
    else
    {
        int k = 0;
        for (int i = maxSize-1; i >=0;i--)
        {
            if (arr[i] != 0)data[k++] = arr[i];
        }
    }
    delete[]arr;
}

/**
 * @brief 计数排序接口实现 请注意:正整数!
 */
template<class Data>
void Sort<Data>::sort_count()//计数排序_简化版
{
    //用一个数组存储数组a的值,存储在下标中,下标天然有序
   
    int maxVal = _findMax(data, size);
    int minVal = _findMin(data, size,maxVal);
    int maxSize = maxVal-minVal + 1;
    int basic_value = minVal;//基准参考数
    Data* arr = new Data[maxSize];
    memset(arr, 0, sizeof(Data) * maxSize);
    for (int i = 0; i < size; i++)
    {
        arr[data[i]-basic_value]++;//下标arr[i]对应的值计数
    }
    if (isAscending == true)
    {
        int k = 0;
        for (int i = 0; i < maxSize; i++)
        {
            if (arr[i] != 0)
            {
                for (int j = 0; j < arr[i]; j++)
                {
                    data[k++] = i + basic_value;//还原值
                }
            }
        }
    }
    else
    {
        int k = 0;
        for (int i = maxSize-1; i>=0; i--)
        {
            if (arr[i] != 0)
            {
                for (int j = arr[i]-1; j>=0 ; j--)
                {
                    data[k++] = i + basic_value;//还原值
                }
            }
        }
    }
    delete[]arr;
}

/**
 * @brief 基数排序接口实现(LSD方式:从最低位到最高位)
 * @note 仅支持正整数排序,通过桶排序实现每一位的分组排序
 */
template<class Data>
void Sort<Data>::sort_radix()
{
    if (size <= 1) return; // 边界条件:空数组或单个元素无需排序

    // 步骤1:找到最大值,确定最大位数
    int maxVal = _findMax(data, size);
    int maxDigits = 0;
    int tempVal = maxVal;
    while (tempVal > 0) {
        maxDigits++;       // 统计最大位数(如1234有4位)
        tempVal /= 10;
    }

    // 步骤2:初始化10个桶(0-9,对应每一位的可能数字)
    // 用动态数组存储桶,每个桶是一个临时存储元素的数组
    Data** buckets = new Data * [10];
    int* bucketSizes = new int[10](); // 记录每个桶的元素数量,初始化为0

    // 步骤3:从最低位到最高位,逐位处理
    for (int exp = 1; maxVal / exp > 0; exp *= 10) { // exp:1(个位)、10(十位)、100(百位)...
        // 重置桶大小
        memset(bucketSizes, 0, sizeof(int) * 10);
        // 先为每个桶分配足够空间(最多为数组大小)
        for (int i = 0; i < 10; i++) {
            buckets[i] = new Data[size];
        }

        // 3.1 将元素按当前位的数字放入对应桶中
        for (int i = 0; i < size; i++) {
            int digit = (data[i] / exp) % 10; // 提取当前位的数字(0-9)
            buckets[digit][bucketSizes[digit]++] = data[i]; // 放入桶并更新计数
        }

        // 3.2 从桶中取出元素,按顺序放回原数组(根据排序方向调整桶的遍历顺序)
        int index = 0; // 原数组的索引
        if (isAscending) {
            // 升序:按0-9的桶顺序取元素
            for (int i = 0; i < 10; i++) {
                for (int j = 0; j < bucketSizes[i]; j++) {
                    data[index++] = buckets[i][j];
                }
            }
        }
        else {
            // 降序:按9-0的桶顺序取元素
            for (int i = 9; i >= 0; i--) {
                for (int j = 0; j < bucketSizes[i]; j++) {
                    data[index++] = buckets[i][j];
                }
            }
        }

        // 3.3 释放当前轮的桶内存
        for (int i = 0; i < 10; i++) {
            delete[] buckets[i];
        }
    }

    // 释放桶的指针数组
    delete[] buckets;
    delete[] bucketSizes;
}


/**
 * @brief 说明:模板参数Data需要重载的运算符
 * 1. 小于运算符 < :用于_isLess函数的比较逻辑
 * 2. 大于运算符 > :用于_isGreater函数的比较逻辑
 * 3. 等于运算符 == :用于排序过程中相等元素的判断(如快速排序的基准比较)
 */

四、代码示例

以下是一个简单的使用示例,展示了如何使用 Sort.h 进行排序:

#include”Sort.hpp“
#include<stdio.h>
#include<iostream>
#include <windows.h>
#include <mmsystem.h>
#pragma comment(lib,"winmm.lib")
#define LENGTH 500
#define AREA LENGTH
#define M true
using namespace std;
template<class T>
void print(T a[], T len, const char* name)
{
	printf("----------------%s---------------\n", name);
	for (int i = 0; i < len; i++)
	{
		cout << a[i] << " ";
	}
	puts("");
}
bool flag = true;
int main()
{
	cout << "数据基数:" << LENGTH << endl;
	int beginTime=0, endTime=0;
	int size = LENGTH;

	srand(timeGetTime());
	

	int a[LENGTH] = { 0 };
	for (int i = 0; i < LENGTH; i++) {
		a[i] = LENGTH-i+1;//0-999
	}

	int a1[LENGTH] = { 0 };
	memcpy(a1, a, LENGTH * sizeof(int));
	size = sizeof(a1) / sizeof(int);
	Sort<int> s1(a1, size,flag); 
	beginTime = timeGetTime();
	s1.sort_bubble();
	endTime = timeGetTime();
	if (M)print <int> (a1, size, "冒泡排序");
	printf("%s耗费了%dms\n", "冒泡排序", endTime - beginTime);

	
	int a2[LENGTH] = { 0 };
	memcpy(a2, a, LENGTH*sizeof(int));
	size = sizeof(a2) / sizeof(int);
	Sort<int> s2(a2, size, flag);
	beginTime = timeGetTime();
	s2.sort_select();
	endTime = timeGetTime();
	if (M)print<int>(a2, size, "选择排序");
	printf("%s耗费了%dms\n", "选择排序", endTime - beginTime);

	
	int a3[LENGTH] = { 0 };
	memcpy(a3, a, LENGTH * sizeof(int));
	size = sizeof(a3) / sizeof(int);
	Sort<int> s3(a3, size, flag);
	beginTime = timeGetTime();
	s3.sort_insert();
	endTime = timeGetTime();
	if (M)print<int>(a3, size, "插入排序");
	printf("%s耗费了%dms\n", "插入排序", endTime - beginTime);

	
	int a4[LENGTH] = { 0 };
	memcpy(a4, a, LENGTH * sizeof(int));
	size = sizeof(a4) / sizeof(int);
	Sort<int> s4(a4, size, flag);
	beginTime = timeGetTime();
	s4.sort_quick();
	endTime = timeGetTime();
	if (M)print<int>(a4, size, "快速排序");
	printf("%s耗费了%dms\n", "快速排序", endTime - beginTime);

	
	int a5[LENGTH] = { 0 };
	memcpy(a5, a, LENGTH * sizeof(int));
	size = sizeof(a5) / sizeof(int);
	Sort<int> s5(a5, size, flag);
	beginTime = timeGetTime();
	s5.sort_merge();
	endTime = timeGetTime();
	if (M)print<int>(a5, size, "归并排序");
	printf("%s耗费了%dms\n", "归并排序", endTime - beginTime);

	int a6[LENGTH] = { 0 };
	memcpy(a6, a, LENGTH * sizeof(int));
	size = sizeof(a6) / sizeof(int);
	Sort<int> s6(a6, size, flag);
	beginTime = timeGetTime();
	s6.sort_merge_iter();
	endTime = timeGetTime();
	if (M)print<int>(a6, size, "迭代归并排序");
	printf("%s耗费了%dms\n", "迭代归并排序", endTime - beginTime);

	int a7[LENGTH] = { 0 };
	memcpy(a7, a, LENGTH * sizeof(int));
	size = sizeof(a7) / sizeof(int);
	Sort<int> s7(a7, size, flag);
	beginTime = timeGetTime();
	s7.sort_shell();
	endTime = timeGetTime();
	if (M)print<int>(a7, size, "希尔排序");
	printf("%s耗费了%dms\n", "希尔排序", endTime - beginTime);

	int a8[LENGTH] = { 0 };
	memcpy(a8, a, LENGTH * sizeof(int));
	size = sizeof(a8) / sizeof(int);
	Sort<int> s8(a8, size, flag);
	beginTime = timeGetTime();
	s8.sort_radix();
	endTime = timeGetTime();
	if (M)print<int>(a8, size, "基数排序");
	printf("%s耗费了%dms\n", "基数排序", endTime - beginTime);

	int a9[LENGTH] = { 0 };
	memcpy(a9, a, LENGTH * sizeof(int));
	size = sizeof(a9) / sizeof(int);
	Sort<int> s9(a9, size, flag);
	beginTime = timeGetTime();
	s9.sort_count();
	endTime = timeGetTime();
	if (M)print<int>(a9, size, "计数排序");
	printf("%s耗费了%dms\n", "计数排序", endTime - beginTime);
	return 0;
}

在这个示例中,我们创建了一个包含 5 个整数的数组,并使用 Sort 类的快速排序算法对其进行升序排序。最后,我们输出了排序后的数组。

四、算法选择建议

在实际应用中,我们需要根据数据的特点和具体需求来选择合适的排序算法。以下是一些建议:

  • 大规模随机数据:快速排序或归并排序通常是不错的选择。
  • 小规模数据:冒泡排序、选择排序或插入排序可能更合适。
  • 接近有序的数据:插入排序的效率较高。
  • 整数数据且取值范围较小:计数排序或基数排序可以提供线性时间复杂度。

五、总结

Sort.h 是一个功能强大、使用方便的排序算法模板库。它提供了多种排序算法,让我们可以根据不同的场景选择最合适的算法。无论是初学者学习排序算法,还是开发者处理实际项目中的排序任务,Sort.h 都是一个值得尝试的工具。

希望这篇介绍能让你对 Sort.h 有更深入的了解,如果你有任何问题或想法,欢迎在评论区留言讨论!(使用过程,若发现Bug,欢迎反馈)


网站公告

今日签到

点亮在社区的每一天
去签到