选择、插入、归并、希尔、快速排序算法性能比较总结

2023-11-05

1 概述

    本文对比较常用且比较高效的排序算法进行了总结和解析,并贴出了比较精简的实现代码,包括选择排序、插入排序、归并排序、希尔排序、快速排序等。算法性能比较如下图所示:


2 选择排序
选择排序的第一趟处理是从数据序列所有n个数据中选择一个最小的数据作为有序序列中的第1个元素并将它定位在第一号存储位置,第二趟处理从数据序列的n-1个数据中选择一个第二小的元素作为有序序列中的第2个元素并将它定位在第二号存储位置,依此类推,当第n-1趟处理从数据序列的剩下的2个元素中选择一个较小的元素作为有序序列中的最后第2个元素并将它定位在倒数第二号存储位置,至此,整个的排序处理过程就已完成。
代码如下:
  1. public class SelectionSort {
  2.     public void selectionSort(int[] array) {
  3.         int temp;
  4.         for (int i = 0; i < array.length - 1; i++) {
  5.             for (int j = i + 1; j <= array.length - 1; j++) {// 第i个和第j个比较j可以取到最后一位,所以要用j<=array.length-1
  6.                 if (array[i] > array[j]) {// 注意和冒泡排序的区别,这里是i和j比较。
  7.                     temp = array[i];
  8.                     array[i] = array[j];
  9.                     array[j] = temp;
  10.                 }
  11.             }
  12.             // 打印每趟排序结果
  13.             for (int m = 0; m <= array.length - 1; m++) {
  14.                 System.out.print(array[m] + "\t");
  15.             }
  16.             System.out.println();
  17.         }
  18.     }

  19.     public static void main(String[] args) {
  20.         SelectionSort selectionSort = new SelectionSort();
  21.         int[] array = { 5, 69, 12, 3, 56, 789, 2, 5648, 23 };
  22.         selectionSort.selectionSort(array);
  23.         for (int m = 0; m <= array.length - 1; m++) {
  24.             System.out.print(array[m] + "\t");
  25.         }
  26.     }
  27. }
复制代码

3 插入排序
直接插入排序法的排序原则是:将一组无序的数字排列成一排,左端第一个数字为已经完成排序的数字,其他数字为未排序的数字。然后从左到右依次将未排序的数字插入到已排序的数字中。
代码如下:
  1. public class InsertSort {
  2.     public void insertSort(int[] array, int first, int last) {
  3.         int temp, i, j;
  4.         for (i = first + 1; i <= last - 1; i++) {// 默认以第一个数为有序序列,后面的数为要插入的数。
  5.             temp = array[i];
  6.             j = i - 1;
  7.             while (j >= first && array[j] > temp) {// 从后进行搜索如果搜索到的数小于temp则该数后移继续搜索,直到搜索到小于或等于temp的数即可
  8.                 array[j + 1] = array[j];
  9.                 j--;
  10.             }
  11.             array[j + 1] = temp;
  12.             // 打印每次排序结果
  13.             for (int m = 0; m <= array.length - 1; m++) {
  14.                 System.out.print(array[m] + "\t");
  15.             }
  16.             System.out.println();
  17.         }
  18.     }

  19.     public static void main(String[] args) {
  20.         InsertSort insertSort = new InsertSort();
  21.         int[] array = { 5, 69, 12, 3, 56, 789, 2, 5648, 23 };
  22.         insertSort.insertSort(array, 0, array.length);// 注意此处是0-9而不是0-8
  23.         for (int i = 0; i <= array.length - 1; i++) {
  24.             System.out.print(array[i] + "\t");
  25.         }
  26.     }
  27. }
复制代码

