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

news/2025/2/5 3:34:20/

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

比较总结

排序算法时间复杂度(最坏/平均/最好)空间复杂度稳定性总结
选择排序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),插入排序是原地排序算法,只需要常数级别的额外空间。

http://www.ppmy.cn/news/1569406.html

相关文章

【机器学习】自定义数据集 ,使用朴素贝叶斯对其进行分类

一、贝叶斯原理 贝叶斯算法是基于贝叶斯公式的&#xff0c;其公式为&#xff1a; 其中叫做先验概率&#xff0c;叫做条件概率&#xff0c;叫做观察概率&#xff0c;叫做后验概率&#xff0c;也是我们求解的结果&#xff0c;通过比较后验概率的大小&#xff0c;将后验概率最大的…

css三角图标

案例三角&#xff1a; <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>Document</title><s…

告别页面刷新!如何使用AJAX和FormData优化Web表单提交

系列文章目录 01-从零开始学 HTML&#xff1a;构建网页的基本框架与技巧 02-HTML常见文本标签解析&#xff1a;从基础到进阶的全面指南 03-HTML从入门到精通&#xff1a;链接与图像标签全解析 04-HTML 列表标签全解析&#xff1a;无序与有序列表的深度应用 05-HTML表格标签全面…

c++ string类 +底层模拟实现

提醒: 本片博客只是小编的听课笔记&#xff0c;介意勿看。 基础 包含在头文件<string>&#xff0c;才能使用string类似函数接口。 string常见构造类 string s1; cin>>s1;//无参构造 string s2(s1);//拷贝构造 string s1("jfksa");//传参构造 三种…

IM 即时通讯系统-50-[特殊字符]cim(cross IM) 适用于开发者的分布式即时通讯系统

IM 开源系列 IM 即时通讯系统-41-开源 野火IM 专注于即时通讯实时音视频技术&#xff0c;提供优质可控的IMRTC能力 IM 即时通讯系统-42-基于netty实现的IM服务端,提供客户端jar包,可集成自己的登录系统 IM 即时通讯系统-43-简单的仿QQ聊天安卓APP IM 即时通讯系统-44-仿QQ即…

算法随笔_37: 交替合并字符串

上一篇:算法随笔_36: 复写零-CSDN博客 题目描述如下: 给你两个字符串 word1 和 word2 。请你从 word1 开始&#xff0c;通过交替添加字母来合并字符串。如果一个字符串比另一个字符串长&#xff0c;就将多出来的字母追加到合并后字符串的末尾。 返回 合并后的字符串 。 示例…

Flutter常用Widget小部件

小部件Widget是一个类&#xff0c;按照继承方式&#xff0c;分为无状态的StatelessWidget和有状态的StatefulWidget。 这里先创建一个简单的无状态的Text小部件。 Text文本Widget 文件&#xff1a;lib/app/app.dart。 import package:flutter/material.dart;class App exte…

Spring 面试题【每日20道】【其二】

1、Spring MVC 具体的工作原理&#xff1f; 中等 Spring MVC 是 Spring 框架的一部分&#xff0c;专门用于构建基于Java的Web应用程序。它采用模型-视图-控制器&#xff08;MVC&#xff09;架构模式&#xff0c;有助于分离应用程序的不同方面&#xff0c;如输入逻辑、业务逻辑…