【hoare优化版】快速排序算法 | 三数取中&小区间优化(2)

简介: 【hoare优化版】快速排序算法 | 三数取中&小区间优化(2)



上篇我们介绍了hoare基础版,但是这种代码存在缺陷,所以我们提出了两种解决方案。主流的解决方案就是【三数取中选key】

GitMidi三数取中

在快排的过程中,每一次我们要取一个元素作为枢纽值,以这个数字来将序列划分为两部分。在此我们采用三数取中法,也就是取左端、中间、右端三个数的下标,然后进行排序,将中间数作为枢纽值。

  • 取的三个数的中位数的下标
  • 取的是下标❗
  • 数值两两比较
  • 对快速排序的单趟的优化,三数取中是走快速排序逻辑(每趟的优化)
  • 三数取中:取三个数中的中位数下标,选到合适的数,避免选取到最小的最大的数,对顺序结构的效率优化很好。

整体思想

  • 设置三个值下标:begin // end // midi
  • 两个两个比较
  • 得到中位数的下标

图解分析

【顺序序列优化前:等差数列O(N^2)

【顺序序列优化后:类似二叉树等比数列O(N*logN)

代码实现

//三数取中
int GetMidi(int* a, int begin, int end)
{
  int midi = (begin + end) / 2;
  if (a[begin] < a[end])
  {
    if (a[begin] > a[midi])
    {
      return begin;
    }
    else if(a[end]<a[midi])
    {
      return end;
    }
    else
    {
      return midi;
    }
  }
  else//begin>=end
  {
    if (a[midi] < a[end])
    {
      return end;
    }
    else if (a[midi] > a[begin])
    {
      return begin;
    }
    else
    {
      return midi;
    }
  }
}

小区间优化

除了三数取中对顺序序列的快速排序起到了优化效果。如果数据量过大会造成

  • 快速排序递归层数太多,在debug版本底下会栈溢出。
  • 对于数据量过小用快速排序/希尔排序/堆排,效率反而没有直接插入排序高。(杀鸡用牛刀)直接插入排序对局部有序序列很友好。
  • 小区间优化走的直接插入的逻辑(整体的优化)
  • 注意❗❗❗❗小区间优化 优化的是递归的层数。

综上所诉,我们在用递归实现快速排序的基础上,如果数据量递归到一定程度过小,可以采用直接插入排序。这就是小区间优化。

整体思想

那么主要是优化那几层递归呢?

  • 主要优化递归层数的最后3~4层
  • 最后3~4层的递归层数占据了总的递归层数的80%(根据二叉树的性质)
  • 当数据量end-begin+1<=10的时候,让序列执行直接插入排序
  • 注意❗❗❗❗每段数据序列被分割了起始位置不一样不都是a,要用a+begin表示
  • 区间是[begin,end] ,此区间的数据量是end-begin+1

所以:小区间优化=数据量大(递归)+数据量小&递归层数多&最后3~4层(用插入排序)

图解分析

代码实现

void QuickSort(int* a, int begin,int end)
{
  if (begin >= end)//只有1个元素 没有区间
  {
    return;
  }
  //<10个数字走插入逻辑 
  if (end - begin + 1 <= 10)
  {
    InsertSort(a + begin, end - begin + 1);
  }
  //>10个数走快排逻辑
  else
  {
    int keyi = PartSort1(a, begin, end);
    QuickSort(a, begin, keyi - 1);
    QuickSort(a, keyi + 1, end);
  }
}

Hoare优化总代码

void Swap(int* p1, int* p2)
{
  int tmp = *p1;
  *p1 = *p2;
  *p2 = tmp;
}
//直接插入
void InsertSort(int* a, int n)
{
  // [0, end] end+1
  for (int i = 0; i < n - 1; ++i)
  {
    int end = i;
    int tmp = a[end + 1];
    while (end >= 0)
    {
      if (tmp < a[end])
      {
        a[end + 1] = a[end];
        --end;
      }
      else
      {
        break;
      }
    }
    a[end + 1] = tmp;
  }
}
//三数取中
int GetMidi(int* a, int begin, int end)
{
  int midi = (begin + end) / 2;
  if (a[begin] < a[end])
  {
    if (a[begin] > a[midi])
    {
      return begin;
    }
    else if(a[end]<a[midi])
    {
      return end;
    }
    else
    {
      return midi;
    }
  }
  else//begin>=end
  {
    if (a[midi] < a[end])
    {
      return end;
    }
    else if (a[midi] > a[begin])
    {
      return begin;
    }
    else
    {
      return midi;
    }
  }
}
//hoare版本&三数取中&每趟的优化
int PartSort1(int* a, int begin, int end)//返回分割线
{
  int left = begin;
  int right = end;
  int keyi = begin;
  //三数取中
  int midi = GetMidi(a, begin, end);
  Swap(&a[keyi], &a[midi]);
  while (left < right)
  {
    //找小
    while (left < right && a[right] >= a[keyi])
    {
      right--;
    }
    //找大
    while (left < right && a[left] <= a[keyi])
    {
      left++;
    }
    //找到了
    Swap(&a[right], &a[left]);
  }
  Swap(&a[left], &a[keyi]);
  keyi = left;
  return keyi;
  //分割 [begin,keyi-1] keyi [keyi+1,end]
}
//小区间优化&整体的优化
void QuickSort(int* a, int begin, int end)
{
  if (begin >= end)
  {
    return;
  }
  //<10个数字走插入逻辑 
  if (end - begin + 1 <= 10)
  {
    InsertSort(a + begin, end - begin + 1);
  }
  //>10个数走快排逻辑
  else
  {
    int keyi = PartSort1(a, begin, end);
    QuickSort(a, begin, keyi - 1);
    QuickSort(a, keyi + 1, end);
  }
}

