插入排序(Insertion sort)
通过构建有序序列,对未排序数据,在已排序序列中从后向前扫描,找到正确的排序位置并插入。在扫描过程中,需要反复把正确插入位置后的元素逐步向后挪位,为最新的元素提供插入空间。
该算法伪代码如下:
Insertion Sort(A, n) ---> A[1,...,n]
for j <—— 2 to n
do key <—— A[j]
i <—— j-1
while i>0 and A[i]>key
do A[i+1] <—— A[i]
i <—— i-1
A[i+1]=key
如果对伪代码算法描述觉得不够清晰,可以文字理解该算法思想:
1. 从第一个元素开始,该元素认为已经被排序;
2. 取出下一个元素,在已排序的元素序列中从后向前扫描;
3. 若扫描到已排序的某元素大于新元素,将该元素向后移动一个位置;
4. 重复步骤3,直到已排序的元素小于或等于新元素的位置;
5. 将新元素插入该位置
6. 重复步骤2~5
其实很容易理解,如同一排座椅按个子大小排序,一旦找到新人(新元素)的插入位置,那么其位置之后的人(已排序的元素)都要依次向后挪一个位置。
/***********************************************
Copyright: Lu Zhan
Data: 09/24/2018
Description: Insertion sorting algorithm
***********************************************/
#include <iostream>
using namespace std;
void insertion_sort(int arr[], int len) {
for (int j = 1; j < len; j++) {
int key = arr[j];
int i = j - 1;
while (i >= 0 && arr[i] > key)
{
arr[i + 1] = arr[i];
i -= 1;
}
arr[i+ 1] = key;
}
for ( int k = 0; k < len; k++)
{
cout << "array[" << k << "] = " << arr[k] << endl;
}
}
int main()
{
int array[10] = { 23, 11, 24, 8, 99, 22, 23, 10, 11, 0 };
insertion_sort(array, 10);
getchar();
return 0;
}
我们知道,C++是一门面向对象的编程语言,为了让代码更为简洁实用,可以更新代码如下:
/***********************************************
Copyright: Lu Zhan
Data: 09/24/2018
Description: Insertion sorting algorithm
***********************************************/
#include <iostream>
using namespace std;
class Insertion_sort {
public:
int array[10] = { 12, 11, 3, 98, 88, 77, 23, 42, 22, 11 };
void insertion_sort(int arr[], int len) {
for (int j = 1; j < len; j++) {
int key = arr[j];
int i = j - 1;
while (i >= 0 && arr[i] > key)
{
arr[i + 1] = arr[i];
i -= 1;
}
arr[i + 1] = key;
}
for (int k = 0; k < len; k++)
{
cout << "array[" << k << "] = " << arr[k] << endl;
}
}
};
int main()
{
//nt array[10] = { 23, 11, 24, 8, 99, 22, 23, 10, 11, 0 };
//insertion_sort(array, 10);
Insertion_sort Sort;
Sort.insertion_sort(Sort.array, 10);
getchar();
return 0;
}
算法复杂度分析:
在领悟一个算法的思想后,最重要的一部分是思考算法的复杂度。
对于插入排序算法,如果目标是将n个元素的序列排序,则其存在最好的情况和最坏的情况。最好情况是该序列已经是目标有序序列,这种情况下算法只需要执行n-1次比较操作,但事实上这种情况很少出出现。最坏情况则是给定序列与实际序列顺序相反,此时需要进行的比较次数为1/2*n*(n-1)次,赋值操作为比较操作的次数减去n-1次。平均来说,插入排序的算法复杂度为O(n^2),因此插入排序并不适合对于数据量较大的排序应用。