目录
-
基本思想
维持数组左边有序,每次从右边拿出一个数,然后插入到左边,保持左边仍然有序。
举例:
原始:3,1,2,8,-4,0,10
第一趟:1,3,2,8,-4,0,10
第二趟:1,2,3,8,-4,0,10
第三趟:1,2,3,8,-4,0,10
第四趟:-4,1,2,3,8,0,10
第五趟:-4,0,1,2,3,8,10
第六趟:-4,0,1,2,3,8,10
-
C++实现
/*算法:插入排序*/
#include <iostream>
using namespace std;
/*********************************************************
Function:swap
Description:交换a,b两个变量的值
**********************************************************/
void swap(int & a,int & b){
int tmp = a;
a = b;
b = tmp;
}
/*********************************************************
Function:issort
Description:插入排序
Input:数组A[l,h]
Output:排序完成的数组A
*********************************************************/
void issort(int A[],int l,int h){
if(l<h){
int tmp;
//从第2个元素开始,依次将右边的元素插入左边
for(int i=l+1;i<=h;i++){
tmp = A[i];//保存要插入的数据
int j = i-1;
while(j>=0&&A[j]>tmp){//将大于tmp的数据向右移动
swap(A[j],A[j+1]);
j--;
}
A[j+1] = tmp;
}
}
}
int main(){
int A[] = {3,1,2,8,-4,0,10};
issort(A,0,6);
for(int i=0;i<7;i++)
cout<<A[i]<<" ";
}
-
时间复杂度
- 最好情况
当数组有序时,会执行n-1次比较,0次交换,时间复杂度为.
- 最坏情况
当数组逆序时,会执行1+2+…+n-1=n(n-1)/2次比较,n(n-1)/2次交换,时间复杂度为.
- 平均情况
平均情况下的时间复杂度为.
-
使用折半查找进行改进
- 先前在寻找要插入的位置时使用的是线性查找的方法,如果使用折半查找会提供一定的效率。
- C++实现
/*算法:折半查找插入排序*/
#include <iostream>
using namespace std;
/*********************************************************
Function:bs_issort
Description:通过折半查找找到要插入的位置,然后将元素插入
Input:数组A[l,h]
Output:排序完成的数组A
*********************************************************/
void bs_issort(int A[],int l,int h){
if(l<h){
for(int i=l+1;i<=h;i++){
int tmp = A[i];
int low = l,high = i-1;//有序元素的上下界
/*
列举所有的最终情况,最终low会指向大于tmp的位置
*/
while(low<=high){
int mid = (low+high)/2;
if(A[i]<mid)
high = mid - 1;
else
low = mid + 1;
}
//移动元素
for(int j=i-1;j>=low;j--)
A[j+1] = A[j];
A[low] = tmp;
}
}
}
int main(){
int A[] = {3,1,2,8,-4,0,10};
bs_issort(A,0,6);
for(int i=0;i<7;i++)
cout<<A[i]<<" ";
}