上一篇详述了冒泡排序及其优化,有兴趣的能够看看:html
如何优化冒泡排序?java
如图所示,每一趟找到未排序的最小值,并放到有序序列的后面(即当前趟对应于数组中的第几个元素)。算法
private static <T extends Comparable<? super T>> void selectionSort(T[] nums) {
if (null == nums || nums.length == 0) {
throw new RuntimeException("数组为null或长度为0");
}
int length = nums.length;
int minValueIndex = 0;
T temp = null;
for (int i = 0; i < length - 1; i++) {
minValueIndex = i;
for (int j = i + 1; j < length; j++) {
if (nums[j].compareTo(nums[minValueIndex]) < 0) {
minValueIndex = j;
}
}
if (minValueIndex != i) {
temp = nums[i];
nums[i] = nums[minValueIndex];
nums[minValueIndex] = temp;
}
}
}
算法思想:经过构建有序序列,对于未排序数据,在已排序序列中从后向前扫描,找到相应位置并插入。插入排序于是在从后向前扫描过程当中,须要反复把已排序元素逐步向后挪位,为最新元素提供插入空间。数组
排序过程:(默认升序)app
InsertionSort 和打扑克牌时,从牌桌上逐一拿起扑克牌,在手上排序的进程相同。优化
举例:spa
Input: {4, 3, 8, 5, 2, 6, 1, 7}。code
首先拿起第一张牌, 手上有 {4}。orm
拿起第二张牌 3, 把 3insert 到手上的牌 {4}, 获得 {3 ,4}。htm
拿起第三张牌 8, 把 8 insert 到手上的牌 {3,4 }, 获得 {3 ,4,8}。
以此类推。
插入排序由N-1趟排序组成。对于p=1到N-1趟排序后,插入排序保证从位置0到位置p上的元素为已排序状态。即插入排序利用了从位置0到p-1位置上已经有序的条件,将位置p上的元素向前查找适当的位置插入此元素。
如图所示:在第p趟,咱们将位置p上的元素向左移动,直到它在前p+1个元素(包括当前位置的元素)中的正确位置被找到。
java实现插入排序
private static <T extends Comparable<? super T>> void insertSort(T[] nums) {
if (null == nums || nums.length == 0) {
throw new RuntimeException("数组为null或长度为0");
}
int length = nums.length;
T temp = null;
int i = 0;
for (int p = 1; p < length; p++) {
temp = nums[p];
for (i = p; i > 0 && (temp.compareTo(nums[i - 1]) < 0); i--) {
nums[i] = nums[i - 1];
}
nums[i] = temp;
}
}
时间、空间复杂度及稳定性分析:
选择排序的主要优势与数据移动有关。若是某个元素位于正确的最终位置上,则它不会被移动。选择排序每次交换一对元素,它们当中至少有一个将被移到其最终位置上,所以对n个元素的表进行排序总共进行n-1次交换。在全部的彻底依靠交换去移动元素的排序方法中,选择排序属于很是好的一种。选择排序最好、最坏时间复杂度都为O(n^2),空间复杂度为O(1),属于不稳定排序。
插入排序不适合对于数据量比较大的排序应用。可是,若是须要排序的数据量很小,例如,量级小于千;或者若已知输入元素大体上按照顺序排列,那么插入排序仍是一个不错的选择。插入排序最好时间复杂度为O(n)、最坏时间复杂度为O(n^2),空间复杂度为O(1),属于稳定排序。