【排序算法】经典排序算法之插入排序

来源:互联网 发布:淘宝店过户 编辑:程序博客网 时间:2024/04/28 03:28
算法的基本思想是每次寻找新元素在已排好序的数组中的位置。

算法描述

一般来说,插入排序都采用in-place在数组上实现。具体算法描述如下:
1、从第一个元素开始,该元素可以认为已经被排序
2、取出下一个元素,在已经排序的元素序列中从后向前扫描
3、如果该元素(已排序)大于新元素,将该元素移到下一位置
4、重复步骤3,直到找到已排序的元素小于或者等于新元素的位置
5、将新元素插入到下一位置中
6、重复步骤2~5
如果比较操作的代价比交换操作大的话,可以采用二分查找法来减少比较操作的数目。该算法可以认为是插入排序的一个变种,称为二分查找排序。

复杂度和稳定性

时间复杂度为O(n*n),空间复杂度为O(1)。
如果目标是把n个元素的序列升序排列,那么采用插入排序存在最好情况和最坏情况。最好情况就是,序列已经是升序排列了,在这种情况下,需要进行的比较操作需(n-1)次即可。最坏情况就是,序列是降序排列,那么此时需要进行的比较共有n(n-1)/2次。插入排序的赋值操作是比较操作的次数加上 (n-1)次。平均来说插入排序算法的时间复杂度为O(n^2)。因而,插入排序不适合对于数据量比较大的排序应用。但是,如果需要排序的数据量很小,例如,量级小于千,那么插入排序还是一个不错的选择。
稳定性
插入排序是在一个已经有序的小序列的基础上,一次插入一个元素。当然,刚开始这个有序的小序列只有1个元素,就是第一个元素。比较是从有序序列的末尾开始,也就是想要插入的元素和已经有序的最大者开始比起,如果比它大则直接插入在其后面,否则一直往前找直到找到它该插入的位置。如果碰见一个和插入元素相等的,那么插入元素把想插入的元素放在相等元素的后面。所以,相等元素的前后顺序没有改变,从原无序序列出去的顺序就是排好序后的顺序,所以插入排序是稳定的。

模拟排序过程

以数据6,4,2,5,3,7,1为例,排序结果为从小到大。
第1次排序:
{6},{4,2,5,3,7,1}
第2次排序:
{4,6},{2,5,3,7,1}
第3次排序:
{2,4,6},{5,3,7,1}
第4次排序:
{2,4,5,6},{3,7,1}
第5次排序:
{2,3,4,5,6},{7,1}
第6次排序:
{2,3,4,5,6,7},{1}

基本算法

public static void insertSort(int[] array) {int len = array.length;for (int i = 1; i < len; i++) {int temp = array[i];int j = i - 1;while (j >= 0 && temp < array[j]) {array[j + 1] = array[j];j--;}array[j + 1] = temp;}}
针对插入排序,可以改进算法。将位置寻找修改为二分查找,对于数据量较大的数组来说,速度会快很多,引申为二分查找排序。

改进算法

public static void insertSort(int[] array) {int len = array.length;for (int i = 1; i < len; i++) {int temp = array[i];int pos = searchInsert(array, temp, i);int j = i - 1;while (j >= pos) {array[j + 1] = array[j];j--;}array[pos] = temp;}}

完整代码

public class Sort {/* * 插入排序(基本算法) * 2014年3月31日 10:37:11 */public static void insertSort(int[] array) {int len = array.length;for (int i = 1; i < len; i++) {System.out.println("第" + i + "次排序:");int temp = array[i];int j = i - 1;while (j >= 0 && temp < array[j]) {array[j + 1] = array[j];j--;}array[j + 1] = temp;printf(array);}}/* * 插入排序(二分查找改进) * 2014年3月31日 10:44:46 */public static void insertSort(int[] array) {int len = array.length;for (int i = 1; i < len; i++) {System.out.println("第" + i + "次排序:");int temp = array[i];int pos = searchInsert(array, temp, i);int j = i - 1;while (j >= pos) {array[j + 1] = array[j];j--;}array[pos] = temp;printf(array);}}public static int searchInsert(int[] array, int target, int len) {if (target < array[0]) {return 0;}if (target > array[len - 1]) {return len;}int low = 0;int high = len - 1;int mid = 0;while (low <= high) {mid = (low + high) >> 1;if (array[mid] > target) {high = mid - 1;} else if (array[mid] < target) {low = mid + 1;} else {return mid;}}return low;}private static void printf(int[] array) {for (int i = 0; i < array.length; i++) {System.out.print(array[i] + " ");}System.out.println();}public static void main(String[] args) {int array[] = { 6, 4, 2, 5, 3, 7, 1 };insertSort(array);printf(array);}}


0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 月花叶子黄了怎么办啊 养的花叶子发黄怎么办 桅子花叶子发黄怎么办 膨珊瑚变皱了怎么办 狗狗的脚断了怎么办 拔倒刺手指肿了怎么办 多肉发芽徒长了怎么办 黄丽又大又肥怎么办 小叶紫檀盘坏了怎么办 多肉植物烂根怎么办 檀木手串开裂了怎么办 手串越来越黑了怎么办 绿萝叶子尖发黄怎么办 绿萝叶子发黄有黑斑怎么办 绿萝叶子尖干枯怎么办 养的花叶子干了怎么办 云株花叶子发黄怎么办 驱蚊草叶子发黄怎么办 多肉叶子有黑点怎么办 多肉植物干瘪了怎么办 多肉叶片有黑点怎么办 多肉叶片有黑斑怎么办 多肉表面有黑点怎么办 杉果游戏买了后怎么办 盆景叶子上的灰怎么办 福建茶盆景掉叶怎么办 被普通蜘蛛咬了怎么办 被小蜘蛛咬了怎么办 被一般蜘蛛咬了怎么办 联通4g流量超出怎么办 腿上的肥胖纹怎么办除 金属眼镜腿歪了怎么办 炸东西油往外溢怎么办 油反复使用起沫怎么办 炸东西的油黑了怎么办 板栗放久了干了怎么办 三四个月的宝宝拉肚子怎么办 四个月的孩子拉肚子怎么办 4个月孩子拉肚子怎么办 三阳的房子很热怎么办 买了缺角的房子怎么办