掌握Java排序算法:实现主流排序方法与性能对比

一,C语言,主流的排序方法介绍

当谈论主流的排序方法时,通常指的是在实际应用中表现优秀且被广泛采用的排序算法。以下是常见的主流排序方法及其介绍、时间复杂度、空间复杂度和简单的C语言代码实现:

  1. 冒泡排序(Bubble Sort):
  • 介绍:冒泡排序是一种简单的交换排序算法。它重复地遍历要排序的列表,依次比较相邻的两个元素,如果顺序不对则交换它们,直到整个列表排好序为止。
  • 时间复杂度:平均情况和最坏情况下都是 O(n^2)。
  • 空间复杂度:O(1)。
  • 代码实现:
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 - i - 1; j++) {if (arr[j] > arr[j + 1]) {int temp = arr[j];arr[j] = arr[j + 1];arr[j + 1] = temp;}}}}public static void main(String[] args) {int[] arr = {64, 34, 25, 12, 22, 11, 90};bubbleSort(arr);System.out.print("冒泡排序结果:");for (int num : arr) {System.out.print(num + " ");}}
}rr[] = {64, 34, 25, 12, 22, 11, 90};int n = sizeof(arr) / sizeof(arr[0]);bubbleSort(arr, n);printf("冒泡排序结果:");for (int i = 0; i < n; i++) {printf("%d ", arr[i]);}return 0;
}
  1. 快速排序(Quick Sort):
  • 介绍:快速排序是一种高效的分治排序算法。它选择一个元素作为基准(通常选择第一个或最后一个元素),然后将列表分为比基准小和比基准大的两部分,再对这两部分进行递归排序。
  • 时间复杂度:平均情况下为 O(n log n),最坏情况下为 O(n^2)(当基准选取不合理时)。
  • 空间复杂度:平均情况下为 O(log n),最坏情况下为 O(n)(当递归树不平衡时)。
  • 代码实现:
public class QuickSort {public static void quickSort(int[] arr, int low, int high) {if (low < high) {int pi = partition(arr, low, high);quickSort(arr, low, pi - 1);quickSort(arr, pi + 1, high);}}public static int partition(int[] arr, int low, int high) {int pivot = arr[high];int i = low - 1;for (int j = low; j < high; j++) {if (arr[j] <= pivot) {i++;int temp = arr[i];arr[i] = arr[j];arr[j] = temp;}}int temp = arr[i + 1];arr[i + 1] = arr[high];arr[high] = temp;return i + 1;}public static void main(String[] args) {int[] arr = {64, 34, 25, 12, 22, 11, 90};int n = arr.length;quickSort(arr, 0, n - 1);System.out.print("快速排序结果:");for (int num : arr) {System.out.print(num + " ");}}
}
  1. 插入排序(Insertion Sort):
  • 介绍:插入排序是一种简单直观的排序算法。它通过构建有序序列,逐步将未排序元素插入到有序序列的正确位置中。
  • 时间复杂度:平均情况和最坏情况下都是 O(n^2)。
  • 空间复杂度:O(1)。
    代码实现:
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;while (j >= 0 && arr[j] > key) {arr[j + 1] = arr[j];j--;}arr[j + 1] = key;}}public static void main(String[] args) {int[] arr = {64, 34, 25, 12, 22, 11, 90};insertionSort(arr);System.out.print("插入排序结果:");for (int num : arr) {System.out.print(num + " ");}}
}
  1. 归并排序(Merge Sort):
  • 介绍:归并排序是一种高效的分治排序算法。它将列表不断地分成两半,递归地对每个子列表进行排序,然后将两个已排序的子列表合并成一个有序列表。
  • 时间复杂度:平均情况和最坏情况下都是 O(n log n)。
  • 空间复杂度:O(n)。
  • 代码实现:
