在要排序的一组数中,假设前面(n-1)[n>=2] 个数已经是排好顺序的,现在要把第n个数找到相应位置并插入,使得这n个数也是排好顺序的。如此反复循环,直到全部排好顺序。 在第一趟排序中,插入排序最多比较一次,第二趟最多比较两次,依次类推,最后一趟最多比较N-1次。因此有: 1+2+3+...+N-1 =NN(N-1)/2 因为在每趟排序发现插入点之前,平均来说,只有全体数据项的一半进行比较,我们除以2得到: NN(N-1)/4 复制的次数大致等于比较的次数,然而,一次复制与一次比较的时间消耗不同,所以相对于随机数据,这个算法比冒泡排序快一倍,比选择排序略快。 与冒泡排序、选择排序一样,插入排序的时间复杂度仍然为O(n^2),这三者被称为简单排序或者基本排序,三者都是稳定的排序算法。 如果待排序数组基本有序时,插入排序的效率会更高。
插入排序的代码实现虽然没有冒泡排序和选择排序那么简单粗暴,但它的原理应该是最容易理解的了,因为只要打过扑克牌的人都应该能够秒懂。插入排序是一种最简单直观的排序算法,它的工作原理是通过构建有序序列,对于未排序数据,在已排序序列中从后向前扫描,找到相应位置并插入。 ☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆
public static void insertSort(int[] array) {
int length = array.length;
// 双重循环的代码一定要清楚每一层做什么。
// 确定第i+1个数应该放到哪个位置。
for (int i = 0; i < length - 1; i++) {
// 首先拿到等待排序的元素,因为前i个元素已经是有序的了。
int pendingSortElement = array[i + 1];
// 然后拿到有序数组的最后一个元素的index。
int preIndex = i;
// 我们用这个等待排序的元素不停地从后往前找,找到第一个比他小的元素(也就是ta第一个大于或等于的元素),他就应该放在这个元素后边
while (preIndex >= 0 && pendingSortElement < array[preIndex]) {
// 说明该元素肯定在列表中间的某个位置。因此我们需要将数组的数据进行移动。
array[preIndex + 1] = array[preIndex];
// 然后继续往前找,找到第一个比他小的元素。
preIndex--;
}
// 这个就是带排序的元素的正确位置了。
array[preIndex + 1] = pendingSortElement;
}
}