这篇接着介绍排序算法——折半插入排序算法
一、概念
折半插入排序(binary insertion sort)是对插入排序算法的一种改进,由于排序算法过程中,就是不断的依次将元素插入前面已排好序的序列中。由于前半部分为已排好序的数列,这样我们不用按顺序依次寻找插入点,可以采用折半查找的方法来加快寻找插入点的速度。
算法思想:在将一个新元素插入已排好序的数组的过程中,寻找插入点时,将待插入区域的首元素设置为a[low],末元素设置为a[high],则轮比较时将待插入元素与a[m],其中m=(low+high)/2相比较,如果比参考元素大,则选择a[low]到a[m-1]为新的插入区域(即high=m-1),否则选择a[m+1]到a[high]为新的插入区域(即low=m+1),如此直至low<=high不成立,即将此位置之后所有元素后移一位,并将新元素插入a[high+1]。
代码
方法一:
void InsertSort(ElemType A[],int n) { int i,j,low,high,mid; //使用哨兵; for(int i=2;i<=n;i++) //依次将A[2]~A[n]插入到前面已排序序列; { A[0]=A[i]; //将A[i]暂存到A[0]; low=1; high = i-1; //设置折半查找范围; while(low<=high) //折半查找(默认递增有序) { mid = (low+high)/2; //取中间点 if(A[mid].key>A[0].key) //查找左半子表; { high=mid-1; } else //查找右半子表; low = mid+1; } for(j=i-1;j>=high+1;j--) { A[j+1]=A[j]; //统一后移元素,空出插入位置 } A[high+1]=A[0]; //插入操作; } }
方法二:
void BinaryInsertSort(ElemType A[],int n) { //不使用哨兵; int i,j,low,high,mid; for(i = 1; i < n; i++) { low = 0; high = i - 1; while(low <= high) { mid = (low + high) / 2; if(A[mid] > A[i]) { high = mid - 1; } else low = mid + 1; } if(j != i - 1) { int temp = A[i]; for(j = i - 1; j >= high + 1; j--) A[j + 1] = A[j]; A[j + 1] = temp; } } }
二、代码实现
#include <stdio.h> #include <stdlib.h> //折半插入排序 void BinaryInsertSort(int A[], int n) { //不使用哨兵; int i, j=0, low, high, mid; for (i = 1; i < n; i++) { low = 0; high = i - 1; while (low <= high) { mid = (low + high) / 2; if (A[mid] > A[i]) { high = mid - 1; } else low = mid + 1; } if (j != i - 1) { int temp = A[i]; for (j = i - 1; j >= high + 1; j--) A[j + 1] = A[j]; A[j + 1] = temp; } } } //输出 void show_arr(int A[], int n) { int i = 0; for (i = 0; i < n;i++) { printf("%d ", A[i]); } } int main() { int sort_arr[9] = { 0,32, 34, 523, 53, 5, 65, 886, -35 }; BinaryInsertSort(sort_arr, 9); show_arr(sort_arr, 9); system("pause"); return 0; }