public class MergeSort {public static void merge(int[] arr, int left, int middle, int right) {int n1 = middle - left + 1;int n2 = right - middle;int[] L = new int[n1];int[] R = new int[n2];for (int i = 0; i < n1; i++)L[i] = arr[left + i];for (int j = 0; j < n2; j++)R[j] = arr[middle + 1 + j];int i = 0, j = 0, k = left;while (i < n1 && j < n2) {if (L[i] <= R[j]) {arr[k] = L[i];i++;} else {arr[k] = R[j];j++;}k++;}while (i < n1) {arr[k] = L[i];i++;k++;}while (j < n2) {arr[k] = R[j];j++;k++;}}public static void mergeSort(int[] arr, int left, int right) {if (left < right) {int middle = left + (right - left) / 2;mergeSort(arr, left, middle);mergeSort(arr, middle + 1, right);merge(arr, left, middle, right);}}public static void main(String[] args) {int[] arr = {64, 34, 25, 12, 22, 11, 90};int n = arr.length;mergeSort(arr, 0, n - 1);System.out.print("归并排序结果:");for (int num : arr) {System.out.print(num + " ");}}
}
  1. 堆排序(Heap Sort):
  • 介绍:堆排序利用堆这种数据结构进行排序。它首先将列表构建为最大堆或最小堆,然后重复提取堆顶元素,并调整堆,直到整个列表排好序。
  • 时间复杂度:平均情况和最坏情况下都是 O(n log n)。
  • 空间复杂度:O(1)。
    -代码实现:
public class HeapSort {public static void heapify(int[] arr, int n, int i) {int largest = i;int left = 2 * i + 1;int right = 2 * i + 2;if (left < n && arr[left] > arr[largest])largest = left;if (right < n && arr[right] > arr[largest])largest = right;if (largest != i) {int temp = arr[i];arr[i] = arr[largest];arr[largest] = temp;heapify(arr, n, largest);}}public static void heapSort(int[] arr) {int n = arr.length;for (int i = n / 2 - 1; i >= 0; i--)heapify(arr, n, i);for (int i = n - 1; i > 0; i--) {int temp = arr[0];arr[0] = arr[i];arr[i] = temp;heapify(arr, i, 0);}}public static void main(String[] args) {int[] arr = {64, 34, 25, 12, 22, 11, 90};heapSort(arr);System.out.print("堆排序结果:");for (int num : arr) {System.out.print(num + " ");}}
}

二,总结

当我们对上面列出的主流排序算法进行总体分析时,可以从它们的优缺点和适用场景等方面来考虑

  1. 冒泡排序:

    • 优点:实现简单,代码易于理解和编写。
    • 缺点:在平均情况和最坏情况下,时间复杂度较高(O(n^2)),不适用于大规模数据排序。
    • 适用场景:适用于数据规模较小且数据基本有序的情况,或作为学习排序算法的入门例子。
  2. 快速排序:

    • 优点:平均情况下性能较好(O(n log n)),是主流排序算法中速度最快的一种。
    • 缺点:在最坏情况下(当基准选取不合理时),可能出现性能下降(O(n^2))。
    • 适用场景:适用于大多数情况下的排序需求,特别是数据规模较大的情况。
  3. 插入排序:

    • 优点:对于小规模数据或基本有序的数据排序效率较高。
    • 缺点:在数据规模较大时,性能下降(O(n^2))。
    • 适用场景:适用于数据规模较小、基本有序或已近排序的情况,也适用于较短数组的排序。
  4. 归并排序:

    • 优点:稳定的排序算法,不受输入数据的影响。在任何情况下都具有相对较好的性能(O(n log n))。
    • 缺点:需要额外的空间来存储临时数据,空间复杂度较高。
    • 适用场景:适用于任何规模的数据排序需求,尤其在对稳定性和性能要求较高的场景下。
  5. 堆排序:

    • 优点:性能稳定,对于大规模数据的排序效率较高。
    • 缺点:不稳定排序算法,不适用于需要保持原始顺序的情况。
    • 适用场景:适用于大规模数据的排序需求,尤其是需要高效率且不关心排序稳定性的情况。

根据上述分析,不同的排序算法适用于不同的情况。在实际应用中,可以根据以下几点考虑选择合适的排序算法:

  • 数据规模:对于小规模数据,可以考虑插入排序、冒泡排序等;对于大规模数据,可以优先考虑快速排序、归并排序或堆排序。
  • 数据状态:如果数据已经基本有序,插入排序和冒泡排序可能会更快;如果数据随机分布或无序,快速排序通常表现较好。
  • 稳定性要求:如果需要保持相等元素的相对顺序不变,应该选择稳定的排序算法,如归并排序。
  • 内存使用:如果内存空间有限,应该选择空间复杂度较低的排序算法,如堆排序。

