选择排序的核心思想是每一趟从待排序列中选取一个关键字值最小的记录,将其放到已排序序列的末尾。第 1 趟从 n 个记录中选取最小值,第 2 趟从剩下的 n-1 个记录中选取次小值,直到整个序列有序。
直接选择排序
核心思路
首先在所有记录中选出关键字值最小的记录,把它与第一个记录进行位置交换;然后在其余的记录中再选出关键字值次小的记录与第二个记录进行位置交换,依此类推,直到所有记录排好序。
直观来看,这个过程就像是从一堆牌里不断挑出最小的那张放到最前面。虽然逻辑简单,但它的比较次数固定,不受数据初始状态影响。
示例演示
假设待排序的 8 个记录的关键字序列为 {5, 3, 6, 4, 7, 1, 8, 2}。初始序列视为无序,第一趟从无序区选最小值 1 与首位 5 交换,构成有序区 [1]。后续每趟遍历完无序区后,有序区长度 +1,无序区长度 -1。

关键实现
public void selectSort() {
RecordNode temp;
for (int i = 0; i < this.curlen - 1; i++) {
int min = i;
for (int j = i + 1; j < this.curlen; j++) {
if (r[j].key.compareTo(r[min].key) < 0) {
min = j;
}
}
if (min != i) {
temp = r[i];
r[i] = r[min];
r[min] = temp;
}
}
}
注意这里通过临时变量完成值交换,避免覆盖数据。虽然代码简洁,但每次都要遍历剩余元素,效率有限。
复杂度评估

树形选择排序
核心思路
为了减少比较次数,树形选择排序引入了锦标赛的思想。先对 n 个记录进行两两比较,将较小者作为优胜者上升到父结点,得到比较的优胜者(关键字值较小者)。重复此过程,直到选出一个关键字值最小的记录为止。这可以用一棵含有 n 个叶子结点的完全二叉树来表示。










