直接插入排序的进阶功法
折半插入排序的算法讲解:(默认为升序)
本质:折半插入排序利用二分法进行寻找待插入元素的位置,是直接插入排序的一种改进。
小伙伴们,如果对直接插入排序有问题,可以看小编的这一篇:
折半查找规则:假设数组的名字为a
利用三个下标 low high mid
low 一开始为 0 high 一开始为数组长度减一
mid = (low+high) /2
利用 a[mid]和待插入元素进行比较
如果 a[mid] > 待插入元素 high = mid -1
a[mid] < 待插入元素时 low = mid + 1
直到 low > high 结束 得到插入元素的位置
当排序列中不含有待插入元素
low |
high |
mid |
和插入的元素的比较(val) |
0 |
4 |
2 |
a[2] = 5 5< 7 low = mid +1 |
3 |
4 |
3 | a[3] = 9 9 > 7 high = mid -1 |
3 |
2 |
low > high 结束 待插元素的位置 high+1 |
low |
high |
mid |
和插入的元素的比较(val) |
0 |
4 |
2 |
a[2] = 5 5> -1 high = mid -1 |
0 |
1 |
0 |
a[0] = 0 0 > -1 high = mid -1 |
0 | -1 |
low > high 结束 待插元素的位置 high+1 |
low |
high |
mid |
和插入的元素的比较(val) |
0 |
4 |
2 |
a[2] = 5 5< 15 low = mid +1 |
3 |
4 | 3 | a[3] = 9 9 <15 low = mid +1 |
4 | 4 |
4 |
a[4] = 10 10<15 low = mid +1 |
5 | 4 | low > high 结束 待插元素的位置 high+1 |
结论:待插入元素的位置都是 high+1
当排序列中含有待插入元素
利用稳定性和时间复杂度的考虑,我们为上面的规则折半算法规则进行改进
折半查找规则:假设数组的名字为a
利用三个下标 low high mid
low 一开始为 0 high 一开始为数组长度减一
mid = (low+high) /2
利用 a[mid]和待插入元素进行比较
如果 a[mid] >= 待插入元素 high = mid -1
a[mid] < 待插入元素时 low = mid + 1
直到 low > high 结束 得到插入元素的位置
low |
high |
mid |
和插入的元素的比较(val) |
0 |
4 |
2 |
a[2] = 5 5== 5 low = mid +1 |
3 |
4 | 3 | a[3] = 5 5==5 low = mid +1 |
4 | 4 | 4 | a[4] = 10 10>5 high = mid -1 |
4 |
3 |
low > high 结束 待插元素的位置 high+1 |
结论:插入元素的位置都是 high+1
总结:元素的位置都是 high+1 得到插入位置就可以写代码了
//折半插入排序
void binarysort(int * a,int length,int val);
/*
a 指针变量 接受数组的首地址
length 数组的长度
val 待插入的元素
*/
void sort(int * a,int length);
void traversal(int * a,int length);
int main(void){
int a[5] = {2,-5,3,1,10};
sort(a,5);
traversal(a,5);
return 0;
}
void binarysort(int * a,int length,int val){
int low = 0;
int high = length-1;
int mid ;
int i;
while(low<=high){
mid = (low+high)/2;
if(a[mid]<=val){
low = mid+1;
}
else{
high = mid-1;
}
}
for(i=length-1;i>=high+1;--i){
a[i+1] = a[i];
}
a[high+1] = val;
return;
}
void sort(int * a,int length){
int i ;
for(i=1;i<length;++i){
binarysort(a,i,a[i]);
}
return;
}
void traversal(int * a,int length){
int i ;
for(i=0;i<length;++i){
printf("%d ",a[i]);
}
printf("\n");
return;
}