综合考虑以上因素,选择合适的排序算法将有助于提高程序的性能和效率。在实际开发中,根据具体的应用场景和数据特点来选择排序算法,进行性能优化是非常重要的。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/24496.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

nginx使用

1 安装 yum -y install gcc pcre-devel zlib-devel openssl openssl-devel yum install -y wget wget https://nginx.org/download/nginx-1.16.1.tar.gz tar -zxvf nginx-1.16.1.tar.gz cd nginx-1.16.1 ./configure --prefix/usr/local/nginx make make install2 目录 目录说…

【雕爷学编程】Arduino动手做(184)---快餐盒盖,极低成本搭建机器人实验平台2

吃完快餐粥&#xff0c;除了粥的味道不错之外&#xff0c;我对个快餐盒的圆盖子产生了兴趣&#xff0c;能否做个极低成本的简易机器人呢&#xff1f;也许只需要二十元左右 知识点&#xff1a;轮子&#xff08;wheel&#xff09; 中国词语。是用不同材料制成的圆形滚动物体。简…

Mac端口扫描工具

端口扫描工具 Mac内置了一个网络工具 网络使用工具 按住 Command 空格 然后搜索 “网络实用工具” 或 “Network Utility” 即可 域名/ip转换Lookup ping功能 端口扫描 https://zhhll.icu/2022/Mac/端口扫描工具/ 本文由 mdnice 多平台发布

C++中的常量介绍

C中的常量介绍 在C中&#xff0c;常量是一个固定的值&#xff0c;它在程序执行期间不会发生改变。常量可以分为&#xff1a; 1.字面常量 2.符号常量&#xff1a;符号常量是通过标识符来表示的常量值&#xff0c;在程序中使用时要先进行定义。使用符号常量的好处是可以给常量起…

JUnit教程_编程入门自学教程_菜鸟教程-免费教程分享

教程简介 JUnit是一个Java语言的单元测试框架。它由Kent Beck和Erich Gamma建立&#xff0c;逐渐成为源于Kent Beck的sUnit的xUnit家族中最为成功的一个。 JUnit有它自己的JUnit扩展生态圈。多数Java的开发环境都已经集成了JUnit作为单元测试的工具。JUnit是由 Erich Gamma 和…

【具生智能】前沿思考与总结(DALL-E-Bot TinyBot)

1. DALL-E-Bot DALL-E-Bot: Introducing Web-Scale Diffusion Models to Robotics (robot-learning.uk) **&#xff08;2023-05-04&#xff09;**DALL-E-Bot: Introducing Web-Scale Diffusion Models to Robotics DALL-E-Bot&#xff1a;将网络规模的扩散模型引入机器人 第…

C语言----动态内存分配(malloc calloc relloc free)超全知识点

目录 一.动态内存函数 1.malloc 2.free 3.calloc 4.malloc和calloc的区别 5.realloc 二.动态内存分配的常见错误 1.对null进行解引用操作 2.对动态开辟空间的越界访问 3.对非动态开辟内存使用free释放 4.使用free释放动态开辟内存的一部分 5.对同一块动态内存多次…

物联网|按键实验---学习I/O的输入及中断的编程|读取I/O的输入信号|中断的编程方法|轮询实现按键捕获实验-学习笔记(13)

文章目录 实验目的了解擒键的工作原理及电原理图 STM32F407中如何读取I/O的输入信号STM32F407对中断的编程方法通过轮询实现按键捕获实验如何利用已有内工程创建新工程通过轮询实现按键捕获代码实现及分析1 代码的流程分析2 代码的实现 Tips:下载错误的解决 实验目的 了解擒键…

Leetcode-每日一题【剑指 Offer 09. 用两个栈实现队列】

题目 用两个栈实现一个队列。队列的声明如下&#xff0c;请实现它的两个函数 appendTail 和 deleteHead &#xff0c;分别完成在队列尾部插入整数和在队列头部删除整数的功能。(若队列中没有元素&#xff0c;deleteHead 操作返回 -1 ) 示例 1&#xff1a; 输入&#xff1a; [&…

如何快速做单元测试?

