在算法的世界里,排序算法是基础且关键的一部分。无论是处理大规模数据,还是进行简单的列表整理,合适的排序算法都能让我们的程序高效运行。今天,我要向大家介绍一个我自己写的强大的排序算法模板库 ——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,欢迎反馈)