总结5种比较高效常用的排序算法

2023-11-10

1 概述

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

 

2 选择排序

    选择排序的第一趟处理是从数据序列所有n个数据中选择一个最小的数据作为有序序列中的第1个元素并将它定位在第一号存储位置,第二趟处理从数据序列的n-1个数据中选择一个第二小的元素作为有序序列中的第2个元素并将它定位在第二号存储位置,依此类推,当第n-1趟处理从数据序列的剩下的2个元素中选择一个较小的元素作为有序序列中的最后第2个元素并将它定位在倒数第二号存储位置,至此,整个的排序处理过程就已完成。

    代码如下:

public class SelectionSort {
    public void selectionSort(int[] array) {
        int temp;
        for (int i = 0; i < array.length - 1; i++) {
            for (int j = i + 1; j <= array.length - 1; j++) {// 第i个和第j个比较j可以取到最后一位,所以要用j<=array.length-1
                if (array[i] > array[j]) {// 注意和冒泡排序的区别,这里是i和j比较。
                    temp = array[i];
                    array[i] = array[j];
                    array[j] = temp;
                }
            }
            // 打印每趟排序结果
            for (int m = 0; m <= array.length - 1; m++) {
                System.out.print(array[m] + "\t");
            }
            System.out.println();
        }
    }
  
    public static void main(String[] args) {
        SelectionSort selectionSort = new SelectionSort();
        int[] array = { 5, 69, 12, 3, 56, 789, 2, 5648, 23 };
        selectionSort.selectionSort(array);
        for (int m = 0; m <= array.length - 1; m++) {
            System.out.print(array[m] + "\t");
        }
    }
}

 

3 插入排序

     直接插入排序法的排序原则是:将一组无序的数字排列成一排,左端第一个数字为已经完成排序的数字,其他数字为未排序的数字。然后从左到右依次将未排序的数字插入到已排序的数字中。

    代码如下:

public class InsertSort {
    public void insertSort(int[] array, int first, int last) {
        int temp, i, j;
        for (i = first + 1; i <= last - 1; i++) {// 默认以第一个数为有序序列,后面的数为要插入的数。
            temp = array[i];
            j = i - 1;
            while (j >= first && array[j] > temp) {// 从后进行搜索如果搜索到的数小于temp则该数后移继续搜索,直到搜索到小于或等于temp的数即可
                array[j + 1] = array[j];
                j--;
            }
            array[j + 1] = temp;
            // 打印每次排序结果
            for (int m = 0; m <= array.length - 1; m++) {
                System.out.print(array[m] + "\t");
            }
            System.out.println();
        }
    }
  
    public static void main(String[] args) {
        InsertSort insertSort = new InsertSort();
        int[] array = { 5, 69, 12, 3, 56, 789, 2, 5648, 23 };
        insertSort.insertSort(array, 0, array.length);// 注意此处是0-9而不是0-8
        for (int i = 0; i <= array.length - 1; i++) {
            System.out.print(array[i] + "\t");
        }
    }
}

4 归并排序

    算法描述:

        把序列分成元素尽可能相等的两半。

        把两半元素分别进行排序。

        把两个有序表合并成一个。

    代码如下:

public class MergeSortTest {
    public void sort(int[] array, int left, int right) {
        if (left >= right)
            return;
        // 找出中间索引
        int center = (left + right) / 2;
        // 对左边数组进行递归
        sort(array, left, center);
        // 对右边数组进行递归
        sort(array, center + 1, right);
        // 合并
        merge(array, left, center, right);
        // 打印每次排序结果
        for (int i = 0; i < array.length; i++) {
            System.out.print(array[i] + "\t");
        }
        System.out.println();
  
    }
  
