二分法排序C++

本文详细介绍了二分插入排序算法的实现原理与过程,通过对比插入排序,利用二分查找来确定待插入元素的位置,进而优化了排序效率。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

首先说一下二分法排序的原理,算法思想简单描述: 
在插入第i个元素时,对前面的0~i-1元素进行折半,先跟他们 
中间的那个元素比,如果小,则对前半再进行折半,否则对后半 
进行折半,直到left>right,然后再把第i个元素前1位与目标位置之间 
的所有元素后移,再把第i个元素放在目标位置上。


二分法排序最重要的一个步骤就是查找要插入元素的位置,也就是要在哪一个位置上放我们要准备排序的这个元素。
当我们查找到位置以后就很好说了,和插入排序一样,将这个位置以后的所有元素都向后移动一位。这样就实现了二分法排序。
  然后是怎么查找着一个位置呢,就是不断的比较已排序的序列中的中间元素和要排序元素,如果大于的话,说明这个要排序的元素在已排序序列中点之前的序列。

#include <stdlib.h>
#include <stdio.h>
void TwoInsertSort(int array[],int n)
{
      int left,right,num;
      int middle,j,i;
      for(i = 1;i < n;i++)
      {
          left = 0;// 准备
          right = i-1;
          num = array[i];         
          while( right >= left)// 二分法查找插入位置
          {
              middle = ( left + right ) / 2; // 指向已排序好的中间位置
              if( num < array[middle] )// 即将插入的元素应当在在左区间
               right = middle-1;
       else                    // 即将插入的元素应当在右区间
       left = middle+1;    
                   }
//每次查找完毕后,left总比right大一,a[left]总是存放第一个比num大的数,因此应从此处开始,每            //个元素右移一位,并将num存入a[left]中,这样就保证了a[0...i]是排好序的
          for( j = i-1;j >= left;j-- )// 后移排序码大于R[i]的记录
              array[j+1] = array[j];
          array[left] = num;// 插入
      }
}
看了以后就会发现,其实就是插入排序法的一种修改,当a[0],a[1]...a[i-1]排好序,寻找第i个元素在其中的位置时采用二分查找法,于是该算法称二分排序法,所以我认为这不是新的算法;另外有人说起时间复杂度是n*lgn的,其实不是,就算每次查找的时间是lgi,但是查找完毕还要移动元素,这个时间平均为i/2,于是总时间为(1/2+lg1) + (2/2 + lg2) + (3/2 + lg3) + ... + ((n-1)/2 + lg(n-1)), 约为n(n-2)/4+nlgn,所以时间复杂度还是n*n的。
### 蓝桥杯 C++ 二分法实现详解 在蓝桥杯竞赛中,C++二分法是一种常见的算法技巧,用于解决有序数据中的查找问题或者优化复杂度较高的暴力枚举方法。以下是基于提供的引用内容以及扩展的知识来解答如何使用 C++ 实现二分法。 #### 一、二分法基本原理 二分法的核心思想是在一个已知范围 `[left, right]` 内通过不断缩小搜索区间的方式快速定位目标值的位置或满足条件的结果。其时间复杂度通常为 \(O(\log n)\),适用于单调性较强的问题场景[^2]。 对于给定的目标值 `target` 和数组 `arr[]`,可以通过比较中间位置的值与目标值的关系逐步调整边界指针完成搜索过程: - 如果当前中间值小于目标值,则更新左界; - 反之则更新右界; - 当左右界限重合时结束循环并返回结果。 #### 二、具体应用案例分析——搬石头问题 根据引用描述,在某些情况下我们需要判断某个数值是否符合条件并通过幂运算验证。下面给出一段完整的代码片段展示如何利用布尔型辅助函数配合二分查找解决问题: ```cpp #include <iostream> #include <cmath> // 使用 pow 函数需引入此头文件 using namespace std; // 定义判定函数pd()用来测试a^m >= n 是否成立 bool pd(double a, int m){ double c = pow(a, m); if(c >= n) return true; else return false; } int main(){ double low = 0, high = max_value; // 初始化上下限 while(low < high - epsilon){ // 设置精度控制退出条件 double mid = (low + high)/2 ; if(pd(mid,k)) // 判断mid作为底数k次方后是否大于等于n high = mid ; // 若满足则尝试更小可能解 else low = mid + step_size ; // 否则增大下限继续探索更大候选者 } cout << fixed << setprecision(6)<<low<<endl;// 输出最终逼近答案保留六位小数形式呈现 return 0; } ``` 上述程序展示了如何结合自定义逻辑函数 `pd()` 来动态调节搜索空间直至达到预期精确程度为止。注意这里假设存在全局变量 `n`, `epsilon`(误差容忍限度),还有步长参数step_size等未明确定义部分需要依据实际题目补充完整。 #### 三、标准库支持下的简化版本 除了手动编写外层迭代结构之外,C++ STL 提供了内置模板类binary_search(),lower_bound()以及upper_bound()可以直接调用从而减少重复造轮子的工作量: ```cpp #include <algorithm> #include <vector> std::vector<int> data = { /* 已排序的数据序列 */ }; auto it = std::lower_bound(data.begin(),data.end(),keyValue); if(it != data.end()){ resultIndex = distance(data.begin(),it); }else{ // 处理找不到的情况... } ``` 以上方式更加简洁高效同时也减少了人为错误概率但是前提是输入源必须先经过预处理成为升序排列状态才能正常使用这些工具函数[^1]。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值