最近打算重新把基础过一遍,先搞搞排序。
插入排序:
顾名思义,我们就是一次次的不断插入我们的数据以保证他的单调性。就像我们平时斗地主一样的,不断的从右边选出一张牌插到左边,保证每次左边的拍一定比它小就可以了。
插入排序在排序过程中分为已排序部分和未排序部分,不断的从未排序部分拿出数字来向已排序部分插入。
举个例子:
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)的复杂度了,由此不难看出插入排序在处理相对有序的序列时,还是很快的,希尔排序算法就是利用了这一特性。
代码如下:
#include <iostream>
#include <cstdio>
using namespace std;
const int maxn = 100 + 5;
int n;
int a[maxn];
int main(){
bool Flag = false;
scanf("%d",&n);
for(int i = 1;i <= n; i++)scanf("%d",&a[i]);
bool f = false;
for(int i = 1;i <= n; i++){
if(f)printf(" ");
printf("%d",a[i]);
f = true;
}
for(int i = 2;i <= n; i++){
int v = a[i];
int j = i-1;
while(j >= 1 && a[j] > v){
a[j+1] = a[j];
j--;
}
a[j+1] = v;
printf("\n");
bool flag = false;
for(int k = 1;k <= n; k++){
if(flag)printf(" ");
printf("%d",a[k]);
flag = true;
}
}
printf("\n");
}