[C语言] 插入排序之二分插入排序的特性及实现
[C语言] 插入排序之二分插入排序的特性及实现
1、算法特性
二分插入又称折半插入,也是一种稳定的插入排序方法,可以利用数组的特点快速定位指定索引的元素。
其时间复杂度因为折半算法而减少到O(nlog(2)n),空间复杂度为O(1)。
2、算法思路
以升序排列为例,先将arr[0]设为左端,再设置一个临时变量存储将要移动的插入值并将其设为右端(最初从arr[1]开始),再将它与左右端中间的数据进行比较。当中间值比插入值大时,说明插入点在中间值左边,右端设为中间点-1,插入值继续向左半区间检索;否则说明插入点在中间值右边,左端设为中间点+1,插入值继续向右半区间检索;检索一直持续到左端大于等于右端为止,检索结束后即可找到合适的插入位置。此时再将检索出来的插入点与插入值下标点之间的数据整体后移一位,最后将临时变量中的插入值插入插入点即可完成一个数据的排序。经过不断循环便可以将所有数据排列有序。
3、实现代码
1 #include <stdio.h> 2 3 // 插入排序 :二分插入,又称折半插入 4 void binary_insert_sort(int arr[],int len) 5 { 6 for(int i=1; i<len; i++) 7 { 8 int num = arr[i]; 9 int left = 0;// 左区间 10 int rigth = i-1;// 右区间 11 while(left <= rigth) 12 { 13 int mid = (left+rigth)/2;// 中间位置 14 if(num < arr[mid])// 要插入的位置还在左边 15 { 16 rigth = mid-1; 17 } 18 else 19 { 20 left = mid+1; 21 } 22 } 23 for(int j=i-1; j>=left; j--)// 移动数据 24 { 25 arr[j+1] = arr[j]; 26 } 27 if(left != i) 28 { 29 arr[left] = num; 30 } 31 } 32 } 33 34 void travel(int arr[],int len) 35 { 36 for(int i=0;i<len;i++) 37 { 38 printf("%d ",arr[i]); 39 } 40 printf("\n"); 41 } 42 43 int main() 44 { 45 int arr[] = {53,82,9,233,43,14,55,9,4,67}; 46 int len = sizeof(arr)/sizeof(arr[0]); 47 48 /* travel(arr,len); 49 insert_sort(arr,len); 50 travel(arr,len);*/ 51 52 travel(arr,len); 53 binary_insert_sort(arr,len); 54 travel(arr,len); 55 56 /* travel(arr,len); 57 shell_sort(arr,len); 58 travel(arr,len);*/ 59 }
4、实现效果