浅谈冒泡排序
浅谈插入排序
前两篇文章中已经介绍过冒泡排序和插入排序,它们的时间复杂度都为O(n²),今天这篇文章将会介绍另一种时间复杂度为O(n²)的排序算法–选择排序。这种算法的实现思路与插入排序类似,也分已排序区间和未排序区间。但是选择排序每次会从未排序区间中找到最小的元素,将其放到已排序区间的末尾。选择排序的原理如下图所示:
对应的代码如下:
public static void selectionSort(int[] a, int n) {
if (n <= 1) return;
for (int i = 0; i < n - 1; ++i) {
// 查找最小值
int minIndex = i;
for (int j = i + 1; j < n; ++j) {
if (a[j] < a[minIndex]) {
minIndex = j;
}
}
// 交换
int tmp = a[i];
a[i] = a[minIndex];
a[minIndex] = tmp;
}
}
1.选择排序是原地排序算法吗?
从代码中我们可以看出,选择排序仅仅使用了常量级的额外空间用于两个元素之间的交换,所以选择排序是原地排序算法。
2.选择排序是稳定的排序算法吗?
选择排序不是稳定的排序算法,选择排序不像插入排序,会先挪动插入位置之后的元素,而是直接交换,从而破坏了算法的稳定性。举个例子,有这样一组数组,元素分别为 4、7、4、1、5。运动选择排序算法第一次找到的最小元素为1,与第一个4发生交换,这样交换之后连个 4的先后顺序就发生了变化,所以选择排序不是稳定的排序算法。
3.选择排序的时间复杂度是多少?
从代码中我们可以看出,无论最初的乱序数组是否有序,每次选择排序都会遍历整个数组,从而每次选择的时间复杂度为O(n),但是数组中有n个元素,所以选择排序的时间复杂度为O(n²)。