🙂感谢大家的阅读,若有错误和不足,欢迎指正。

目录
打赏
0
0
0
0
14
分享
相关文章
基于DWA优化算法的机器人路径规划matlab仿真
本项目基于DWA优化算法实现机器人路径规划的MATLAB仿真,适用于动态环境下的自主导航。使用MATLAB2022A版本运行,展示路径规划和预测结果。核心代码通过散点图和轨迹图可视化路径点及预测路径。DWA算法通过定义速度空间、采样候选动作并评估其优劣(目标方向性、障碍物距离、速度一致性),实时调整机器人运动参数,确保安全避障并接近目标。
153 68
|
15天前
|
基于遗传优化算法的风力机位置布局matlab仿真
本项目基于遗传优化算法(GA)进行风力机位置布局的MATLAB仿真,旨在最大化风场发电效率。使用MATLAB2022A版本运行,核心代码通过迭代选择、交叉、变异等操作优化风力机布局。输出包括优化收敛曲线和最佳布局图。遗传算法模拟生物进化机制,通过初始化、选择、交叉、变异和精英保留等步骤,在复杂约束条件下找到最优布局方案,提升风场整体能源产出效率。
近端策略优化(PPO)算法的理论基础与PyTorch代码详解
近端策略优化(PPO)是深度强化学习中高效的策略优化方法,广泛应用于大语言模型的RLHF训练。PPO通过引入策略更新约束机制,平衡了更新幅度,提升了训练稳定性。其核心思想是在优势演员-评论家方法的基础上,采用裁剪和非裁剪项组成的替代目标函数,限制策略比率在[1-ϵ, 1+ϵ]区间内,防止过大的策略更新。本文详细探讨了PPO的基本原理、损失函数设计及PyTorch实现流程,提供了完整的代码示例。
177 10
近端策略优化(PPO)算法的理论基础与PyTorch代码详解
算法系统协同优化,vivo与港中文推出BlueLM-V-3B,手机秒变多模态AI专家
BlueLM-V-3B是由vivo与香港中文大学共同研发的多模态大型语言模型,专为移动设备优化。它通过算法和系统协同优化,实现了高效部署和快速生成速度(24.4 token/s),并在OpenCompass基准测试中取得优异成绩(66.1分)。模型小巧,语言部分含27亿参数,视觉编码器含4000万参数,适合移动设备使用。尽管如此,低端设备可能仍面临资源压力,实际应用效果需进一步验证。论文链接:https://arxiv.org/abs/2411.10640。
29 9
基于WOA鲸鱼优化的CNN-GRU-SAM网络时间序列回归预测算法matlab仿真
本项目基于MATLAB 2022a实现时间序列预测,采用CNN-GRU-SAM网络结构,结合鲸鱼优化算法(WOA)优化网络参数。核心代码含操作视频,运行效果无水印。算法通过卷积层提取局部特征,GRU层处理长期依赖,自注意力机制捕捉全局特征,全连接层整合输出。数据预处理后,使用WOA迭代优化,最终输出最优预测结果。
|
18天前
|
基于SOA海鸥优化算法的三维曲面最高点搜索matlab仿真
本程序基于海鸥优化算法(SOA)进行三维曲面最高点搜索的MATLAB仿真,输出收敛曲线和搜索结果。使用MATLAB2022A版本运行,核心代码实现种群初始化、适应度计算、交叉变异等操作。SOA模拟海鸥觅食行为,通过搜索飞行、跟随飞行和掠食飞行三种策略高效探索解空间,找到全局最优解。
量子算法的设计与优化:迈向量子计算的未来
量子算法的设计与优化:迈向量子计算的未来
35 3
基于GA遗传优化的CNN-LSTM-SAM网络时间序列回归预测算法matlab仿真
本项目使用MATLAB 2022a实现时间序列预测算法,完整程序无水印。核心代码包含详细中文注释和操作视频。算法基于CNN-LSTM-SAM网络,融合卷积层、LSTM层与自注意力机制,适用于金融市场、气象预报等领域。通过数据归一化、种群初始化、适应度计算及参数优化等步骤,有效处理非线性时间序列,输出精准预测结果。
基于GWO灰狼优化的多目标优化算法matlab仿真
本程序基于灰狼优化(GWO)算法实现多目标优化,适用于2个目标函数的MATLAB仿真。使用MATLAB2022A版本运行,迭代1000次后无水印输出结果。GWO通过模拟灰狼的社会层级和狩猎行为,有效搜索解空间,找到帕累托最优解集。核心步骤包括初始化狼群、更新领导者位置及适应值计算,确保高效探索多目标优化问题。该方法适用于工程、经济等领域复杂决策问题。
基于GA遗传算法的多机无源定位系统GDOP优化matlab仿真
本项目基于遗传算法(GA)优化多机无源定位系统的GDOP,使用MATLAB2022A进行仿真。通过遗传算法的选择、交叉和变异操作,迭代优化传感器配置,最小化GDOP值,提高定位精度。仿真输出包括GDOP优化结果、遗传算法收敛曲线及三维空间坐标点分布图。核心程序实现了染色体编码、适应度评估、遗传操作等关键步骤,最终展示优化后的传感器布局及其性能。

热门文章

最新文章

AI助理

你好,我是AI助理

可以解答问题、推荐解决方案等