「Java」- 八大排序

本文详细介绍了Java中常见的八种排序算法:冒泡排序、选择排序、插入排序、希尔排序、堆排序、快速排序、归并排序和计数排序。通过对每种排序算法的原理、代码实现和时间复杂度分析,帮助读者理解各种排序方法的特点和应用场景。
摘要由CSDN通过智能技术生成

目录

前言

1.冒泡排序

2.选择排序

3.插入排序

4.希尔排序

5.堆排序

6.快速排序

7.归并排序

8.计数排序


前言

由于本章介绍的大多数排序都需要用到数组两个元素之间进行交换操作 , 所以作者在这里先写好一个通用的交换方法,后续在文中遇到的交换方法都是此方法

// 交换数组中的两个值
public void swap(int[] elem, int i, int j) {
    int tmp = elem[i];
    elem[i] = elem[j];
    elem[j] = tmp;
}	

冒泡排序

原理:在无序区间,通过相邻数的比较,将最大的数冒泡到无序区间的最后,持续这个过程,直到数组整体有序

 冒泡排序动画演示 

每次两个相邻之间的元素进行比较 , 我们将当前比较元素下标 定义成 j , 如果 j 位置的元素大于 j+1 位置的元素则进行交换 , 当比较完最后一个元素时 , 此时 一次冒泡排序就完成了,而每一次的冒泡排序完成那么最后一个元素都是有序的, 所以我们可以通过控制 排序区间比较次数 来进行编写冒泡排序算法 , 首先可以看到假设数组长度为 n, 每次排序都可以使最后一位元素变得有序 , 而 n 个元素需要进行 n-1 趟排序才能使整个数组变得有序, 所以我们可以定义个 i 变量 控制每一趟排序 , 而每次排序都涉及到比较 , 如果上一次排序完后最后一个元素已经有序了,那么还需要比较嘛?显然是不需要的 , 而记录趟数的变量 i 刚好可以作为比较次数的边界, i 为 1 时比较次数为 n-1 , i 为 2 时 比较次数为 n-2 , 所以每一趟排序只需要比较 n-i 次即可

 代码实现

public void bubbleSort(int[] elem) {
    // 控制排序趟数
    for (int i = 1; i < elem.length; i++) {
        // 控制比较次数
        for (int j = 0; j < elem.length - i; j++) {
            if (elem[j] > elem[j + 1]) {
                swap(elem, j, j + 1);// 调用上面写的交换方法
            }
        }
    }
}

 冒泡排序优化

可以在这考虑一个问题 , 假设给定的数组就是有序的 , 或者给定数组是以下这种情况

如上面这种情况 , 只需要一次排序即可将数组变有序 , 但是上面的代码即使不会进行交换 , 还是会进行 n-1 次的排序 , 如果这个数组是一个很长的数组 , 那么也就会浪费一定的时间去执行不必要的代码 , 所以我们加个 boolean 变量 flag 作为标志 ,初始值为 false , 如果在排序中发生交换 那么将 flag 改成 true , 如果一次排序下来 , flag 仍然是 false 那就说明当前数组已经有序了.

public void bubbleSort(int[] elem) {
        for (int i = 1; i < elem.length; i++) {
            boolean flag = false;// 每趟排序都需要将 flag 设置为 false
            for (int j = 0; j < elem.length - i; j++) {
                if (elem[j] > elem[j + 1]) {
                    swap(elem, j, j + 1);// 调用上面写的交换方法
                    flag = true;// 发生交换 flag 更新为 true
                }
            }
            if (!flag) { // 如果 flag 还是为 false 则代表没发生交换,也就代表当前元素是有序的
                break;
            }
        }
}

时间复杂度: O(n^2)

空间复杂度:O(1)

稳定性: 稳定


选择排序

原理:每一次从无序区间选出最大(或最小)的一个元素,存放在无序区间的最后(或最前),直到全部待排序的数据元素排完

选择排序动画演示 

每趟排序选择无序列表的最前面的元素下标,定义为 i , 将 i 下标后面的下标定义为 j 每次拿出数组 i 下标的元素与数组 j 下标的元素进行比较 , 如果 i 下标的元素大于 j 下标则进行交换 , 一次排序之后第 i 个元素就成了有序的了 , 我们通过控制 i 变量,来进行对每一趟的首位元素定位 ,控制 j 变量来进行每一次与 i 下标元素 , 进行比较 , 而 j 变量的起始位置可以是 i+1 ,

代码实现

public void selectSort(int[] elem) {
    for (int i = 0; i < elem.length; i++) {
        for (int j = i + 1; j < elem.length; j++) {
            if (elem[i] > elem[j]) {
                swap(elem, i, j);// 调用上面写的交换方法
            }
        }
    }
}

优化

原理:首先在未排序序列中找到最小元素,存放到排序序列的起始位置,然后再从剩余未排序元素中继续寻找最小元素,然后放到已排序序列的末尾。

双向选择排序 , 一次可以将两个元素变为有序的 , 定义一个 min 变量记录最小元素的下标 , 然后定义一个 max 变量记录最大元素的下标 , 循环结束后将 min 下标处的变量和 待排序区间 首个元素进行交换 , 将 max 下标处的变量和 待排序区间 的最后一个元素进行交换

 代码实现

public void dbSelectSort(int[] elem) {
    int left = 0;//左区间
    int right = elem.length - 1;//右区间
    while (left < right) {
        int min = left;//记录最小值的下标
        int max = left;//记录最大值的下标
        for (int i = left; i <= right; i++) {
            if (elem[i] < elem[min]) {
                min = i;//更新最小值下标
            }
            if (elem[i] > elem[max]) {
                max = i;//更新最大值下标
            }
        }
        //交换最小值
        swap(e
  • 46
    点赞
  • 40
    收藏
    觉得还不错? 一键收藏
  • 28
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 28
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值