插入排序
- 基本思想:
假设一共有N个数。插入排序是:当将第P个元素进行插入时,从位置0到位置P-1上的元素是已经排过序的(这也是插入排序的名字由来)。我们只需要比较位置P上的元素与位置0到位置P-1上的所有元素的值,将第P个元素放到适当位置即可。当然,P是从1开始的(但是数组下标从零开始)。
如下表是插入排序示例:
- 原理分析:
第一次P=1,我们假设位置1以前的元素是已经排好序的。我们只需要将位置P=1上的元素与位置0到位置P-1=0上的所有元素进行比较,将位置1上的元素放到适当的位置即可。【8<34,所以将8与34交换】
第二次P=2,我们假设位置2以前的元素是已经排好序的。我们只需要将位置P=2上的元素与位置0到位置P-1=1上的所有元素进行比较,将位置2上的元素放到适当的位置即可。【64>34,不用移动,64>8,不用移动】
第三次P=3,我们假设位置3以前的元素是已经排好序的。我们只需要将位置P=3上的元素与位置0到位置P-1=2上的所有元素进行比较,将位置3上的元素放到适当的位置即可。【51<64,,将51与64交换,51>34,不用移动,51>8,不用移动】
第四次P=4,我们假设位置4以前的元素是已经排好序的。我们只需要将位置P=4上的元素与位置0到位置P-1=3上的所有元素进行比较,将位置2上的元素放到适当的位置即可。【32<64,将32与64交换,32<51,将32与51交换,32<34,将32与34交换,32>8,不用移动】
第五次P=5,我们假设位置5以前的元素是已经排好序的。我们只需要将位置P=5上的元素与位置0到位置P-1=4上的所有元素进行比较,将位置3上的元素放到适当的位置即可。【21<64,将21与64交换,21<51,将21与51交换,21<34,将21与34交换,21<32,将21与32交换,21>8,不用移动】
- 程序实现:
#include<iostream>
using namespace std;
void print(int a[], int n ,int i){
cout<<i <<":";
for(int j= 0; j<n; j++){
cout<<a[j] <<" ";
}
cout<<endl;
}
void InsertSort(int a[], int n)
{
int j,p;
int Tmp;
for(p=1;p<n;p++)
{
Tmp=a[p]; //现将位置p上的元素存储起来(因为后续的比较,将元素后移会覆盖位置p)
for(j=p;j>0&&a[j-1]>Tmp;j--)
a[j]=a[j-1];//因为j-1位置上的元素大于tmp,要把j-1位置元素往后移
a[j]=Tmp;
print(a,n,p);
}
}
int main(){
int a[6] = {34,8,64,51,32,21};
InsertSort(a,6);
print(a,6,6);
system("pause");
return 0;
}
- 程序实现分析:
两层for循环,第一层for循环确定比较的趟数,第二层for循环确定每趟比较的次数。程序中实现数据移动而没有明显的使用交换。每趟将p-1位置上的元素与哨兵元素(位置p上的元素)进行比较,若位置p-1位置上的元素大于哨兵元素(位置p上的元素),就将位置p-1上的元素后移。最终将位置P上的元素移动到它在前P+1个元素的正确位置上。
- 插入排序时间复杂度为O(n2)。