2023/01/06更新
以下都是从小到大排序
直接插入排序
思路简述
- 将无序序列中的第一个数当做有序序列,后面都看作无序。
- 无序部分的首个数据元素插入到有序部分(数据与有序序列中的数进行比较,若有序序列中的数更大,则后移,反之,则插入到当前有序序列后一位中)。
- 重复第2步直到无序部分全部插入有序。(对无序序列从头到尾依次遍历)
代码注意问题
- 注意无序插入到有序的条件。(即内层for循环跳出的两种条件:有序序列数据元素小于无序部分首个元素和有序序列数据元素的索引出界(小于0))
- 只要内层循环跳出,无序元素就插入到有序后面。
a[j+1]=temp
复杂度
1.时间复杂度
最好情况就是全部有序,此时只需遍历一次,最好的时间复杂度为O(n)
最坏情况全部反序,内层每次遍历已排序部分,最坏时间复杂度为O(n2)
直接插入排序的平均时间复杂度为O(n2)
2.空间复杂度
辅助空间是常量(就是个temp)
平均空间复杂度为:O(1)
3.算法稳定性(就是原序列排完之后,小数是否仍然排在大数前面)
相同元素的前后顺序是否改变
结果
- 常规运行结果
- 使有序数组在后面的运行结果
希尔排序
思路简述
代码注意问题
- 一直比较(第二个for循环),需要两个限定条件j>=0()和temp<a[j],最后a[j+1]=temp
#include<stdio.h>
#include<stdlib.h>
void InsertSort(int a[],int n) //直接插入排序
{
int i,j;
int temp;
for(i=1;i<n;i++)
{
temp=a[i];
for(j=i-1;j>=0&&a[j]>temp;j--)
{
a[j+1]=a[j];
}
a[j+1]=temp;
print(a,n);
printf("\t%d\n",temp);
}
}
void InsertSort2(int a[],int n) //直接插入排序 (从尾部开始有序)
{
int i,j;
int temp;
for(i=n-2;i>=0;i--)
{
temp=a[i];
for(j=i+1;a[j]<temp&&j<n;j++)
{
a[j-1]=a[j];
}
a[j-1]=temp;
print(a,n);
printf("\t%d\n",temp);
}
}
void ShellSort(int a[],int n) //希尔排序
{
int i,j,gap;
int temp;
for(gap=n/2;gap>0;gap/=2)
{
for(i=gap;i<n;++i)
{
temp=a[i];
for(j=i;j>=gap&&a[j-gap]>temp;j-=gap)
a[j]=a[j-gap];
a[j]=temp;
}
}
}
void print(int array[],int n)
{
int i;
for(i=0;i<n;i++)
{
printf("%d ",array[i]);
}
}
int main()
{
int array[]={4,3,6,9,7,1,2,4,5,0}; //0 1 2 3 4 4 5 6 7 9
int n=10;
// InsertSort(array,n);
InsertSort2(array,n);
// ShellSort(array,n);
print(array,n);
}