1.基本概念
折半插入排序是将待排序序列分成两部分,前边是已经排好序的有序序列,后面是无序序列。每次从无序序列中拿出一个待排序元素a[i],按照折半查找的思想找到应插入位置a[high+1],折半查找是要找到这个元素,而插入排序是应该找到比前一个元素大,同时又比后一个元素小的位置。
2.函数实现
/*
算法思想:将待排序队列看成两部分,前半部分有序,后半部分无序。起始状态下,第一个元素有序,后面全部无序。
每次取出无序队列中的一个元素,将其插入有序队列。
对有序队列折半查找,找到待插入数据在有序队列中的位置。
进行插入操作。
*/
int HalfInsertSort(int a[],int n){
int low,mid,high;
int temp;
for(int i=1;i<n;i++){
if(a[i-1]>a[i]){//保证了排序的稳定性
temp=a[i];
low=0;
high=i-1;
//寻找插入位置
for(int j=i-1;j>=0&&low<=high;j--){
mid=(low+high)/2;
if(a[mid]<temp)
low=mid+1;
else{
high=mid-1;
}
}
for(int k=i-1;k>high;k--)
a[k+1]=a[k];
a[high+1]=temp;
}
}
for(int m=0;m<n;m++)
printf("%d\t",a[m]);
printf("折半插入排序!!!\n");
return 1;
}
3.主函数
int main()
{
int a[]={10,1,5,40,52,2,4};
int n=sizeof(a)/sizeof(int);
//DirectInsertSort(a,n);
HalfInsertSort(a,n);
return 0;
}
4.完整代码
#include <iostream>
using namespace std;
//直接插入排序
//DirectInsertSort(int &a[]);
//折半插入排序
//HalfInsertSort(int &a[]);
//希尔排序
//ShellInsertSort(int &a[]);
void DirectInsertSort(int a[],int n){
//int i=0;
int j=0;
int temp;
int k;
//根据数组性质,第一个元素a[0]本身有序,排序从第二个元素开始
for(j=1;j<n;j++){
temp=a[j];
if(j>0&&a[j-1]>a[j]){
for(k=j;k>0&& a[k-1]>temp;k--){
a[k]=a[k-1];
}
a[k]=temp;
}
}
for(j=0;j<n;j++)
printf("%d\t",a[j]);
printf("直接插入排序!!!\n");
}
/*
算法思想:将待排序队列看成两部分,前半部分有序,后半部分无序。起始状态下,第一个元素有序,后面全部无序。
每次取出无序队列中的一个元素,将其插入有序队列。
对有序队列折半查找,找到待插入数据在有序队列中的位置。
进行插入操作。
*/
int HalfInsertSort(int a[],int n){
int low,mid,high;
int temp;
for(int i=1;i<n;i++){
if(a[i-1]>a[i]){//保证了排序的稳定性
temp=a[i];
low=0;
high=i-1;
//寻找插入位置
for(int j=i-1;j>=0&&low<=high;j--){
mid=(low+high)/2;
if(a[mid]<temp)
low=mid+1;
else{
high=mid-1;
}
}
for(int k=i-1;k>high;k--)
a[k+1]=a[k];
a[high+1]=temp;
}
}
for(int m=0;m<n;m++)
printf("%d\t",a[m]);
printf("折半插入排序!!!\n");
return 1;
}
int main()
{
int a[]={10,1,5,40,52,2,4};
int n=sizeof(a)/sizeof(int);
//DirectInsertSort(a,n);
HalfInsertSort(a,n);
return 0;
}
5.运行过程(手动操作)
6.运行结果
7.总结
在写折半插入排序的时候if语句里面的for循环我写出来过,感觉自己懂了折半插入排序,但是又不理解为什么待排序元素要插在a[high+1],自己手动走了前两个插入过程,大致知道它不满足low<=high时退出循环high小于low,这样他应该插入到a[high+1]的位置,也就是a[low]位置。当遇到感觉自己已经会了的时候,但运行报错或者写不出来,就再看一遍算法定义,可以手动模拟一下过程,就会有一个不一样的理解。