4 归并排序
算法描述:
把序列分成元素尽可能相等的两半。
把两半元素分别进行排序。
把两个有序表合并成一个。
代码如下:
  1. public class MergeSortTest {
  2.     public void sort(int[] array, int left, int right) {
  3.         if (left >= right)
  4.             return;
  5.         // 找出中间索引
  6.         int center = (left + right) / 2;
  7.         // 对左边数组进行递归
  8.         sort(array, left, center);
  9.         // 对右边数组进行递归
  10.         sort(array, center + 1, right);
  11.         // 合并
  12.         merge(array, left, center, right);
  13.         // 打印每次排序结果
  14.         for (int i = 0; i < array.length; i++) {
  15.             System.out.print(array[i] + "\t");
  16.         }
  17.         System.out.println();

  18.     }

  19.     /**
  20.      * 将两个数组进行归并,归并前面2个数组已有序,归并后依然有序
  21.      * 
  22.      * @param array
  23.      *            数组对象
  24.      * @param left
  25.      *            左数组的第一个元素的索引
  26.      * @param center
  27.      *            左数组的最后一个元素的索引,center+1是右数组第一个元素的索引
  28.      * @param right
  29.      *            右数组最后一个元素的索引
  30.      */
  31.     public void merge(int[] array, int left, int center, int right) {
  32.         // 临时数组
  33.         int[] tmpArr = new int[array.length];
  34.         // 右数组第一个元素索引
  35.         int mid = center + 1;
  36.         // third 记录临时数组的索引
  37.         int third = left;
  38.         // 缓存左数组第一个元素的索引
  39.         int tmp = left;
  40.         while (left <= center && mid <= right) {
  41.             // 从两个数组中取出最小的放入临时数组
  42.             if (array[left] <= array[mid]) {
  43.                 tmpArr[third++] = array[left++];
  44.             } else {
  45.                 tmpArr[third++] = array[mid++];
  46.             }
  47.         }
  48.         // 剩余部分依次放入临时数组(实际上两个while只会执行其中一个)
  49.         while (mid <= right) {
  50.             tmpArr[third++] = array[mid++];
  51.         }
  52.         while (left <= center) {
  53.             tmpArr[third++] = array[left++];
  54.         }
  55.         // 将临时数组中的内容拷贝回原数组中
  56.         // (原left-right范围的内容被复制回原数组)
  57.         while (tmp <= right) {
  58.             array[tmp] = tmpArr[tmp++];
  59.         }
  60.     }

  61.     public static void main(String[] args) {
  62.         int[] array = new int[] { 5, 69, 12, 3, 56, 789, 2, 5648, 23 };
  63.         MergeSortTest mergeSortTest = new MergeSortTest();
  64.         mergeSortTest.sort(array, 0, array.length - 1);
  65.         System.out.println("排序后的数组:");
  66.         for (int m = 0; m <= array.length - 1; m++) {
  67.             System.out.print(array[m] + "\t");
  68.         }
  69.     }
  70. }
复制代码

5 希尔排序
希尔排序又称“缩小增量排序”,该方法的基本思想是:先将整个待排元素序列分割成若干个子序列(由相隔某 个“增量”的元素组成的)分别进行直接插入排序,然后依次缩减增量再进行排序,待整个序列中的元素基本有序(增量足够小)时,再对全体元素进行一次直接插 入排序。因为直接插入排序在元素基本有序的情况下(接近最好情况),效率是很高的,因此希尔排序在时间效率上比前两种方法有较大提高。
代码如下:
  1. public class ShellSort {
  2.     public void shellSort(int[] array, int n) {
  3.         int i, j, gap;
  4.         int temp;
  5.         for (gap = n / 2; gap > 0; gap /= 2) {// 计算gap大小
  6.             for (i = gap; i < n; i++) {// 将数据进行分组
  7.                 for (j = i - gap; j >= 0 && array[j] > array[j + gap]; j -= gap) {// 对每组数据进行插入排序
  8.                     temp = array[j];
  9.                     array[j] = array[j + gap];
  10.                     array[j + gap] = temp;
  11.                 }
  12.                 // 打印每趟排序结果
  13.                 for (int m = 0; m <= array.length - 1; m++) {
  14.                     System.out.print(array[m] + "\t");
  15.                 }
  16.                 System.out.println();
  17.             }
  18.         }
  19.     }

  20.     public static void main(String[] args) {
  21.         ShellSort shellSort = new ShellSort();
  22.         int[] array = { 5, 69, 12, 3, 56, 789, 2, 5648, 23 };
  23.         shellSort.shellSort(array, array.length);// 注意为数组的个数
  24.         for (int m = 0; m <= array.length - 1; m++) {
  25.             System.out.print(array[m] + "\t");
  26.         }
  27.     }
  28. }
复制代码

