博客
关于我
数据结构:常见排序算法(2) -- 选择排序(选择排序、堆排序)
阅读量:556 次
发布时间:2019-03-09

本文共 2816 字,大约阅读时间需要 9 分钟。

选择排序和堆排序是两种经典的排序算法,在不同的场景下各有优劣。以下从原理、代码实现及性能分析等方面详细阐述。

选择排序

原理

选择排序是一种简单有效的排序算法。其工作原理是:每次从当前数组中找出最小或最大元素,将其移动到已排序区间的最末端或最前端。这个过程重复进行,直至整个数组排序完成。

具体而言:

  • 将数组分为已排序区间和无序区间。
  • 在每次循环中,选择当前无序区间中的最大或最小值。
  • 将选择的值移动到已排序区间的末尾或开头。
  • 重复上述步骤,直到无序区间为空。
  • 这种方法的最优性在于其逻辑简单,时间复杂度为O(n²),适合针对数据规模较小时使用。

    代码实现

    以下是基于Java的选择排序代码示例:

    import java.util.Arrays;public class SelectSort {    public static void main(String[] args) {        int[] array = {5, 1, 25, 4, 8, 11, 5, 7, 5, 0};        System.out.println(Arrays.toString(array));        selectSort(array);        System.out.println(Arrays.toString(array));    }    public static void selectSort(int[] array) {        int left = 0, right = array.length - 1;        while (left < right) {            int maxPos = left;            for (int i = left + 1; i <= right; i++) {                if (array[i] > array[maxPos]) {                    maxPos = i;                }            }            int max = array[maxPos];            array[maxPos] = array[left];            array[left] = max;            left++;        }    }}

    性能分析

    • 时间复杂度:O(n²),排序时间与数组长度的平方成正比。
    • 空间复杂度:O(1),算法仅使用常数额外空间。
    • 稳定性:不稳定,较大值多次被交换可能破坏相对顺序。

    堆排序

    原理

    堆排序与选择排序类似,但采用了不同的策略:通过构建堆(最大堆或最小堆)来快速找到无序区间的最大或最小值。关键步骤包括:

  • 将数组构建为大根堆或小根堆。
  • 从堆顶取出最大的元素,并放在已排序区间。
  • 调整堆结构,重新插入元素并恢复堆属性。
  • 重复上述步骤,直到无序区间为空。
  • 这与选择排序相比,减少了逐次查找最大值的时间复杂度,从O(n) 降低至 O(log n),但增加了堆操作的复杂性。

    代码实现

    以下是基于Java的堆排序代码示例:

    import java.util.Arrays;public class HeapSort {    public static void main(String[] args) {        int[] array = {27, 15, 19, 18, 28, 34, 65, 49, 25, 37};        printArray(array);        heapSort(array);        printArray(array);    }    private void printArray(int[] array) {        System.out.println(Arrays.toString(array));    }    public void heapSort(int[] array) {        int size = array.length;        int[] heap = new int[size];        for (int i = 0; i < size; i++) {            heap[i] = array[i];        }        for (int i = size - 1; i > 0; i--) {            adjustHeap(i, size);        }        int end = size - 1;        while (end > 0) {            int temp = heap[0];            heap[0] = heap[end];            heap[end] = temp;            adjustHeap(0, end);            end--;        }    }    private void adjustHeap(int parent, int len) {        int child = 2 * parent + 1;        while (child < len) {            if (child < len - 1 && heap[child] > heap[child + 1]) {                child++;            }            if (heap[child] > heap[parent]) {                swapElements(child, parent);                parent = child;                child = 2 * parent + 1;            } else {                break;            }        }    }    private void swapElements(int i, int j) {        int temp = heap[i];        heap[i] = heap[j];        heap[j] = temp;    }}

    性能分析

    • 时间复杂度:O(n log n),排序时间与数组长度的对数成正比。
    • 空间复杂度:O(n),需要额外存储用于构建堆。
    • 稳定性:不稳定,较大值多次被交换可能破坏相对顺序。

    转载地址:http://bwkpz.baihongyu.com/

    你可能感兴趣的文章
    MySQL 存储过程参数:in、out、inout
    查看>>
    mysql 存储过程每隔一段时间执行一次
    查看>>
    mysql 存在update不存在insert
    查看>>
    Mysql 学习总结(86)—— Mysql 的 JSON 数据类型正确使用姿势
    查看>>
    Mysql 学习总结(87)—— Mysql 执行计划(Explain)再总结
    查看>>
    Mysql 学习总结(88)—— Mysql 官方为什么不推荐用雪花 id 和 uuid 做 MySQL 主键
    查看>>
    Mysql 学习总结(89)—— Mysql 库表容量统计
    查看>>
    mysql 实现主从复制/主从同步
    查看>>
    mysql 审核_审核MySQL数据库上的登录
    查看>>
    mysql 导入 sql 文件时 ERROR 1046 (3D000) no database selected 错误的解决
    查看>>
    mysql 导入导出大文件
    查看>>
    mysql 将null转代为0
    查看>>
    mysql 常用
    查看>>
    MySQL 常用列类型
    查看>>
    mysql 常用命令
    查看>>
    Mysql 常见ALTER TABLE操作
    查看>>
    mysql 往字段后面加字符串
    查看>>
    mysql 快速自增假数据, 新增假数据,mysql自增假数据
    查看>>
    Mysql 报错 Field 'id' doesn't have a default value
    查看>>
    MySQL 报错:Duplicate entry 'xxx' for key 'UNIQ_XXXX'
    查看>>