    /**
     * 将两个数组进行归并,归并前面2个数组已有序,归并后依然有序
     * 
     * @param array
     *            数组对象
     * @param left
     *            左数组的第一个元素的索引
     * @param center
     *            左数组的最后一个元素的索引,center+1是右数组第一个元素的索引
     * @param right
     *            右数组最后一个元素的索引
     */
    public void merge(int[] array, int left, int center, int right) {
        // 临时数组
        int[] tmpArr = new int[array.length];
        // 右数组第一个元素索引
        int mid = center + 1;
        // third 记录临时数组的索引
        int third = left;
        // 缓存左数组第一个元素的索引
        int tmp = left;
        while (left <= center && mid <= right) {
            // 从两个数组中取出最小的放入临时数组
            if (array[left] <= array[mid]) {
                tmpArr[third++] = array[left++];
            } else {
                tmpArr[third++] = array[mid++];
            }
        }
        // 剩余部分依次放入临时数组(实际上两个while只会执行其中一个)
        while (mid <= right) {
            tmpArr[third++] = array[mid++];
        }
        while (left <= center) {
            tmpArr[third++] = array[left++];
        }
        // 将临时数组中的内容拷贝回原数组中
        // (原left-right范围的内容被复制回原数组)
        while (tmp <= right) {
            array[tmp] = tmpArr[tmp++];
        }
    }
  
    public static void main(String[] args) {
        int[] array = new int[] { 5, 69, 12, 3, 56, 789, 2, 5648, 23 };
        MergeSortTest mergeSortTest = new MergeSortTest();
        mergeSortTest.sort(array, 0, array.length - 1);
        System.out.println("排序后的数组:");
        for (int m = 0; m <= array.length - 1; m++) {
            System.out.print(array[m] + "\t");
        }
    }
}

 5 希尔排序

    希尔排序又称“缩小增量排序”,该方法的基本思想是:先将整个待排元素序列分割成若干个子序列(由相隔某 个“增量”的元素组成的)分别进行直接插入排序,然后依次缩减增量再进行排序,待整个序列中的元素基本有序(增量足够小)时,再对全体元素进行一次直接插 入排序。因为直接插入排序在元素基本有序的情况下(接近最好情况),效率是很高的,因此希尔排序在时间效率上比前两种方法有较大提高。

    代码如下:

public class ShellSort {
    public void shellSort(int[] array, int n) {
        int i, j, gap;
        int temp;
        for (gap = n / 2; gap > 0; gap /= 2) {// 计算gap大小
            for (i = gap; i < n; i++) {// 将数据进行分组
                for (j = i - gap; j >= 0 && array[j] > array[j + gap]; j -= gap) {// 对每组数据进行插入排序
                    temp = array[j];
                    array[j] = array[j + gap];
                    array[j + gap] = temp;
                }
                // 打印每趟排序结果
                for (int m = 0; m <= array.length - 1; m++) {
                    System.out.print(array[m] + "\t");
                }
                System.out.println();
            }
        }
    }
  
    public static void main(String[] args) {
        ShellSort shellSort = new ShellSort();
        int[] array = { 5, 69, 12, 3, 56, 789, 2, 5648, 23 };
        shellSort.shellSort(array, array.length);// 注意为数组的个数
        for (int m = 0; m <= array.length - 1; m++) {
            System.out.print(array[m] + "\t");
        }
    }
}

 6 快速排序

    快速排序(Quicksort)是对冒泡排序的一种改进。由C. A. R. Hoare在1962年提出。它的基本思想是:通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然 后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列。

    代码如下:

public class QuickSort {
    public int partition(int[] sortArray, int low, int height) {
        int key = sortArray[low];// 刚开始以第一个数为标志数据
        while (low < height) {
            while (low < height && sortArray[height] >= key)
                height--;// 从后面开始找,找到比key值小的数为止
            sortArray[low] = sortArray[height];// 将该数放到key值的左边
            while (low < height && sortArray[low] <= key)
                low++;// 从前面开始找,找到比key值大的数为止
            sortArray[height] = sortArray[low];// 将该数放到key值的右边
        }
        sortArray[low] = key;// 把key值填充到low位置,下次重新找key值
        // 打印每次排序结果
        for (int i = 0; i <= sortArray.length - 1; i++) {
            System.out.print(sortArray[i] + "\t");
        }
        System.out.println();
        return low;
    }
  
    public void sort(int[] sortArray, int low, int height) {
        if (low < height) {
            int result = partition(sortArray, low, height);
            sort(sortArray, low, result - 1);
            sort(sortArray, result + 1, height);
        }
    }
  