6 快速排序
快速排序(Quicksort)是对冒泡排序的一种改进。由C. A. R. Hoare在1962年提出。它的基本思想是:通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然 后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列。
代码如下:
  1. <font size="3"><pre class="brush: csharp; gutter: false; first-line: 1">public class QuickSort {
  2.     public int partition(int[] sortArray, int low, int height) {
  3.         int key = sortArray[low];// 刚开始以第一个数为标志数据
  4.         while (low < height) {
  5.             while (low < height && sortArray[height] >= key)
  6.                 height--;// 从后面开始找,找到比key值小的数为止
  7.             sortArray[low] = sortArray[height];// 将该数放到key值的左边
  8.             while (low < height && sortArray[low] <= key)
  9.                 low++;// 从前面开始找,找到比key值大的数为止
  10.             sortArray[height] = sortArray[low];// 将该数放到key值的右边
  11.         }
  12.         sortArray[low] = key;// 把key值填充到low位置,下次重新找key值
  13.         // 打印每次排序结果
  14.         for (int i = 0; i <= sortArray.length - 1; i++) {
  15.             System.out.print(sortArray[i] + "\t");
  16.         }
  17.         System.out.println();
  18.         return low;
  19.     }

  20.     public void sort(int[] sortArray, int low, int height) {
  21.         if (low < height) {
  22.             int result = partition(sortArray, low, height);
  23.             sort(sortArray, low, result - 1);
  24.             sort(sortArray, result + 1, height);
  25.         }
  26.     }

  27.     public static void main(String[] args) {
  28.         QuickSort quickSort = new QuickSort();
  29.         int[] array = { 5, 69, 12, 3, 56, 789, 2, 5648, 23 };
  30.         for (int i = 0; i <= array.length - 1; i++) {
  31.             System.out.print(array[i] + "\t");
  32.         }
  33.         System.out.println();
  34.         quickSort.sort(array, 0, 8);
  35.         for (int i = 0; i <= array.length - 1; i++) {
  36.             System.out.print(array[i] + "\t");
  37.         }
  38.     }
  39. }</pre></font><pre class="brush: csharp; gutter: false; first-line: 1"></pre>
复制代码 文章来源: http://www.mfqyw.com/
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

选择、插入、归并、希尔、快速排序算法性能比较总结 的相关文章

  • Dubbo分布式日志追踪,多线程不能获取窜ID和IP问题

    接着上一篇日志 当用MDC或者ThreadContext来put或者get数据的时候 不同线程是获取不到的 他们都是ThreadLocal维护 所以线程独立 如果需要子线程获取则将参数传入 在Thread的run方法执行的时候将传入的ID和
  • Ubuntu & CentOS配置JAVA JDK环境

    Linux配置Java JDK 环境 下载地址 https www oracle com technetwork java javase downloads jdk8 downloads 2133151 html 根据系统相应版本进行下载
  • 程序流程图

    程序流程图又称程序框图 是以特定图形符号外加文字说明描述程序运行具体步骤的图示 它结合相应的算法 经由处理框 判断框 起止框 连接点 流程线等构成整个流程图 在工作过程中 流程图主要是说明某一特定过程 尤其对于产品经理和交互设计师来说 学会
  • Qt Creator登录对话框

    实现功能 在弹出对话框中填写用户名和密码 按下登录按钮 如果用户名和密码均正确则进入主窗口 如果有错则弹出警告对话框 实现原理 通过上节的多窗口原理实现由登录对话框进入主窗口 而用户名和密码可以用if语句进行判断 实现过程 1 先新建Qt4
  • 基于D-S证据理论的数据融合研究与应用

    1 课题背景及研究的目的和意义 1 1课题背景 证据理论源于20世纪60年代美国哈弗大学的数学家A P Dempster 利用上 下概率来解决多值映射问题方面的研究工作 后来他的学生G Shafer对证据理论引入了信任函数和似然函数的概念
  • 指针数组——元素为指针的数组

    说明 指针数组就是一个数组 这个数组的数组单元都是指针型数据 定义 int a 6 1 2 3 4 5 6 int p 6 数据类型符 变量名 常量表达式 用法 for i 0 i lt 6 i p i a i 就是一个元素为指针的数组 注
  • CTF比赛中常见的MISC解题方法(不涉及内存取证和流量分析)仅供菜鸟,大佬绕道

    我们在ctf比赛中 大多数时候签到题都是misc 会不会有小伙伴因为签到题而感到头痛 其实misc的签到题是非常简单的 不然怎么可能叫签到 好吧 废话不多说 直接说干货 1 题目直接给了编码 比如 前几天的第一届 长城杯 的misc签到题
  • 单片机学习 7-IO拓展(串转并)-74HC595

    I O拓展 串转并 74HC595芯片介绍 上面两张都是 74HC595 芯片管脚图 左侧的 1 脚是 QB 而右侧芯片的 1 脚是 Q1 左侧芯片的 11 脚是 SCK 而右侧芯片的 11 脚是 SH CP 还有很多其他管脚不一样 其实这
  • 【Linux命令详解

    文章标题 简介 一 参数列表 二 使用介绍 1 pwd命令的基本使用 2 pwd命令中的参数 3 pwd命令的工作机制 4 pwd命令的实际应用 总结 简介 pwd命令是Linux中的基础命令之一 使用该命令可以快速查看当前工作目录 在掌握
  • go 实现结构体的复制

    go 将一个结构体里面的数据全部复制到另一个结构体 import reflect func DeepFields ifaceType reflect Type reflect StructField var fields reflect S
  • KEIL Real view MDK中插入空操作NOP

    折腾了大半天 才搞明白一个空操作的指令 先在网上查有的说是 asm NOP 从intrins h里调用 可犄角旮旯全找了 也没看到什么intrint h的文件 如果直接用 就出现 error 1113 Inline assembler no
  • git获取本地用户名和密码命令

    1 查看本地 Git 配置文件 在使用 Git 的过程中 用户的用户名和邮箱地址都会被保存在本地 Git 配置文件中 因此 可以通过查看该配置文件来获取用户名和密码 打开 Git Bash 或者终端窗口 输入以下命令 查看用户名 git c
  • kaggle在output上;pytorch安装包下载后怎么装;(最全的安装包下载带cuda版本)DGL113下载;报错:UserWarning: NVIDIA GeForce RTX;fcntl报错

    1 kaggle在output上运行 可以从kaggle上查看https www kaggle com houzitest cake1111 因为input只能读 所以再output上运行 再执行 import torch print to
  • (C++)输入一行字符,分别统计出其中英文字母、空格、数字的个数

    include
  • echart 实现可以点击下钻的地图

    codescanbox 封装成了一个类 通过 getLoadMap 来获取对应的实例对象 一个是单纯的地图 一个是可以打点的地图 getLoadMap 需要 3 个参数 echarts 实例 registerMap 注册地图的api typ
  • ionic3之js(jQuary),css,图片的引入

    一 js文件 以jQuary为例 相信有很多朋友使用不习惯angularjs 所以想使用已经很熟悉的JQuary 在这里我就给出怎么引入jQuary文件 并使用 1 把要引入的jQuary文件放到app下的assets目录下 2 在src下
  • go 进阶 请求代理相关: 三. ReverseProxy 负载均衡

    目录 一 ReverseProxy 负载均衡 简单随机负载均衡示例 简单轮询负载均衡示例 加权负载均衡示例 一致性Hash 二 反向代理添加负载均衡功能 一 ReverseProxy 负载均衡 ReverseProxy 支持负载均衡功能 提
  • IO之字节字符转换流

    1 转换流概述 转换流 可以将一个字节流转换为字符流 也可以将一个字符流转换为字节流 OutputStreamWriter 可以将输出的字符流转换为字节流的输出形式 InputStreamReader 将输入的字节流转换为字符流输入形式 2
  • 多文件编辑作业(2023.1.9)

    第一题 main c include head h int main int argc const char argv char str 10 abcdefg MyStrRev str char a hello StrRevRec a st
  • qt 在ui界面添加控件后在cpp文件中无法调用?

    问题 qt 在ui界面添加控件后在cpp文件中无法调用 解决方法 在build选项中选择 重新build项目 再次在cpp中调用添加的控件发现可以调用了 还有一种情况导致添加控件后无法调用 就是没有导入ui xxx h文件 xxx是ui界面

