三傻排序的比较(选择,冒泡,插入)

在学习排序算法时,选择排序、冒泡排序和插入排序是最常见的基础排序算法。但是,尽管这些算法看起来非常相似,它们在实际应用中的效率和性能却有所不同。本文将详细比较这三种排序算法的时间复杂度、空间复杂度。

比较总结

排序算法 时间复杂度(最坏/平均/最好) 空间复杂度 稳定性 总结
选择排序 O(n^2) / O(n^2) / O(n^2) O(1) 不稳定 选择排序就像每次去找最小的苹果,把它拿过来放到最前面。比较次数多,但并不保证相同值的苹果顺序不变。
冒泡排序 O(n^2) / O(n^2) / O(n) O(1) 稳定 冒泡排序就像水中泡泡,每次拿两个相邻的元素交换位置,把最大的"泡泡"挤到最后面。对已经排序的部分有点帮助。
插入排序 O(n^2) / O(n^2) / O(n) O(1) 稳定 插入排序像扑克牌,每次从剩下的牌中选一张,插入到已经排好序的部分。只要原本部分已经排得差不多,插入排序就很快。
解释:
  • 选择排序 :就像在一堆乱七八糟的苹果里,每次都找最小的一个放到最前面,直到找完所有苹果。这样做效率低,因为每次都要扫描整个数组。并且,交换位置时会改变相同数值元素的顺序,所以它是不稳定的。

  • 冒泡排序 :它的工作方式像水中的气泡,每次把最小(或者最大)的一泡气泡"冒泡"到水面。这样做最差的情况就像是给每个气泡都挤出来一次,效率比较差。不过,如果数据本来就已经有点有序了,冒泡排序会比选择排序好,因为它可以提前结束。冒泡排序是稳定的,也就是说,相同的数值会保持原来的顺序。

  • 插入排序 :插入排序就像你在玩扑克牌,已经排好的一部分牌,就像一个顺序的队列,后面的牌从后面插进这个顺序队列。如果已经排得差不多了,那么插入排序就能非常快速地完成任务,效率提升很多。它也是稳定的,意思是相同的数字不会改变顺序。

总结:
  • 选择排序 :非常简单,但因为每次都要比较整个数组,所以它的效率较差,尤其是大数据时。它是不稳定的,不适合用在需要保留相等元素顺序的场景。
  • 冒泡排序 :虽然每次"冒泡"都能把大的数挤到最后,但它效率也不高,尤其是需要进行多轮比较时。它是稳定的,如果数据部分有序,它比选择排序要好一些。
  • 插入排序 :适合数据已经有序或者部分有序的情况,可以非常高效。它也是稳定的,是一个非常实用的排序算法,尤其是数据量不大时。

分别分析:

1. 选择排序(Selection Sort)

选择排序是一种简单的排序算法,它的基本思想是:

  • 每次从待排序的数组中选择最小的元素,然后将其与未排序部分的第一个元素交换。
  • 重复这个过程,直到所有元素都被排序。
选择排序的工作原理:
  1. 找到数组中最小的元素。
  2. 将其与数组的第一个元素交换。
  3. 然后对剩下的元素继续执行相同操作,直到整个数组有序。

选择排序的Java代码实现:

java 复制代码
public class SelectionSort {
    public static void selectionSort(int[] arr) {
        int n = arr.length;
        
        // 遍历数组
        for (int i = 0; i < n - 1; i++) {
            // 假设当前元素是最小的
            int minIndex = i;
            
            // 查找剩余部分的最小元素
            for (int j = i + 1; j < n; j++) {
                if (arr[j] < arr[minIndex]) {
                    minIndex = j;
                }
            }
            
            // 交换最小元素与当前位置的元素
            int temp = arr[i];
            arr[i] = arr[minIndex];
            arr[minIndex] = temp;
        }
    }

    public static void printArray(int[] arr) {
        for (int num : arr) {
            System.out.print(num + " ");
        }
        System.out.println();
    }

    public static void main(String[] args) {
        int[] arr = {64, 25, 12, 22, 11};
        System.out.println("Original Array:");
        printArray(arr);

        selectionSort(arr);

        System.out.println("Sorted Array:");
        printArray(arr);
    }
}
选择排序的时间和空间复杂度:
  • 时间复杂度:O(n^2),在每次选择最小值时需要遍历剩余部分,因此时间复杂度为 O(n^2)。
  • 空间复杂度:O(1),选择排序是原地排序算法,仅使用常数级别的额外空间。

2. 冒泡排序(Bubble Sort)

冒泡排序的基本思想是:

  • 通过多次比较相邻的元素,若顺序错误则交换它们。
  • 每一轮遍历将当前未排序部分中的最大元素"冒泡"到数组的末尾。
  • 重复这个过程,直到整个数组有序。
