选择排序
在讲解选择排序算法前,我们先来讨论和实现下冒泡排序的第二种写法。
冒泡排序的第二种写法
我们在冒泡排序算法中讲到,冒泡排序的核心思想为:循环N轮,每轮在剩余数组中交换一个最大值到数组的末端,其代码如下:
public static void bubbleSort(int[] array) {
for (int i = 0; i < array.length - 1; i++) {
for (int j = 0; j < array.length - 1 - i; j++) {
if (array[j] > array[j + 1]) {
CommonUtils.swap(array, j, j + 1);
}
}
}
}
现在我们思考下,每轮在剩余数组中交换一个最大值到数组的首端,我们该怎么实现呢?我们从三个元素数组交换最大值到数组首端开始说起
三个元素数组交换最大值到数组首端
假如有一个数组,它包含三个元素,把数组元素最大值放到数组首端的算法步骤如下:
- 比较数组第一个元素和第二个元素的值
- 如果第一个元素小于第二个元素,则交换他们的位置
- 比较第一个元素和第三个元素的值
- 如果第一个元素小于第三个元素,则交换他们的位置
这里的算法的核心就是最大值的位置不随着算法步骤而变化,不管多少次比较交换,最大值永远处于数组的首端(假设数组元素为[1,3,5], 当执行算法步骤三时,其数组元素为[3,1,5]), 代码如下:
public static void swapMaxValueToArrayStart(int[] array) {
assert array != null && array.length == 3;
if (array[0] < array[1]) {
int temp = array[0];
array[0] = array[1];
array[1] = temp;
}
if (array[0] < array[2]) {
int temp = array[0];
array[0] = array[2];
array[2] = temp;
}
}
有了上诉算法的基础,就可以很轻松的写出第二种冒泡排序的代码:
public static void bubbleSort1(int[] array) {
// 每轮依次交换两个元素,直到最大的元素处于首端
for (int i = 0; i < array.length - 1; i++) {
for (int j = i + 1; j < array.length; j++) {
if (array[i] < array[j]) {
CommonUtils.swap(array, i, j);
}
}
}
}
外循环标记已经排序数组的位置,内循环每次从剩余的数组元素中比较交换最大元素到已经排序的数组末端。
优化冒泡排序的第二种写法
上诉冒泡排序算法每轮都需要比较和交换数组元素,为了提高算法效率,我们能不能减少交换的次数呢?因为我们每轮只需要把一个最大值交换到数组的首端,那么我们就没有必要每次都交换元素,每次比较的时候只需要记录最大值的下标,在比较最后一个元素的时候判断这个下标再进行交换元素即可,根据这个思路,我们就可以得到选择排序算法的代码:
private static void selectSort(int[] array) {
// 每轮在未排序的数组中选择一个最小值或者最大值放入到已排序元素的末尾
assert array != null;
int len = array.length;
int minIndex;
for (int i = 0; i < len; i++) {
minIndex = i;
// 未排序元素中寻找小于已排序元素的最大值
for (int j = i + 1; j < len; j++) {
if (array[j] < array[minIndex]) {
minIndex = j;
}
}
// 存在更小的元素,交换
if (minIndex != i) {
CommonUtils.swap(array, minIndex, i);
}
}
}
算法定义
选择排序(Selection sort)是一种简单直观的排序算法。它的工作原理如下。首先在未排序序列中找到最小(大)元素,存放到排序序列的起始位置,然后,再从剩余未排序元素中继续寻找最小(大)元素,然后放到已排序序列的末尾。以此类推,直到所有元素均排序完毕。
算法步骤
选择排序算法的算法步骤如下:
- 在未排序序列中找到最小(大)元素,存放到排序序列的起始位置。
- 从剩余未排序元素中继续寻找最小(大)元素,然后放到已排序序列的末尾。
- 重复以上步骤,直到所有元素均排序完毕。
总结
排序算法概况下就是:循环N轮,每轮在未排序的数组中选择一个最小值或者最大值放入到已排序元素的末尾。