算法思想:
开辟另一个新空间,将待排中的n个元素,依次取出,插入到新空间的正确位置。
确定插入的位置:从队尾往队首依次比较,直到发现某个元素A比当前待插入元素B要小时,则B需要插入到A的后面
执行插入:将A后面的所有元素,往后移动一位,这样,A元素后面的这个位置就空闲出来,供B插入
思路举例:玩扑克牌,抓牌,插入手中已有牌的某个正确位置
最好情况:
如果待排序的数组是和期望的排序是完全有序的,则其每个元素只要和队尾的一个元素比较一次,就停止了,所以,假设每次比较的代价为1,则花费的代价为常量n,其和带排序集合的规模n是一个线性函数O(n)
最坏情况:
如果待排序的数组是完全倒序的,则其在第n个位置上的元素,要执行n-1次比较,其代价为:
(n-1) + (n-2) + (n-3) + ….. + 1,用数学符号表示就是:
=(n-1)*(n-2)/2 ,所以,其代价是二次函数级的O(n^2)
空间上,需要开辟与原数据规模同等大小的空间。。
算法实现:
//插入排序的原理:
//每拿取一张牌,都从后往前找,如果比当前牌大,则往后移,否则插入当前新牌
void SortInsert::do_insert_sort(int * data,int array_size){
int data_tmp [array_size];
//取未排序的牌
for (int oldIndex =0; oldIndex < array_size; oldIndex++) {
//当前未排序的待插入的牌
int key =data[oldIndex];
//理想情况下,待插入的位置就是当前位置
int insertIndex = oldIndex;
//发现左边比待插入的牌大,则将左边的牌往右移动一下
while (insertIndex -1 >= 0 && data_tmp[insertIndex -1] > key) {
//右移一下
data_tmp[insertIndex] = data_tmp[insertIndex-1];
insertIndex--;
}
//插入key
data_tmp[insertIndex] = key;
}
//值回写
for(int t=0;t<array_size;t++){
data[t] = data_tmp[t];
}
}
算法总结:
代价随着规模的增长,成n的平方级增长!同时,需要开辟与原数据规模同等大小的空间,但是如果待排序的集合已经趋向于有序,则使用插入算法的时间代价则趋向于O(n)