极简算法_选择排序
Posted 野区杰西
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了极简算法_选择排序相关的知识,希望对你有一定的参考价值。
简介
选择排序的基本思想是:每一趟在待排序的记录中选出关键字最小的记录,依次存放在已排好序的记录序列的最后,直到全部记录排好序为止。
选择排序本篇文章讲两种:直接选择排序
和 堆排序
。
直接选择排序
直接选择排序
的基本思想是,每次从待排序的无序区中选出关键字值最小记录,将该记录与该区中的第一个记录交换位置。初始时,target[1..n]
为无序区,有序区为空。第一趟排序后是在无序区的 target[1..n]
中选出最小的记录,将它与 target[1]
交换,target[1]
为有序区;第二趟排序后是在无序区的 target[2..n]
中选出最小的记录,将它与 target[2]
交换,target[1..2]
为有序区。以此类推,做了 n-1
趟选择后,区间 target[1..n]
中记录按递增有序。
实现
void selectSort (int[] target, int n) {
int i,j,k;
for (i=1;i<n;i++) { //做 n-1 趟排序
k=i; //设 k 为第 i 趟排序中记录关键字最小的记录位置
for (j=i+1;j<=n;j++) { //在 [i..n] 选择关键字最小的记录
if (target[j] < target[k]) {
k = j; //若有比 target[k] 小的记录,记住该位置
}
}
if (k!=i) { //与第 i 个记录交换
target[0] = target[i];
target[i] = target[k];
target[k] = target[0];
}
}
}
堆排序
堆排序
的基本思想是,在排序过程中,将记录数组 R[1..n]
看成是一颗完全二叉树的顺序存储结构,利用完全二叉树中双亲结点和孩子结点之间的内在关系,在当前无序区中选择关键字最大(或最小)记录。
堆排序正是利用大根堆(或小根堆)来选取当前无序区中关键字最大(或最小)的记录实现排序。每一趟排序的操作是,将当前无序区调整为一个大根堆,根据关键字最大的堆顶记录,将它和无序区中最后一个记录交换,这正好与选择排序相反。堆排序就是一个不断建堆的过程。
实现
/**
* 建造堆
* @param target 目标排序数组
* @param i
* @param h
*/
void siftSort(int[] target, int i, int h) {
int j;
//作为对比点,将待筛结点暂存于 x 中
int x = target[i];
//获取左节点
j = 2*i;
//若 target[i] 的左孩子不为空的时候执行循环
while (j <= h) {
//如果右孩子的关键字较大, j 为较大右孩子的下标
if (j < h && target[j] < target[j+1]) {
j++;
}
//找到了 x 的最终位置上,终止循环
if (x >= j) {
break;
}
// 将 target[j] 调整到双亲的位置上
target[i] = target[j];
i = j; // 修改 i 和 j 的值
j = 2*i; // 使 i 指向新的调整点
}
// 将被筛结点放入最终的位置上
target[i] = x;
}
然后我们可以通过调用 siftSort
方法
/**
* 堆排序
* @param target 目标数组
* @param n
*/
void heapSort(int[] target, int n) {
int i;
for (i=n/2;i>0;i--) {
siftSort(target, i, n); // 对初始数组 target[1..n] 建大根堆
}
for (i=n;i>1;i--) { //堆 target[1..n]进行堆排序,共 n-1 趟
target[0] = target[1];
target[1] = target[i];
target[i] = target[0];
siftSort(target, 1, i-1);
}
}
完!
以上是关于极简算法_选择排序的主要内容,如果未能解决你的问题,请参考以下文章