极简算法_选择排序

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);
        }
    }

完!


以上是关于极简算法_选择排序的主要内容,如果未能解决你的问题,请参考以下文章

算法_选择排序

算法_基本排序算法之冒泡排序,选择排序,插入排序和希尔排序

十大排序算法总结(Python3实现)

面试相关-七大排序算法:图解+动图+最直观的代码分析_性能比较

各种基本算法实现小结—— 排序算法

算法交换排序——快速排序+冒泡排序