经典排序之插入排序

来源:互联网 发布:阿里云售后技术支持 编辑:程序博客网 时间:2024/05/15 08:19

经典排序算法 – 插入排序Insertion sort  

插入排序就是每一步都将一个待排数据按其大小插入到已经排序的数据中的适当位置,直到全部插入完毕。 
插入排序方法分直接插入排序和折半插入排序两种,这里只介绍直接插入排序,折半插入排序留到“查找”内容中进行。 

  图1演示了对4个元素进行直接插入排序的过程,共需要(a),(b),(c)三次插入。



设数组为a[0…n-1]。

1.      初始时,a[0]自成1个有序区,无序区为a[1..n-1]。令i=1

2.      将a[i]并入当前的有序区a[0…i-1]中形成a[0…i]的有序区间。

3.      i++并重复第二步直到i==n-1。排序完成。


代码:

#include <iostream>using namespace std ;//C语言获取数组长度  注意宏定义不能换行#define getLength(array)  sizeof(array)/sizeof(array[0])//C++获取数据长度template <class T>int getLen(T& array) {return sizeof(array)/sizeof(array[0]);}int* insertSort1(int a[],int len1) {int i,j,k;for (i = 1; i < len1; i++) {for (j = 0; j < i; j++) {if (a[i] < a[j]) {break;}}        //这个地方要记得用一个变量保存这个值,不然下面的数据移动的时候会把这个数据改变int temp = a[i];      //for (k = j; k < i; k++) {   如果数据从左边移到右边 就有这个问题 such as a[2] = a[1]; -》a[2] = 4, //a[k+1] = a[k];          然后a[3] = a[2];  -》a[3] = 4; 所以向右移动数据,最先需要移动的最右边的数据//}                           而不是最左边的,请注意。        //向右移动数据for (k = i-1; k >= j; k--) {a[k+1] = a[k];}a[j] = temp;}return a;}void printArray(int* a, int len1) {for (int k = 0; k < len1; k++) {cout<<a[k]<<"\t";}cout<<endl;}int* insertSort2(int a[],int len1) {int i,j,temp;for (i = 1; i < len1; i++) {temp = a[i];j = i-1;while (j >= 0 && temp < a[j]) {a[j+1] = a[j];j--;}a[j+1] = temp;}return a;}int* insertSort3(int arr[],int len1) {int i,j,target;for (i = 1; i < len1; i++) {j = i;        target = arr[i];        while (j > 0 && target < arr[j - 1])        {            arr[j] = arr[j - 1];            j--;        }        arr[j] = target;}return arr;}int* insertSort4(int a[],int len1) {int i,j,temp;for (i = 1; i < len1; i++) {temp = a[i];for (j = i-1; j >= 0 && temp < a[j]; j--) {a[j+1] = a[j];}a[j+1] = temp;}return a;}int main() {   int array1[] = {5,1,4,2,3};int length =getLength(array1);cout<<"length:"<<length<<endl;int len1 = getLen(array1);int *b = insertSort1(array1, len1);//打印结果    printArray(b, len1);cout<<"------------------------"<<endl;int array2[] = {5,1,4,2,3};int *c = insertSort2(array2, len1);printArray(c ,len1);cout<<"------------------------"<<endl;int array3[] = {5,1,4,2,3};int *d = insertSort3(array2, len1);printArray(d ,len1);cout<<"------------------------"<<endl;int array4[] = {5,1,4,2,3};int *f = insertSort4(array2, len1);printArray(f ,len1);    return 0 ;}


结果:


分析:

稳定 
空间复杂度O(1) 
时间复杂度O(n2) 
最差情况:反序,需要移动n*(n-1)/2个元素 
最好情况:正序,不需要移动元素

数组在已排序或者是“近似排序”时,插入排序效率的最好情况运行时间为O(n);

插入排序最坏情况运行时间和平均情况运行时间都为O(n2)。

通常,插入排序呈现出二次排序算法中的最佳性能。

对于具有较少元素(如n<=15)的列表来说,二次算法十分有效。

在列表已被排序时,插入排序是线性算法O(n)。

在列表“近似排序”时,插入排序仍然是线性算法。

在列表的许多元素已位于正确的位置上时,就会出现“近似排序”的条件。

通过使用O(nlog2n)效率的算法(如快速排序)对数组进行部分排序,

然后再进行选择排序,某些高级的排序算法就是这样实现的。

0 0
原创粉丝点击