首先写unit test之前&#xff0c;要确认自己的测试遵循两个原则&#xff1a; 1、尽量不要干涉原来的代码。从阅读代码的体验来说&#xff0c;不要让你的测试&#xff08;哪怕是一小段if..else...的代码&#xff09;出现在你准备测试的代码中。 2、代码要只是测试某个class里面…

springboot第34集:ES 搜索,nginx

#用search after解决深分页性能问题 #第一页 GET /bank/_search {"size": 10,"sort": [{"account_number": {"order": "asc"}}] }#第二页 GET /bank/_search {"size": 10,"sort": [{"account_numb…

【WEB逆向】前端全报文加密的分析技巧

由于前端全报文加密&#xff0c;无法从变量的全文搜索来快速定位加密函数对加密参数的定位&#xff08;全局搜索还有个弊病是编码混淆的js也不能全局搜到&#xff0c;需要进一步分析判定混淆的编码形式后再全局搜编码后的变量名&#xff09;&#xff0c;因此可利用xhr断点全局拦…

LLM reasoners 入门实验 24点游戏

LLM reasoners Ber666/llm-reasoners 实验过程 实验样例24games&#xff0c;examples/tot_game24&#xff0c;在inference.py中配置使用代理和open ai的api key。 首先安装依赖 git clone https://github.com/Ber666/llm-reasoners cd llm-reasoners pip install -e .然后…

【雕爷学编程】Arduino动手做(187)---1.3寸OLED液晶屏模块2

37款传感器与模块的提法&#xff0c;在网络上广泛流传&#xff0c;其实Arduino能够兼容的传感器模块肯定是不止37种的。鉴于本人手头积累了一些传感器和执行器模块&#xff0c;依照实践出真知&#xff08;一定要动手做&#xff09;的理念&#xff0c;以学习和交流为目的&#x…

Spring Security OAuth2.0(7):自定义认证连接数据库

自定义认证连接数据库 首先创建数据库和用户表 CREATE TABLE t_user (id bigint(20) NOT NULL AUTO_INCREMENT,username varchar(64) DEFAULT NULL,password varchar(64) DEFAULT NULL,fullname varchar(255) DEFAULT NULL,mobile varchar(20) DEFAULT NULL,PRIMARY KEY (id)…

Django W292 no newline at end of file

这个警告 "W292 no newline at end of file" 表示在文件末尾没有空行。在许多编程语言中&#xff0c;文件末尾的空行被认为是一种良好的编码习惯。这个警告是 PEP 8&#xff08;Python 编码风格指南&#xff09;的一部分&#xff0c;它建议在文件末尾添加一个空行。 …

MacOS使用brew如何下载Nginx

首先&#xff0c;第一步切换源&#xff1a; 切换 brew.git 仓库地址&#xff1a; cd "$(brew --repo)" git remote set-url origin https://mirrors.aliyun.com/homebrew/brew.git 替换 homebrew-core.git 仓库地址: cd "$(brew --repo)/Library/Taps/home…

LabVIEW 开发在不确定路况下自动速度辅助系统

LabVIEW 开发在不确定路况下自动速度辅助系统 智能驾驶辅助系统是汽车行业最先进的升级和尖端技术&#xff0c;智能交通系统依靠智能驾驶辅助系统在公共交通部门工作。该智能驾驶辅助系统技术包括自适应巡航控制&#xff0c;防抱死制动系统&#xff0c;安全气囊展开&#xff0…

【机器学习】编码、创造和筛选特征

在机器学习和数据科学领域中&#xff0c;特征工程是提取、转换和选择原始数据以创建更具信息价值的特征的过程。假设拿到一份数据集之后&#xff0c;如何逐步完成特征工程呢&#xff1f; 文章目录 一、特性类型分析1.1 数值型特征1.2 类别型特征1.3 时间型特征1.4 文本型特征1.…

图像 检测 - RetinaNet: Focal Loss for Dense Object Detection (arXiv 2018)

图像 检测 - RetinaNet: Focal Loss for Dense Object Detection - 密集目标检测中的焦点损失&#xff08;arXiv 2018&#xff09; 摘要1. 引言2. 相关工作References 声明&#xff1a;此翻译仅为个人学习记录 文章信息 标题&#xff1a;RetinaNet: Focal Loss for Dense Obje…