冒泡排序的工作原理:
  1. 从数组的第一个元素开始,比较相邻的两个元素,如果顺序错误就交换它们。
  2. 每一轮遍历后,最大的元素被交换到末尾。
  3. 重复遍历,直到所有元素都已排序。

冒泡排序的Java代码实现:

java 复制代码
public class BubbleSort {
    public static void bubbleSort(int[] arr) {
        int n = arr.length;
        
        // 外层循环,控制比较的轮数
        for (int i = 0; i < n - 1; i++) {
            // 内层循环,进行相邻元素的比较和交换
            for (int j = 0; j < n - 1 - i; j++) {
                if (arr[j] > arr[j + 1]) {
                    // 交换相邻元素
                    int temp = arr[j];
                    arr[j] = arr[j + 1];
                    arr[j + 1] = temp;
                }
            }
        }
    }

    public static void printArray(int[] arr) {
        for (int num : arr) {
            System.out.print(num + " ");
        }
        System.out.println();
    }

    public static void main(String[] args) {
        int[] arr = {64, 25, 12, 22, 11};
        System.out.println("Original Array:");
        printArray(arr);

        bubbleSort(arr);

        System.out.println("Sorted Array:");
        printArray(arr);
    }
}
冒泡排序的时间和空间复杂度:
  • 时间复杂度:O(n^2),在最坏和最常见的情况下,需要两层嵌套循环,因此时间复杂度是 O(n^2)。
  • 空间复杂度:O(1),冒泡排序是原地排序算法,不需要额外的存储空间。

3. 插入排序(Insertion Sort)

插入排序的基本思想是:

  • 从第二个元素开始,将每个元素插入到已经排好序的部分中。
  • 每次插入时,先与已经排序的元素进行比较,找到合适的位置插入。
插入排序的工作原理:
  1. 从数组的第二个元素开始,将其插入到前面已排序部分的合适位置。
  2. 每次插入时,从右向左移动元素,直到找到合适的位置。
  3. 重复这一过程,直到整个数组有序。
插入排序的Java代码实现:
java 复制代码
public class InsertionSort {
    public static void insertionSort(int[] arr) {
        int n = arr.length;
        
        // 从第二个元素开始插入
        for (int i = 1; i < n; i++) {
            int key = arr[i];
            int j = i - 1;
            
            // 移动比key大的元素
            while (j >= 0 && arr[j] > key) {
                arr[j + 1] = arr[j];
                j = j - 1;
            }
            
            // 插入key元素
            arr[j + 1] = key;
        }
    }

    public static void printArray(int[] arr) {
        for (int num : arr) {
            System.out.print(num + " ");
        }
        System.out.println();
    }

    public static void main(String[] args) {
        int[] arr = {64, 25, 12, 22, 11};
        System.out.println("Original Array:");
        printArray(arr);

        insertionSort(arr);

        System.out.println("Sorted Array:");
        printArray(arr);
    }
}
插入排序的时间和空间复杂度:
  • 时间复杂度:O(n^2),在最坏情况下(当数组是倒序时),需要两层循环,因此时间复杂度为 O(n^2)。但在部分有序的数组中,插入排序的表现比选择排序和冒泡排序更优。
  • 空间复杂度:O(1),插入排序是原地排序算法,只需要常数级别的额外空间。
相关推荐
weixin_404551241 分钟前
openrewrite Lossless Semantic Trees (LST)
java·tree·yaml·lossless·openrewrite·lst·semantic
一 乐5 分钟前
口腔健康系统|口腔医疗|基于java和小程序的口腔健康系统小程序设计与实现(源码+数据库+文档)
java·数据库·vue.js·小程序·毕设
进击的炸酱面8 分钟前
第三章 线性模型
人工智能·算法·机器学习
YDS8298 分钟前
苍穹外卖 —— 文件上传和菜品的CRUD
java·spring boot·后端
立志成为大牛的小牛9 分钟前
数据结构——三十一、最小生成树(王道408)
数据结构·学习·程序人生·考研·算法
xiguolangzi29 分钟前
mysql迁移PG库 主键、唯一处理、批量修改
java·后端
摇滚侠30 分钟前
Spring Boot3零基础教程,Actuator 导入,笔记82
java·spring boot·笔记
DolphinScheduler社区31 分钟前
小白指南:Apache DolphinScheduler 补数据功能实操演示
java·大数据·开源·apache·海豚调度·大数据工作流调度
TDengine (老段)32 分钟前
TDengine 数据函数 TAN 用户手册
java·大数据·数据库·物联网·时序数据库·tdengine·涛思数据
TDengine (老段)33 分钟前
TDengine 数学函数 SQRT 用户手册
java·大数据·数据库·物联网·时序数据库·tdengine·1024程序员节