    public static void main(String[] args) {
        QuickSort quickSort = new QuickSort();
        int[] array = { 5, 69, 12, 3, 56, 789, 2, 5648, 23 };
        for (int i = 0; i <= array.length - 1; i++) {
            System.out.print(array[i] + "\t");
        }
        System.out.println();
        quickSort.sort(array, 0, 8);
        for (int i = 0; i <= array.length - 1; i++) {
            System.out.print(array[i] + "\t");
        }
    }
}

 

  这里只贴出了自己总结的部分排序算法,更多的算法总结可参考自己另外一篇文章:Java自学之道

 

  原创文章欢迎转载,转载时请注明出处。

  作者推荐文章:

    》Java自学之道

    》Eclipse中部署Hadoop2.3.0并直接在Eclipse中提交mapreduce任务

    》Java如何获取系统信息(包括操作系统、jvm、cpu、内存、硬盘、网络等)

    》Java如何生成二维码过程详解

 

转载于:https://www.cnblogs.com/minkaihui/p/4077888.html

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

总结5种比较高效常用的排序算法 的相关文章

  • SQL中declare申明变量

    原文地址 http blog csdn net yanpingsz article details 5633660 在sql语句中添加变量 declare local variable data type 声明时需要指定变量的类型 可以使用
  • python定时运行,多进程

    可以通过另开一条线程 去专门做这件事情 py2代码如下 如果是py3请自行调整下语法 coding utf8 import threading import time 真正要执行的函数 def t1 print ok 每隔10秒钟执行 de
  • 五大车载操作(VOS)系统优劣对比,车载系统架构分析-QNX系统性能分析

    如果你认为本系列文章对你有所帮助 请大家有钱的捧个钱场 点击此处赞助 赞助额0 1元起步 多少随意 声明 本文只用于个人学习交流 若不慎造成侵权 请及时联系我 立即予以改正 锋影 email 174176320 qq com 导读 车载操作
  • UART、TTL和RS232的区别

    UART TTL和RS232的区别 串行通信 UART TTL RS232 学习硬件的开始接触的就是串口 但是一直没搞懂UART TTL和RS232这些的关系 总感觉相互之间有所交叉 无法完全区分开 于是有了这篇博文 但是 这篇博文自我感觉
  • 分离轴定理(SAT):凸多边形相交检测

    引言 在计算机图形学 游戏开发 碰撞检测等领域 凸多边形相交检测是一个常见而重要的问题 为了快速准确地判断两个凸多边形是否相交 分离轴定理 Separating Axis Theorem 简称 SAT 成为了一种高效而可靠的算法 本文将深入
  • css里各个元素的书写顺序

    1 位置相关 position top left index float display 2 大小相关 width height margin padding 3 文字相关 font line height color letter spa
  • Python 怎么利用Python绘制二元高次隐函数的函数图像及其极值点——以某双核论文模型方程为例

    项目场景 几日前 在研究某双核期刊的某篇论文时 发现论文上的函数图像绘制得似乎有些不精确 原函数方程为 0 2045 y 2 3 4 y 3 2 x y 2 0 45 2 0 论文原文中函数图像如下图 问题描述 可以很明显地看出 极值点附近
  • Gof23设计模式之模板方法模式

    1 定义 定义一个操作中的算法骨架 而将算法的一些步骤延迟到子类中 使得子类可以不改变该算法结构的情况下重定义该算法的某些特定步骤 2 结构 模板方法 Template Method 模式包含以下主要角色 抽象类 Abstract Clas
  • execjs随心所欲运行抠出来的js代码:报错什么都不是问题 execjs._exceptions.ProgramError: ReferenceError: $ is not defined

    起因 今天扣出一段js想用execjs执行 报错 未定义 也就是说execjs不能执行jquery 决定试试用nodejs来执行 execjs exceptions ProgramError ReferenceError is not de
  • Windows10 安装 Vue3

    一 安装Node js 官网下载Node js https nodejs org en download 下载完成后 双击 msi文件 将默认安装路径按照喜好修改 其余的设置默认即可 不需要勾选安装的附加选项 node v 二 更新Node
  • lattice

    lattice 在实际的语音识别系统中 最优路径不一定与实际字序列匹配 我们一般希望能够得到得分最靠前的多条候选路径 即N best 为了紧凑地保存候选路径 我们一般采用lattice 词图 来保存识别的候选序列 lattice本质上是一个
  • Ubuntu18.04上安装RTX 2080Ti显卡驱动

    文章目录 1 安装Linux系统 1 1下载Linux镜像文件 1 2 制作系统盘 1 3 安装Linux系统 1 4 配置linux系统 2 安装英伟达显卡驱动 2 1 预备工作 2 2 安装显卡驱动 3 安装cuda 4 安装cudnn
  • 代数余子式的几何意义,点积和叉乘的几何意义

    1 点乘的几何意义 a b c d e f ad be cf 结果是一个标量 也可以写为 a b a b cos 以下说明点乘的几何意义 就是一个向量在另一个单位向量 如果另一个向量是单位向量 上的投影长度 a b b a cos a b
  • thinkphp5.1开发app接口版本控制(路由设置)

    使用thinkphp5 1开发app接口进行版本控制 在index controller下创建v1和v2目录 v1下创建版本1的文件 如下图 在route route php中 如下图 v获取版本例如 v1 v2 下面第一个路由其实是 接口
  • 如何为服务网格选择入口网关_如果使用服务网格,是否需要API网关?

    如何为服务网格选择入口网关 这篇文章可能无法突破API网关和Service Mesh周围的噪音 但是 这是2020年 围绕这些主题仍然存在很多困惑 我选择编写此内容是为了帮助带来真正的具体解释 以帮助阐明差异 重叠之处以及何时使用它们 如果
  • 前缀树(字典树)应用——实现 Trie (前缀树)、添加与搜索单词

    目录 1 前缀树原理简介 2 实现前缀树 2 1 题目描述 2 2 题目分析 2 3 代码实现 3 添加与搜索单词 3 1 题目描述 3 2 题目分析 3 3 代码实现 4 总结 1 前缀树原理简介 先来简单介绍一下前缀树是什么 前缀树也叫
  • python--爬虫 爬取html和txt文件

    一 python爬取html文件 使用python爬取某网站首页并下载html文件 下面介绍两种方式 一种是urllib 另一种是requests 1 使用urllib import urllib request url http www
  • (十) web自动化测试-PO设计模式

    十 web自动化测试 PO设计模式 文章目录 十 web自动化测试 PO设计模式 前言 一 PageObject原则 1 使用方法代替页面的功能点 2 case中不要过多暴露页面的细节 3 po本身不进行断言 4 一个方法返回另一个页面 P
  • Python运算符中/和//的区别

    首先先看单斜杆的用法 举几个栗子 gt gt gt print 5 3 type 5 3 1
  • node-sass npm安装详解

    node sass npm安装详解 npm 安装 node sass 依赖时 会从 github com 上下载 node 文件 由于国内网络环境的问题 这个下载时间可能会很长 甚至导致超时失败 解决方案就是使用其他源 或者使用工具下载 然

