详解插入排序

Posted geekymv

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了详解插入排序相关的知识,希望对你有一定的参考价值。

插入排序(Insertion Sort)的过程就像我们排序扑克牌一样(从左到右,从小到大)。开始时我们左手为空,然后我们从桌子上拿起一张牌并将它插入到左手中正确的位置,为了找到这个位置,我们将这张牌与左手中从右向左的每张牌进行比较,直到找到比它小或相等的牌的后面。

与排序扑克牌类似,插入排序的原理是将数组中的数据分为两个区间,已排序区间未排序区间。初始已排序区间只有一个元素,就是数组的第一个元素,接着取未排序区间中的元素(数组的第二个元素),在已排序区间中找到合适的插入位置将其插入,并保证已排序区间数据一直有序,重复这个过程,直到未排序区间中元素为空。

还是中的需求:

排序前:4, 6, 3, 5, 2, 1

排序后:1, 2, 3, 4, 5, 6


算法过程

1、从第一个元素开始,该元素可以认为已经排序;

2、取出下一个元素,在已排序区间倒序遍历

3、如果已排序元素大于新元素,将已排序元素移动到下一个位置;

4、继续向前遍历,重复上一步骤直到找到已排序的元素小于或等于新元素,将新元素插入已排序元素的后面;

5、重复2-4步骤。

为了便于大家理解,我画了张图


代码实现

public class InsertionSort {
public void sort(int[] arr) { int len = arr.length; if(len <= 1) { return; }
for(int i = 1; i < len; i++) { // 未排序区间 int item = arr[i]; // 待排序元素
int j = i-1; for(;j >= 0; j--) { // 已排序区间 if(arr[j] <= item) { break; } else { arr[j+1] = arr[j]; // 已排序区间元素后移 } }
// 待排序元素的位置 arr[j+1] = item; } }
}

总结

1、插入排序的时间复杂度是多少?

如果要排序的数据已经是有序的,如果我们是在已排序区间倒序遍历查找,每次只需要比较一个数据就能确定插入的位置。所以在这种情况下,最好的时间复杂度为O(n)(注意,这里是倒序遍历)。

如果要排序的数据刚好是相反的,每次插入都相当于在数组的第一个位置插入新的数据,需要移动大量的数据,以最坏的时间复杂度为O(n^2)。

2、插入排序的空间复杂度是多少?

从上述实现过程可以看出,插入排序没有额外的存储空间,所以它的空间复杂度为O(1)。这是一个原地排序算法。

3、插入排序是稳定的排序算法吗?

在插入排序中,对于值相同的元素,我们可以将新元素插入到已排序区间元素的后面,这样就可以保持原有的顺序不变,所以插入排序是稳定的排序算法。

END

以上是关于详解插入排序的主要内容,如果未能解决你的问题,请参考以下文章

插入排序算法详解及代码实现

C# 插入排序详解

8种面试经典!排序详解--选择,插入,希尔,冒泡,堆排,3种快排,快排非递归,归并,归并非递归,计数(图+C语言代码+时间复杂度)

8种面试经典排序详解--选择,插入,希尔,冒泡,堆排,3种快排及非递归,归并及非递归,计数(图+C语言代码+时间复杂度)

8种面试经典排序详解--选择,插入,希尔,冒泡,堆排,3种快排及非递归,归并及非递归,计数(图+C语言代码+时间复杂度)

排序02-直接插入排序法