随机推荐

  • Python图像处理-4.pil调整图片尺寸和旋转角度

    from PIL import Image import matplotlib pyplot as plt pil im1 Image open pic1 png plt figure girlfriend1 plt imshow pil
  • 魔搭开源FaceChain个人写真项目,大幅提升写真多样性,登顶github趋势榜首!

    一 上周数据概览 一周时间获取超过3K star 连续在github trending榜单蝉联top 开发者们纷纷标记star GitHub modelscope facechain FaceChain is a deep learning
  • zlib库VS2017编译步骤

    点击这里下载zlib1 2 11源码 http zlib net zlib1211 zip 下载源码库 从上面给出的源码路径下载zlib源码库 如果不想自己编译 可以使用上面给出的二进制包直接使用 无视本文 编译步骤 编译方法一 解压源码文
  • MyBatis-plus 动态条件构造器总结

    MyBatis plus 动态条件构造器类结构图 MyBatis Plus条件构造器QueryWrapper对应常用SQL语法说明 函数 说明 SQL语法 eq 等于 ne 不等于 lt gt gt 大于 gt lt 小于 lt ge 大于
  • STM32单片机通过ESP8266WiFi模块与Android APP实现数据传输(一)---下位机硬件配置

    事务的难度远远低于对事物的恐惧 STM32F407单片机通过ESP8266 WiFi模块与Android 手机APP连接实现数据的相互传输 在单片机上通过LCD显示屏实时显示连接的状态以及互相传输的数据 先看效果图 STM32单片机 And
  • simulink教程(自动控制原理)

    1 启动simulink 命令行输入simulink或者 会弹出 2 点击blank model 出现新窗口 新建或者打开模型文件 There are two major classes of items in Simulink block
  • GLES3.0中文API-glDrawRangeElements

    名称 glDrawRangeElements 从数组数据渲染基元 C规范 void glDrawRangeElements GLenum mode GLuint start GLuint end GLsizei count GLenum t
  • Open mv识别三角形的办法

    文章目录 前言 带着问题来看 一 函数 二 使用方法 1 find line segments 2 img find template 三 摄像情况及终端结果 1 find line segments 2 img find template
  • 初始C语言——利用Ascll码进行字母大小写转换

    打开Ascll码表 你会发现大写字母和小写字母之间存在这样的关系 图片来自 https img blog csdnimg cn 54404234b42348d6a33bc1c4d5ab24e5 png 小写字母的值始终比大写字母多32 de
  • Node.js

    Node js Node js基础 概念 简单的说 Node js 就是运行在服务端的 JavaScript Node js 是一个基于Chrome JavaScript 运行时建立的一个平台 Node js是一个事件驱动I O服务端Jav
  • (五)决策树

    一 决策树 决策树是监督学习算法 下面为一些样本 本质上是一种特征去结果的相关度 比如你的信贷情况与能否还贷的相关度肯定高 而你有没有结婚的相关度肯定低 二 信息增益 三 ID3算法
  • php 未支付取消订单,【php】用户提交订单,30分钟后没付款取消订单功能分析

    我先在要做这样的功能 用户在创建订单后 订单表中记入的是未付款状态 如果用户在30分钟后 还未付款 然后就把该订单给取消 关于用户创建订单 30分钟后还没付款 取消该订单的逻辑是怎么实现的 我自己的想了两个方案 1 客户端记入这个订单 如果
  • MindNode 5 for Mac(思维导图软件)中文版

    绘制流程图 思维导图 规划图 信息图等自然少不了这款MindNode 5 for Mac 作为优质的思维导图软件 mindnode5 mac破解版的功能很全面 添加文字 链接 图片 扩展注释等非常便捷 而且mindnode 5 破解版会智能
  • Rocketmq原理&最佳实践

    一 MQ背景 选型 消息队列作为高并发系统的核心组件之一 能够帮助业务系统解构提升开发效率和系统稳定性 主要具有以下优势 削峰填谷 主要解决瞬时写压力大于应用服务能力导致消息丢失 系统奔溃等问题 系统解耦 解决不同重要程度 不同能力级别系统
  • Python开发篇——基于React-Dropzone开发上传组件

    这次我要讲述的是在React Flask框架上开发上传组件的技巧 我目前主要以React开发前端 在这个过程中认识到了许多有趣的前端UI框架 React Bootstrap Ant Design Material UI Bulma等 而比较
  • Linux操作系统知识点总结

    1 什么是Linux系统 Linux 全称GNU Linux 是一种免费使用和自由传播的类UNIX操作系统 其内核由林纳斯 本纳第克特 托瓦兹 Linus Benedict Torvalds 于1991年10月5日首次发布 它主要受到Min
  • Qt 实现自定义Ui控件例子,以自定义的Slider为例(QWidget)

    说明 Qt可以比较方便地实现自定义控件在Qt Creator中使用 网上也有很多大神的控件可以使用 但是如果想要自己简单定制也可以按照这个流程 本文的要点 1 如何实现一个自定义控件 本文使用的方法有两个步骤 先在一个普通项目中实现使用 新
  • FreeRTOS学习笔记(3、信号量、互斥量的使用)

    FreeRTOS学习笔记 3 信号量 互斥量的使用 前言 往期学习笔记链接 学习工程 信号量 semaphore 两种信号量的对比 信号量的使用 1 创建信号量 2 give 3 take 4 删除信号量 使用计数型信号量实现同步功能 使用
  • zookeeper结构和命令

    zookeeper特性 1 Zookeeper 一个leader 多个follower组成的集群 2 全局数据一致 每个server保存一份相同的数据副本 client无论连接到哪个server 数据都是一致的 3 分布式读写 更新请求转发
  • 选择、插入、归并、希尔、快速排序算法性能比较总结

    1 概述 本文对比较常用且比较高效的排序算法进行了总结和解析 并贴出了比较精简的实现代码 包括选择排序 插入排序 归并排序 希尔排序 快速排序等 算法性能比较如下图所示 2 选择排序 选择排序的第一趟处理是从数据序列所有n个数据中选择一个最