随机推荐

  • 5分钟掌握接口自动化测试,4个知识点简单易学!

    一 什么是接口测试 接口测试是一种软件测试方法 用于验证不同软件组件之间的通信接口是否按预期工作 在接口测试中 测试人员会发送请求并检查接收到的响应 以确保接口在不同场景下都能正常工作 就工具而言 常见的测试工具有Jmeter Postma
  • 一张900w的数据表,16s执行的SQL优化到300ms?

    大家好 我是磊哥 有一张财务流水表 未分库分表 目前的数据量为9555695 分页查询使用到了limit 优化之前的查询耗时16 s 938 ms execution 16 s 831 ms fetching 107 ms 按照下文的方式调
  • 【每日一具3】推荐一个4K、蓝光、3D高清影视下载站,影视资源丰富 发烧友必备

    我猜测大家收藏都是有些能看片源比较丰富能看最新电影的网站 这些网站往往都是采集最大资源网的片源 最新的电影收录后的画质不敢恭维 对于那些真正的影视爱好者来说这不是最好的选择 今天博谈天下给你们推荐一个4K 蓝光 3D高清影视下载站 这个网站
  • C++多态

    C 中的多态分为静态多态和动态多态两种 其中 静态多态在编译阶段实现 其原理是由函数重载实现 通过不同的实参调用其相应的同名函数 动态多态通过虚函数实现 以下着重介绍 动态多态的两个必要条件 必须通过基类的指针或者引用调用 被调用的必须是虚
  • TamperMonkey油猴脚本弹出系统通知

    TamperMonkey油猴脚本弹出系统通知 通知问题 解决方法 删除通知 修改通知内容 通知问题 安装某些TamperMonkey油猴脚本后偶尔弹出如下系统通知 通知标题显示为Microsoft Edge或Chrome 正在使用的浏览器
  • laravel模型中数据批量加入

    laravel模型中数据批量加入 控制器 关联新增批量加入 user User find 19 user gt book gt saveMany new Book title gt 哈利波特1 new Book title gt 哈利波特2
  • Java课题笔记~ SpringMVC概述

    1 1 SpringMVC简介 SpringMVC 也叫Spring web mvc 是Spring 框架的一部分 在Spring3 0 后发布的 1 2 SpringMVC的优点 基于MVC 架构 基于 MVC 架构 功能分工明确 解耦合
  • 性能测试指标全解

    最近在公司做压测时 对于各个监控工具的监控指标一脸蒙 有时候不清晰 有时候理解错误 于是 恶补基础知识 希望对广大网友有所帮助 一 性能测试指标 1 在线用户数 此指标指的是某个时间段内 在服务器上保持登录状态的用户数 在线用户数不等同于并
  • 【Go】字符串拼接

    在 Go 语言中 常见的字符串拼接方式包括 拼接 fmt Sprintf拼接 strings Join拼接 buffer Builderbuffer WriteString拼接和strings Builder WriteString拼接 1
  • 什么是to B 业务

    引言 To B or Not to B there is not a question 对于企业而言 数据分析的作用主要体现在三大领域 1 是对业务的改进优化 2 是帮助业务发现机会 3 是创造新的商业价值 数据分析最重要的是基于对业务的理
  • 常见的反爬手段、原理以及应对思路

    应对反爬的主要思路就是 尽可能的去模拟浏览器 浏览器在如何操作 代码中就如何去实现 1 通过User Agent反爬 爬虫发送请求时 请求头中默认没有User Agent 或者提供非正常的UA 应对思路 在请求时添加UA 具体应对 requ
  • 用JAVA实现网络数据包嗅探

    用JAVA实现网络数据包嗅探 网络嗅探可是说是网络开发的一个基础 SNIFFER IDS都是在这个基础上开发的 一个提供了网络分析 一个提供了入侵检测 实现一个网络嗅探程序到底有多难呢 可以很复杂 也可以很简单 在WINDOWS平台下 大多
  • 框架分析(8)-React Native

    框架分析 8 React Native 专栏介绍 React Native 特性和优势 跨平台开发 热更新 原生性能 组件化开发 第三方库支持 社区支持 限制和挑战 性能问题 第三方库兼容性 学习曲线 总结 专栏介绍 link 主要对目前市
  • 大数据开发:数仓建模常见数据模型

    在数据仓库搭建的过程当中 根据需求合理地选择数据模型 是非常关键的一个环节 对于数仓建模 很多人说不就是建表吗 哪有那么复杂 事实上 这是非常错误的思想 今天的大数据开发分享 我们来聊聊数仓建模常见的几种数据模型 目前来说 市场上主流的数据
  • Tomcat性能优化详细教程

    首先 是客户端访问tomcat的一个过程 如图所示 图中间虚线框部分是 Apache基金下的服务器来做静态资源处理的 而这部分需要花费大量时间 当用nginx和tomcat做企业级集群的时候 需要禁用掉AJP协议 一 准备工作 1 配置管理
  • ORACLE在分区表的分区字段上进行更新的方法

    有些业务表 由于数据量比较大 例如成交表 因此 为了方便查询 通常在一个日期字段上对表进行分区用以提高查询效率 但是一旦对表进行分区后 如果要对表中的记录更新 如果更新字段设计到了分区字段 那么update语句就会出错 ORA 10442
  • 学习TCP

    参考知乎 实战 我用 Wireshark 让你 看见 TCP 知乎 zhihu com 学习工具 tcpdump linux wireshark windows dump 转储 json dump a fp 转储到文件 动态数据转储为静态文
  • 关于基本功能测试用例,到底是传统的表格(Excel)形式好还是思维导图(Xmind、MindManager等)模式好?

    这个问题先抛出我的观点 具体选择哪种形式更好 需要根据具体情况来考虑 如果测试用例较为简单 可以选择表格形式 如果测试用例较为复杂 可以选择思维导图形式 但实际工作中 二者一般是结合使用的 想把握好这个度 就需要了解两种用例形式的优缺点 所
  • Windows batch编程常用语法及命令介绍

    1 echo 和 回显命令 关闭单行回显 echo off 从下一行开始关闭回显 echo off 从本行开始关闭回显 一般批处理第一行都是这个 echo on 从下一行开始打开回显 echo 显示当前是 echo off 状态还是 ech
  • 总结5种比较高效常用的排序算法

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