#include <iostream>
#include <assert.h>
#include <stdlib.h>
#define XT( str ) #str
#define CNT_ARY( ary ) ( sizeof( ary ) / sizeof( ary[ 0 ] ) )
typedef int s32;
typedef unsigned int u32;
typedef unsigned char u8;
typedef float f32;
//1.快速排序
//冒泡排序的升级版本,数组左右两边小的数往左边移动,大的数往右边移动
//关键是取其中任意的一个元素作为参考值,围绕这个参考值 把小的往参考值左边移动,大的往左边移动
//eg.
//数组:[5][6][3][7][1] 降序排序
//取5作为参考,则循环一次得到:[1][3][5][7][6] 5左边比他小右边比它大 剩下的就是遍历[1][3] 和后面的[7][6] 直到元素为1
//下面是快速排序算法( 如果是非递归用栈数据结构存储范围 )
void QuickSort( s32 *p, s32 left, s32 right )
{
assert( nullptr != p );
if( left >= right )
{
return;
}
const auto key = p[ left ]; //我们 已经记录了key的值 此时[row=left] 空了来,作为基准参考值(任意一个元素都行一般都选left元素)
auto low = left;
auto high = right;
while( low < high )//移动 比key小在key左边, 比key大在key右边, 一次大循环做了两次操作
{
//eg.草稿
//[low 5][6][3][7][high 1]
while( low < high && p[ high ] >= key ) //从高位到低位找到小于key的元素索引
{
--high;
}
//eg.草稿
//[low 5][6][3][7][high 1]
//[low = 0, 5] = [high = 4, 1]
//[1][6][3][7][1]
p[ low ] = p[ high ]; //把小于key的放到低位low
while( low < high && p[ low ] <= key ) //从低位到高位找到大于key的元素索引
{
++low;
}
//eg.草稿
//[high = 4, 1] = [low = 1, 6]
//[1][6][3][7][6]
p[ high ] = p[ low ]; //把大于key的放到刚才空出来的高位high
}
//eg.草稿
//key始终在徘徊在中间 除非他是最小或者最大值 当row >= high 则 找到中间key的位置 使得 左边小于它 右边大于它
//[1][3][low = high = 2, 5][7][6]
p[low] = key; //[小于key 1][小于key 3][low key的位置 5][大于key 7][大于key 6]
QuickSort( p, left, low - 1 ); //递归[left 小于key 1][lwo -1 小于key 3] 确定他们之间的位置
QuickSort( p, low + 1, right ); //递归[low + 1 大于key 7][right 大于key 6] 确定他们之间的位置
}
//2.鸽巢排序
//如果我们能预估待排序数据中最大的数的话
//且在不可避免遍历每一个元素并且排序的情况下效率最好的一种排序算法
//eg.:例如已知1、2、3...N 当中顺序是乱的( 元素可以重复 )
//时间复杂度O( N + n )最好
//时间复杂度O( N * n )最坏
//空间复杂度O( N )
//下面是鸽巢排序算法
template< u32 maxval >
void PigeonholeSort( s32 *p, u32 len )
{
assert( nullptr != p );
//需要预定义空间 maxval + 1
u32 indexs[ maxval + 1 ] = {};
//统计元素个数
for( u32 i = 0; i < len; ++i )
{
++indexs[ p[ i ] ];
}
//遍历统计元素并且直接排序
u32 k = 0;
for( u32 i = 0; i < maxval + 1; ++i )
{
for( u32 j = 0; j < indexs[ i ]; ++j, ++k )
{
p[ k ] = i;
}
}
}
//3.基数排序
//利用数据的个位十位百位千位排序,是一种不必比较元素大小的一种排序算法
//eg.[99][91][15][1][7] 没有十位直接补0其他类推
//根据个位排序后[1][91][15][7][99]
//根据十位排序后[1][7][15][91][99] 两次循环就排序好数据
//下面是基数排序算法
void RadixSort( s32 *p, u32 len )
{
assert( nullptr != p );
//得到最大的位数数量
u8 maxbit = 0;
//倍数
u32 times = 1;
//计算最大位数数量
for( u32 i = 0; i < len;
C++高级排序算法详解
最新推荐文章于 2024-07-27 14:35:57 发布
本文详细讲解了C++中常见的高级排序算法,包括快速排序、鸽巢排序、基数排序、希尔排序、鸡尾酒排序、桶排序和归并排序,并提供了相应的代码实现。通过这些排序算法,读者可以深入理解各种排序方法的原理和应用场景。
摘要由CSDN通过智能技术生成