我们所知道的排序算法有多种,根据理解程度以及时间复杂度等不同的要求,选择合适的排序算法。这里对多种排序算法进行说明以及代码实现。
- 插入排序
- 希尔排序
- 选择法排序
在理解希尔排序之前首先对插入排序进行理解,希尔排序是插入排序的特例,跨多步的插入排序,同时希尔排序是不稳定的排序算法。
1.插入排序:从下标为1的元素开始,之后的元素为即将进行插入排序的待排序组,即为A[j],将下标为0的元素作为有序组,即为A[i],其中设j=i-1,每次从待插入组中取出一个元素,与有序组的元素进行比较,若待排元素大于有序元素,则A[j–],一次与有序组元素进行比较,直到找到合适的位置,将该元素插到有序组当中,A[i++]。就这样,每次插入一个元素,有序组增加,待插入组减少。直到待插入组元素个数为0。
其中插入排序不稳定,时间复杂度为O(n),空间复杂度为O(1)。
2.希尔排序:先取一个小于n的整数a1作为第一个增量,把文件的全部记录分组。所有距离为a1的倍数的记录放在同一个组中。先在各组内进行直接插入排序;然后,取第二个增量a2<a1重复上述的分组和排序,直至所取的增量=1(<…<a2<a1),即所有记录放在同一组中进行直接插入排序为止。实质上是一种分组插入方法。将距离较远的两个数通过在同一个组中进行交换,每个组排序完成后,缩小距离增量,重复步骤,直到增量等于1,排序完成。
同插入排序,希尔排序,时间复杂度 O(n1.3-n1.5),空间复杂度 O(1),不稳定(跳跃式交换数据)
如下图所示,在未采用间隔分组的情况下进行分组排序,即将待排序组进实施成块分组,组内进行排序,效率上十分缓慢,只保证组内有序。
3.选择法排序:起初数组为无序数组,假设将第一个数字作为最小的数字,从待排序组中找到比当前下标为0的元素最小的元素进行交换,如果没有比当前数组小的则不进行交换,第一个元素为有序组,再从待排序组中找到比第二个元素最小的数字进行交换。每次交换的元素,放到有序组的后面,直到排序完成即可。
//插入排序
#include<stdio.h>
//大量数据基本有序,采用插入类操作
void InsertSort(int *arr,int len)//直接插入排序:O(n^2),O(1),稳定
{
int tmp;
int i;
int j;
for(i=1;i<len;i++)//1,2,3,4,5,有序,时间复杂度O(n)
{
tmp=arr[i];
for(j=i-1;j>=0;j--)//从后往前找
{
if(arr[j]<=tmp)
{
break;
}
else
{
arr[j+1]=arr[j];
}
}
arr[j+1]=tmp;
}
}
void Show(int *arr,int len)
{
for(int i=0;i<len;i++)
{
printf("%3d",arr[i]);
}
printf("\n");
}
int main()
{
int arr[]={9.0,1,3,6,2,7,8,10,13,12,11,14,16,15};
int len=sizeof(arr)/sizeof(arr[0]);
InsertSort(arr,len);
Show(arr,len);
return 0;
}
//希尔排序
#include<stdio.h>
void Shell(int *arr,int len,int gap)
{
int tmp;
int i;
int j;
for(i=gap;i<len;i++)
{
tmp=arr[i];
for(j=i-gap;j>=0;j-=gap)
{
if(arr[j]<=tmp)
{
break;
}
else
{
arr[j+gap]=arr[j];
}
}
arr[j+gap]=tmp;
}
}
void ShellSort(int *arr,int len)
{
int d[]={5,3,1};
for(int i=0;i<sizeof(d)/sizeof(d[0]);i++)
{
Shell(arr,len,d[i]);
}
}
void Show(int *arr,int len)
{
for(int i=0;i<len;i++)
{
printf("%3d",arr[i]);
}
printf("\n");
}
int main()
{
int arr[]={20,33,21,54,17,16,30,18,19,22,7,10,46,12,15};
ShellSort(arr,sizeof(arr)/sizeof(arr[0]));
Show(arr,sizeof(arr)/sizeof(arr[0]));
return 0;
}
#include<stdio.h>
/*
选择法排序:
每次跟待排序序列的后面的元素里面找到比当前数字最小的数字进行交换
复杂度:O(n^2) O(1)
算法的稳定性:不稳定,跳跃式的交换
*/
void SeleteSort(int *arr,int n)
{
int tmp=0;
int minindex=0;
for(int i=0;i<n;i++)
{
minindex=i;
for(int j=i+1;j<n;j++)
{
if(arr[j]<arr[minindex])
{
tmp=arr[j];
arr[j]=arr[minindex];
arr[minindex]=tmp;
}
}
}
}
void Show(int *arr,int n)
{
int m=0;
for(;m<n;m++)
{
printf("% d",arr[m]);
}
}
int main()
{
int arr[]={12,21,3,1,5,2,8,9,5,7};
int len=sizeof(arr)/sizeof(arr[0]);
SeleteSort(arr,len);
Show(arr,len);
return 0;
}