看了一本书,《数据结构(C语言版)1000个问题与解答》,这本书第481-482页,介绍了一种快速排序方法,感觉挺有趣的(也感觉挺奇怪的,尤其是gap值的选择方法),就在VS2022中做了代码实现,和大家共同学习研究。
在VS2022中创建空项目,添加文件“main.cpp”,并输入如下代码:
#includeint update_gap(int gap); void combine_sort(double* pData, int nDataSize); void show_data_value(double* pData, int nDataSize); bool monotone_increasing(double* pData, int nDataSize); bool bPrint = true; // 是否显示 // 更新gap值(gap值是进行比较的两个元素之间的间隔数.) // 输入gap值,返回更新后的gap值. // 由combine_sort函数调用. int update_gap(int gap) { gap = (gap * 10) / 13; if (gap == 9 || gap == 10) gap = 11; if (gap < 1) return 1; return gap; } // 对数组pData中的数值按从小到大顺序排序(组合排序). // 组合排序的代码实现参考了文献《数据结构(C语言版)1000个问题与解答》第481-482页. void combine_sort(double *pData, int nDataSize) { int gap = nDataSize; std::cout << "gap初始值:" << gap << std::endl; bool bSwapped = false; do { bSwapped = false; gap = update_gap(gap); std::cout << "gap值:" << gap << std::endl; for (int i = 0; i < nDataSize - gap; i++) { if (pData[i]>pData[i + gap]) { // 比较 if(bPrint) std::cout << "交换pData[" << i <<"](值为"<< pData[i] << ")" << "和pData[" << i+gap << "](值为" << pData[i+gap]<<")的值:" << std::endl; // 交换.(将乌龟移到顶部,帮助兔子走到底部) double temp = pData[i]; pData[i] = pData[i + gap]; pData[i + gap] = temp; bSwapped = true; // 显示交换后数据的值 if (bPrint) show_data_value(pData, nDataSize); } } } while (gap > 1 || bSwapped); } // 显示数据的值 void show_data_value(double* pData, int nDataSize) { for (int i = 0; i < nDataSize; i++) std::cout << pData[i] << " "; std::cout << std::endl; } // 判断数组是否是单调递增的. bool monotone_increasing(double* pData, int nDataSize) { for (int i = 0; i < nDataSize - 1; i++) { if (pData[i + 1] < pData[i]) { std::cout << "pData[" << i + 1 << "](值" << pData[i + 1] << ")小于pData[" << i << "](值" << pData[i] << ")" << std::endl; return false; } } return true; } int main() { // 构造数组pData,元素个数为nDataSize int nDataSize = 13; double* pData = new double[nDataSize]; for (int i = 0; i < nDataSize; i++) pData[i] = nDataSize - i; // 排序前,显示pData的初始值. std::cout << "排序前pData的值:" << std::endl; show_data_value(pData, nDataSize); bool b = monotone_increasing(pData, nDataSize); // 调用combine_sort进行排序 combine_sort(pData, nDataSize); // 排序前,显示pData的初始值. std::cout << "排序后pData的值:" << std::endl; show_data_value(pData, nDataSize); if(!monotone_increasing(pData, nDataSize)) std::cout << "出错:排序后pData的值不满足单调递增性." << std::endl; else std::cout << "正确:排序后pData的值满足单调递增性." << std::endl; return 1; }
update_gap用于更新gap的值,这个更新算法确实有些新奇,看不明白这种算法是经过严格的数学证明还是根据经验设置的;combine_sort是排序的核心算法,通过比较、交换将数组元素按照从小到大排序;show_data_value是个辅助函数,用于显示数组的内容;monotone_increasing也是个辅助函数,用于验证数组中的元素是否是单调递增的。bPrint用于控制combine_sort执行过程中是否在控制台显示数组的内容。
main函数创建数组,并对函数的正确性进行检验。
当nDataSize的值为13时,其程序执行结果如下:
当nDataSize的值为1300时,排序依然正确。
虽然不是太明白gap值的更新算法,但是经过检验,这个组合排序算法确实是正确的,能正确地完成排序。



