排序(插入)
最近打算重新把基础过一遍,先搞搞排序。
插入排序:
顾名思义,我们就是一次次的不断插入我们的数据以保证他的单调性。就像我们平时斗地主一样的,不断的从右边选出一张牌插到左边,保证每次左边的拍一定比它小就可以了。
插入排序在排序过程中分为已排序部分和未排序部分,不断的从未排序部分拿出数字来向已排序部分插入。
举个例子:
A = {8,3,1,5,2,1};
1.{8|,3,1,5,2,1};
2.{3,8|,1,5,2,1};//把3拿出来与8比较,比8小则将8后移一位,将3插到8的前面
3.{1,3,8|,5,2,1};//把1拿出来与8比较,比8小则将8后移一位,再与3比较,则3后移一位,将1插在3的前面
4.{1,3,5,8|,2,1};//把5拿出来与8比较,比8小则将8后移一位,再与3比较,比3大,怎插在3的后面8的前面。
5.{1,2,3,5,8|,1};//同理继续
6.{1,1,2,3,5,8};//同理继续
最终完成了排序。
复杂度分析:
在这里需要估算每个A【i】元素再循环中移动的次数,最坏的情况下,每个i都要循环i次,总共需要1+2+......+N-1 = (N^2-N)/2次。忽略常熟项,则为O(N^2)。
优缺点:
插入排序算法,由于是N^2的复杂度,其实很少有人使用他,但是假如输入序列是一个降序排列,那么,我们完成排序就只要O(n)的复杂度了,由此不难看出插入排序在处理相对有序的序列时,还是很快的,希尔排序算法就是利用了这一特性。
代码如下:
1 #include <iostream> 2 #include <cstdio> 3 using namespace std; 4 5 const int maxn = 100 + 5; 6 7 int n; 8 int a[maxn]; 9 10 int main(){ 11 bool Flag = false; 12 scanf("%d",&n); 13 for(int i = 1;i <= n; i++)scanf("%d",&a[i]); 14 bool f = false; 15 for(int i = 1;i <= n; i++){ 16 if(f)printf(" "); 17 printf("%d",a[i]); 18 f = true; 19 } 20 for(int i = 2;i <= n; i++){ 21 int v = a[i]; 22 int j = i-1; 23 while(j >= 1 && a[j] > v){ 24 a[j+1] = a[j]; 25 j--; 26 } 27 a[j+1] = v; 28 printf("\n"); 29 bool flag = false; 30 for(int k = 1;k <= n; k++){ 31 if(flag)printf(" "); 32 printf("%d",a[k]); 33 flag = true; 34 } 35 } 36 printf("\n"); 37 }