直接插入排序
基本思想:从第一个元素开始,取出下一个元素与前一个元素比 较,确定它插入的位置,并将它插入到子序列中。
算法:
- 从第二个元素到最后一个元素,依次将数组和前面子序中的数组进行比较,确定元素插入的位置;
- 将元素插入,并将子序中元素个数+1,直到所有元素都插入完为止。
for(int i=0;i<n-1;i++){//重点:i<n-1,最后一个往里插
int t=a[i+1];//后边的数
for(int j=i;j>=0;j--)//重点,后边的数不断与前边的数比较
if(t<a[j]){
int temp=a[j];
a[j]=t;
a[j+1]=temp;} }
//{3}
//{3,44}
//{3,,44,}t=38
//{3, ,38,44}t=5
for(int i=0;i<n;i++)
cout<<a[i]<<endl;
排序效率:
空间复杂度:O(1)
时间复杂度:O(n²)
希尔排序
希尔排序是直接插入排序的改进,改进的关键点:如何尽快找到插入为止。
算法:
- 设置间隔gap,对间隔序列进行分组,对每一组进行插入排序;
- 逐渐减小gap值,分组,插入排序。
序列:3, 44, 38, 5, 47, 15, 36, 26, 27, 2, 46, 4, 19, 50, 40
间隔1:gap = n / 2 = 7
按间隔分组:
(3,26)(44,27)(38,2)(5,46)(47,4)(15,19)(36,50) 40
组内插入排序:
(3,26)(27,44)(2,38)(5,46)(4,47)(15,19)(36,50)40
按照1,2位写出:
3, 27, 2, 5, 4, 15, 36, 40, 26, 44, 38, 46, 47, 19, 50
间隔2:gap = n / 2 = 7 / 2 = 3
按间隔分组:
(3, 5, 36, 44, 47)(27, 4, 40, 38, 19)(2, 15, 26, 46, 50)
组内插入排序:
(3, 5, 36, 44, 47)(4, 19, 27, 38, 40)(2, 15, 26, 46, 50)
按照位置写出:
3, 4, 2 , 5, 19 , 15, 36 , 27, 26, 44, 38, 46, 47, 40, 50
间隔3:gap = 3 / 2 = 1
插入算法,组内排序:
2, 3, 4, 5, 15, 19, 26, 27, 36, 38, 40, 44, 46, 47, 50
int gap=n/2;
while(gap>0){
for(int k=0;k<=gap;k++){//分组,对每组进行排序
for(int i=0;i<n-gap;i+=gap){//组内进行插入排序,组内增量是gap增量
int t=a[i+gap];
for(int j=i;j>=0;j-=gap)//后边元素与前进行排序
if(t<a[j]){
int temp=a[j];
a[j]=t;
a[j+gap]=temp;}
}}
gap/=2;}//重点
排序效率:
空间复杂度:O(1)
时间复杂度:O(n²)