直接插入排序
最简单的排序方法。它的基本操作是将一个记录插入到已经排好序的有序表中,从而得到一个新的、记录增1的有序表。
把n个待排序的元素看成一个有序表和一个无序表,开始时有序表中只有一个元素,无序表中有n-1个元素;排序过程即每次从无序表中取出第一个元素,将它插入到有序表中,使之成为新的有序表,重复n-1次完成整个排序过程。
——————————那一季的银杏叶:https://www.cnblogs.com/snowcan/p/6244128.html
0.初始状态 3,1,5,7,2,4,9,6(共8个数)
有序表:3;无序表:1,5,7,2,4,9,6
1.第一次循环,从无序表中取出第一个数 1,把它插入到有序表中,使新的数列依旧有序
有序表:1,3;无序表:5,7,2,4,9,6
2.第二次循环,从无序表中取出第一个数 5,把它插入到有序表中,使新的数列依旧有序
有序表:1,3,5;无序表:7,2,4,9,6
3.第三次循环,从无序表中取出第一个数 7,把它插入到有序表中,使新的数列依旧有序
有序表:1,3,5,7;无序表:2,4,9,6
4.第四次循环,从无序表中取出第一个数 2,把它插入到有序表中,使新的数列依旧有序
有序表:1,2,3,5,7;无序表:4,9,6
5.第五次循环,从无序表中取出第一个数 4,把它插入到有序表中,使新的数列依旧有序
有序表:1,2,3,4,5,7;无序表:9,6
6.第六次循环,从无序表中取出第一个数 9,把它插入到有序表中,使新的数列依旧有序
有序表:1,2,3,4,5,7,9;无序表:6
7.第七次循环,从无序表中取出第一个数 6,把它插入到有序表中,使新的数列依旧有序
有序表:1,2,3,4,5,6,7,9;无序表:(空)
——————————那一季的银杏叶:https://www.cnblogs.com/snowcan/p/6244128.html
程序:
//直接插入排序
//升序排序
#include<stdio.h>
void InsertSort(int *a,int n)
{
int i,j,tmp;
for(i=1;i<n;i++)
{
if(a[i-1]>a[i])
{
tmp=a[i];
j=i;
while(j&&tmp<a[j-1])
{
a[j]=a[j-1];
j--;
}
a[j]=tmp;
}
}
}
int main()
{
int i;
int a[]={1,2,8,5,6,9,4,2,7,5};
int n=sizeof(a)/sizeof(int);
InsertSort(a,n);
for(i=0;i<n;i++)
printf("%d ",a[i]);
return 0;
}
直接插入排序的时间复杂度是o(n2) ;
折半插入排序
由于直接插入排序的前方数据已经基本有序,有时顺序查找很费时。因而产生了“折半”查找的排序。
——————————来自:百度文库https://wenku.baidu.com/view/0e6dc051a76e58fafab003e1.html
程序:
//折半插入排序
//升序排列
#include<stdio.h>
using namespace std;
void BInsertSort(int *a,int n)
{
int i,j,low,high,m,tmp;
for(i=1;i<n;i++)
{
if(a[i]<a[i-1])
{
low=0;
high=i-1;
tmp=a[i];
m=(low+high)/2;
while(low<high)//最后low==high跳出时,m=low=high
{ //因而总体来说,m最后记录的是插入位置
if(tmp<a[m])
high=m-1;
else if(tmp>a[m])
low=m+1;
else
break;
m=(low+high)/2;
}
for(j=i;j>m;j--)
a[j]=a[j-1];
a[j]=tmp;
}
}
}
int main()
{
int i;
int a[]={4,5,9,6,3,8,2,8,2,8,6,6,5,4,2,8,9,5};
int n=sizeof(a)/sizeof(int);
BInsertSort(a,n);
for(i=0;i<n;i++)
printf("%d ",a[i]);
return 0;
}
希尔排序
插入排序在基本有序的情况下效率挺高,希尔排序可使程序部分逐渐变得有序。
一. 算法描述
希尔排序:将无序数组分割为若干个子序列,子序列不是逐段分割的,而是相隔特定的增量的子序列,对各个子序列进行插入排序;然后再选择一个更小的增量,再将数组分割为多个子序列进行排序......最后选择增量为1,即使用直接插入排序,使最终数组成为有序。
增量的选择:在每趟的排序过程都有一个增量,至少满足一个规则 增量关系 d[1] > d[2] > d[3] >..> d[t] = 1 (t趟排序);根据增量序列的选取其时间复杂度也会有变化,这个不少论文进行了研究,在此处就不再深究;本文采用首选增量为n/2,以此递推,每次增量为原先的1/2,直到增量为1;
下图详细讲解了一次希尔排序的过程:
--------------------- 本文来自 love小仙 的CSDN 博客 ,全文地址请点击:https://blog.csdn.net/jianfpeng241241/article/details/51707618?utm_source=copy
代码:
//希尔排序(升序)
#include<stdio.h>
void ShellInsert(int *a,int n)
{
int dk[]={5,3,1};
int dk_len=sizeof(dk)/sizeof(int);
int i,j,k,tmp1,tmp2;
for(i=0;i<dk_len;i++)
{
for(j=0;j<dk[i];j++)
{
for(k=j+dk[i];k<n;k+=dk[i])
{
if(a[k]<a[k-dk[i]])
{
tmp1=k;
tmp2=a[k];
while(tmp1>j&&tmp2<a[tmp1-dk[i]])
{
a[tmp1]=a[tmp1-dk[i]];
tmp1-=dk[i];
}
a[tmp1]=tmp2;
}
}
}
}
}
int main()
{
int i;
int a[]={8,2,5,8,7,4,2,6,3,85,62,5,4,3,2,22,25,87};
int n=sizeof(a)/sizeof(int);
ShellInsert(a,n);
for(i=0;i<n;i++)
printf("%d ",a[i]);
return 0;
}
参考文章: