基本思想
折半插入排序,又称二分插入排序,先用折半查找1找到应该插入的位置,再移动元素
步骤(从小到大排序)
- 找到没有排序的元素
- 标记元素
- 对前面排好序的元素进行折半,low、high 上下界,mid标记为中间的元素
- 将标记元素与 mid 位置上的元素进行比较,如果标记元素<mid 位置上的元素,则应该插入到mid 的左边,high=mid-1;如果标记元素>mid 位置上的元素,则应该插入到 mid 的右边,low=mid+1。重复第3步
- 当 low>high 时停止折半查找,将[low,i-1]内的元素全部右移,并将标记元素插入到 low 所指的位置
算法代码
#include<iostream>usingnamespacestd; //折半(二分)插入排序算法(设置 nums[0] 为哨兵暂存标记元素)voidInsertSort(intnums[],intn){ inti,j,low,high,mid; for(i=2;i<n;i++){ if(nums[i]<nums[i-1]){ //若 nums[i]<nums[i-1] 即当前项比前一项小 nums[0]=nums[i]; //nums[0] 暂存 nums[i] low=1,high=i-1; //low、high用于标记已排好序列的上下界 while(low<=high){ //查找标记元素要插入的位置 mid=(low+high)/2; //mid 指向已排序区间的中间位置if(nums[mid]>nums[0]){ high=mid-1; //插入元素应在左子区间 }else{ low=mid+1; //插入元素应在右子区间 } } for(j=i;j>low;j--){ nums[j]=nums[j-1]; //将[low,i-1]的元素全部右移 } nums[low]=nums[0]; //将 nums[0] 插入到下标为 low 的位置 } } } //打印数组 voidprintNum(intnumbers[],intn){ for(inti=1;i<n;i++){ cout<<numbers[i]<<" "; } } intmain() { intnumbers[13]={0,3,44,5,44,47,15,36,26,27,2,99,1}; intn=sizeof(numbers)/sizeof(numbers[0]); //数组长度 InsertSort(numbers,n); //调用 InsertSort 函数进行插入排序 printNum(numbers,n); //打印数组 return0; }
算法性能分析
- 空间复杂度
- 时间复杂度
- 算法稳定性