插入排序
2015-03-11 15:27
281 查看
在冒泡排序、选择排序编写代码之后,楼主渐渐找到了coding的信心,熟能生巧,就像写词唱曲之前,都得先背诵大量的诗词,熟悉各路歌曲,才能走出自己的路线,有自己的杰作。好吧,来让楼主继续进行"社会主义初级阶段"的任务,这次是插入排序。
以下面5个无序的数据为例:
65 27 59 64 58 (文中仅细化了第四次插入过程)
第1次插入: 27 65 59 64 58
第2次插入: 27 59 65 64 58
第3次插入: 27 59 64 65 58
第4次插入: 27 58 59 64 65
空间复杂度:O(1) (用于记录需要插入的数据)
稳定性:稳定
但楼主发现从后面查找插入的方式,代码复杂程度较低:
如果目标是把n个元素的序列升序排列,那么采用插入排序存在最好情况和最坏情况。最好情况就是,序列已经是升序排列了,在这种情况下,需要进行的比较操作需(n-1)次即可。最坏情况就是,序列是降序排列,那么此时需要进行的比较共有n(n-1)/2次。插入排序的赋值操作是比较操作的次数加上 (n-1)次。平均来说插入排序算法的时间复杂度为O(n^2)。因而,插入排序不适合对于数据量比较大的排序应用。但是,如果需要排序的数据量很小,例如,量级小于千,那么插入排序还是一个不错的选择。[
插入排序是在一个已经有序的小序列的基础上,一次插入一个元素。当然,刚开始这个有序的小序列只有1个元素,就是第一个元素。比较是从有序序列的末尾开始,也就是想要插入的元素和已经有序的最大者开始比起,如果比它大则直接插入在其后面,否则一直往前找直到找到它该插入的位置。如果碰见一个和插入元素相等的,那么插入元素把想插入的元素放在相等元素的后面。所以,相等元素的前后顺序没有改变,从原无序序列出去的顺序就是排好序后的顺序,所以插入排序是稳定的。
在冒泡排序、选择排序编写代码之后,楼主渐渐找到了coding的信心,熟能生巧,就像写词唱曲之前,都得先背诵大量的诗词,熟悉各路歌曲,才能走出自己的路线,有自己的杰作。好吧,来让楼主继续进行"社会主义初级阶段"的任务,这次是插入排序。
一. 算法描述
插入排序:插入即表示将一个新的数据插入到一个有序数组中,并继续保持有序。例如有一个长度为N的无序数组,进行N-1次的插入即能完成排序;第一次,数组第1个数认为是有序的数组,将数组第二个元素插入仅有1个有序的数组中;第二次,数组前两个元素组成有序的数组,将数组第三个元素插入由两个元素构成的有序数组中......第N-1次,数组前N-1个元素组成有序的数组,将数组的第N个元素插入由N-1个元素构成的有序数组中,则完成了整个插入排序。以下面5个无序的数据为例:
65 27 59 64 58 (文中仅细化了第四次插入过程)
第1次插入: 27 65 59 64 58
第2次插入: 27 59 65 64 58
第3次插入: 27 59 64 65 58
第4次插入: 27 58 59 64 65
二. 算法分析
平均时间复杂度:O(n2)空间复杂度:O(1) (用于记录需要插入的数据)
稳定性:稳定
三. 算法实现
从前向后查找的插入排序:/******************************************************** *函数名称:InsertSort *参数说明:pDataArray 无序数组; * iDataNum为无序数据个数 *说明: 插入排序 *********************************************************/ void InsertSort(int* pDataArray, int iDataNum) { for (int i = 1; i < iDataNum; i++) //从第2个数据开始插入 { int j = 0; while (j < i && pDataArray[j] <= pDataArray[i]) //寻找插入的位置 j++; if (j < i) //i位置之前,有比pDataArray[i]大的数,则进行挪动和插入 { int k = i; int temp = pDataArray[i]; while (k > j) //挪动位置 { pDataArray[k] = pDataArray[k-1]; k--; } pDataArray[k] = temp; //插入 } } }
但楼主发现从后面查找插入的方式,代码复杂程度较低:
/******************************************************** *函数名称:InsertSort *参数说明:pDataArray 无序数组; * iDataNum为无序数据个数 *说明: 插入排序 *********************************************************/ void InsertSort(int* pDataArray, int iDataNum) { for (int i = 1; i < iDataNum; i++) //从第2个数据开始插入 { int j = i - 1; int temp = pDataArray[i]; //记录要插入的数据 while (j >= 0 && pDataArray[j] > temp) //从后向前,找到比其小的数的位置 { pDataArray[j+1] = pDataArray[j]; //向后挪动 j--; } if (j != i - 1) //存在比其小的数 pDataArray[j+1] = temp; } }
四. 算法优化
插入排序中,总是先寻找插入位置,然后在实行挪动和插入过程;寻找插入位置采用顺序查找的方式(从前向后或者从后向前),既然需要插入的数组已经是有序的,那么可以采用二分查找方法来寻找插入位置,提高算法效率,但算法的时间复杂度仍为O(n2)。
//查找数值iData在长度为iLen的pDataArray数组中的插入位置 int FindInsertIndex(int *pDataArray, int iLen, int iData) { int iBegin = 0; int iEnd = iLen - 1; int index = -1; //记录插入位置 while (iBegin <= iEnd) { index = (iBegin + iEnd) / 2; if (pDataArray[index] > iData) iEnd = index - 1; else iBegin = index + 1; } if (pDataArray[index] <= iData) index++; return index; } /******************************************************** *函数名称:BinaryInsertSort *参数说明:pDataArray 无序数组; * iDataNum为无序数据个数 *说明: 二分查找插入排序 *********************************************************/ void BinaryInsertSort(int* pDataArray, int iDataNum) { for (int i = 1; i < iDataNum; i++) //从第2个数据开始插入 { int index = FindInsertIndex(pDataArray, i, pDataArray[i]); //二分寻找插入的位置 if (i != index) //插入位置不为i,才挪动、插入 { int j = i; int temp = pDataArray[i]; while (j > index) //挪动位置 { pDataArray[j] = pDataArray[j-1]; j--; } pDataArray[j] = temp; //插入 } } }
如果目标是把n个元素的序列升序排列,那么采用插入排序存在最好情况和最坏情况。最好情况就是,序列已经是升序排列了,在这种情况下,需要进行的比较操作需(n-1)次即可。最坏情况就是,序列是降序排列,那么此时需要进行的比较共有n(n-1)/2次。插入排序的赋值操作是比较操作的次数加上 (n-1)次。平均来说插入排序算法的时间复杂度为O(n^2)。因而,插入排序不适合对于数据量比较大的排序应用。但是,如果需要排序的数据量很小,例如,量级小于千,那么插入排序还是一个不错的选择。[
插入排序是在一个已经有序的小序列的基础上,一次插入一个元素。当然,刚开始这个有序的小序列只有1个元素,就是第一个元素。比较是从有序序列的末尾开始,也就是想要插入的元素和已经有序的最大者开始比起,如果比它大则直接插入在其后面,否则一直往前找直到找到它该插入的位置。如果碰见一个和插入元素相等的,那么插入元素把想插入的元素放在相等元素的后面。所以,相等元素的前后顺序没有改变,从原无序序列出去的顺序就是排好序后的顺序,所以插入排序是稳定的。
相关文章推荐
- 简单排序算法:冒泡、选择、插入
- 白话经典算法系列之二 直接插入排序的三种实现
- python 冒泡排序 选择排序 插入排序的对比分析
- 算法(algorithms)基础之:插入排序
- 排序——直接插入排序
- 插入排序之直接插入排序
- 直接插入排序法的解析
- 学习笔记-直接插入排序 15/01/05
- 插入排序思想与实现
- 直接插入排序
- 插入排序的一个应用-调整负数在前,正数在后,原来相对位置不变
- java语言编写链表的基本操作(链表的创建,插入,删除,打印,排序)
- php实现直接插入排序
- 数据结构之排序--插入类排序
- 插入排序与选择排序
- 插入排序(Scala语言实现)
- php -- 四种基础排序:冒泡、选择、插入、快速
- Java排序算法(五):直接插入排序
- 常用算法Java实现之直接插入排序
- 插入排序