数据结构与算法 — 希尔排序 和 快速排序

2023-05-16

目录

一. 希尔排序

  1.希尔排序的介绍

        (1).希尔排序的历史背景

        (2).插入排序的问题

        (3).希尔排序的做法

        (4).选择合适的增量

  2.希尔排序的实现

  3.希尔排序的效率

        (1).希尔排序的效率

        (2).Hibbard 增量序列

        (3).Sedgewick增量序列

二、快速排序

  1.快速排序的介绍

        (1).快速排序的重要性

        (2).快速排序是什么

        (3).快速排序的思想

  2.快速排序的枢纽

  3.快速排序的实现

  4.快速排序的效率

        (1).快速排序的最坏情况效率

        (2).快速排序的平均效率


一. 希尔排序

        希尔排序是插入排序的一种改进版,效率比插入排序要更快

  1.希尔排序的介绍

        (1).希尔排序的历史背景

        希尔排序按其设计者希尔(Donald Shell)的名字命名,该算法由1959年公布。优先的排序算法首要条件就是速度,在简单排序出现后的很多一段时间内,人们发明了各种各样的算法,但是最终发现算法的时间复杂度都是O(N²),似乎没法超越了。此时,计算机学术界充斥着"排序算法不可能突破O(N²)"的声音。终于有一天,一位科学家发布超越了O(N²)的新排序算法(后来为了纪念这个里程碑,用Shell来命名了该算法)。

 

        (2).插入排序的问题

        假设一个很小的数据项在很靠近右端的位置上,这里本来应该是较大的数据项的位置。把这个小数据项移动到左边的正确位置,所有的中间数据项都必须向右移动一位。如果每个步骤对数据项都进行N次复制,平均下来是移动N/2,N个元素就是 N*N/2 = N²/2。通常认为插入排序的效率是O(N²)。

        (3).希尔排序的做法

 

        比如上面的数字, 81, 94, 11, 96, 12, 35, 17, 95, 28, 58, 41, 75, 15。

先让间隔为5进行排序. (81, 35, 41), (94, 17, 75), (11, 95, 15), (96, 28), (12, 58)

排序后的新序列, 一定可以让数字离正确位置更近一步。

再让间隔位3进行排序. (35, 28, 75, 58, 95), (17, 12, 15, 81), (11, 41, 96, 94)

排序后的新序列, 一定可以让数字离自己的正确位置又近了一步。

最后,让间隔为1,也就是正确的插入排序。这个时候数字都离自己的正确位置更近,那么需要复制的次数就会减少很多。

 

        (4).选择合适的增量

        在希尔排序的原稿中建议的初始间距是N / 2,简单的把每一回排序分成两半。也就是说,对于N = 100的数组,增量间隔序列为: 50, 25, 12, 6, 3, 1。这个方法的好处是不需要在开始排序前为找合适的增量而进行任何的计算

  2.希尔排序的实现

    //希尔排序
    ArrayList.prototype.shellSort = function () {
        //1.获取数组长度
        var length = this.array.length
        //2.初始化的增量
        var gap = Math.floor(length / 2)
        //3.while循环(gap不断的减小)
        while (gap >= 1) {
            //4.以gap作为间隔,进行分组,对分组进行插入排序
            for (var i = 0; i < length; i++) {
                var temp = this.array[i]
                var j = i
                while (this.array[j - gap] > temp && j > gap - 1) {
                    this.array[j] = this.array[j - gap]
                    j -= gap
                }
                //5.将j位置的元素赋值temp
                this.array[j] = temp
            }
            gap = Math.floor(gap / 2)
        }
    }

 

  3.希尔排序的效率

        (1).希尔排序的效率

        希尔排序的效率与增量是有关系的。但是,它的效率证明非常困难,甚至某些增量的效率到目前依然没有被证明出来。但是经过统计,希尔排序使用原始增量,最坏的情况下时间复杂度为O(N²),通常情况下都要好于O(N²)

 

        (2).Hibbard 增量序列

        增量的算法为2^k - 1,也就是为1 3 5 7...等等。这种增量的最坏复杂度为O(N^3/2), 猜想的平均复杂度为O(N^5/4),目前尚未被证明。

 

        (3).Sedgewick增量序列

        增量序列为{1, 5, 19, 41, 109, … },该序列中的项是94^i - 9*2^i + 1或者是4^i - 32^i + 1

这种增量的最坏复杂度为O(N^4/3),平均复杂度为O(N^7/6),但是均未被证明.

 

使用希尔排序大多数情况下效率都高于简单排序, 甚至在合适的增量和N的情况下, 还好于快速排序.

二、快速排序

  1.快速排序的介绍

        (1).快速排序的重要性

        快速排序可以说是排序算法中最常见的,也被列为20世纪十大算法之一。快速排序几乎可以说是目前所有排序算法中最快的一种排序算法。当然, 没有任何一种算法是在任意情况下都是最优的, 比如希尔排序确实在某些情况下可能好于快速排序。但是大多数情况下,快速排序还是比较好的选择。

 

        (2).快速排序是什么

        希尔排序相当于插入排序的升级版,快速排序其实也是冒泡排序的升级版。冒泡排序需要经过很多次交换,才能在一次循环中,将最大值放在正确的位置上。而快速排序可以在一次循环中(其实是递归调用)找出某个元素的正确位置,并且该元素之后不需要任何移动。

 

        (3).快速排序的思想

 

快速排序最重要的思想是分而治之

如上图有这样一些数字需要排序:

第一步: 从其中选出了65。(可以是选出任意的数字)

第二步: 将所有小于65的数字放在65的左边,将所有大于65的数字放在65的右边。

第三步: 递归处理左边的数据,递归的处理右边的数据。

第四步: 排序完成

 

  2.快速排序的枢纽

        快速排序中有一个很重要的步骤就是选取枢纽。

        选取最合适的枢纽:

        一种方案是直接选择第一个元素作为枢纽。但第一个作为枢纽在某些情况下,效率并不是特别高。

        另一种方案是使用随机数,随机取 pivot,但是随机函数是一个耗性能的操作。

        另一种比较优秀的解决方案是:取头、中、尾的中位数。例如 8、12、3的中位数就是8。

 

枢纽选择的代码实现:

    //1.选择枢纽
    ArrayList.prototype.median = function (left, right) {
        //1.取出中间的位置
        var center = Math.floor((left + right) / 2)
        //2.判断大小,并进行交换
        if (this.array[left] > this.array[center]) {
            this.swap(left, center)
        }
        if (this.array[left] > this.array[right]) {
            this.swap(left, right)
        }
        if (this.array[center] > this.array[right]) {
            this.swap(center, right)
        }

        //3.将center换到right-1的位置
        this.swap(center, right - 1)

        return this.array[right - 1]
    }

 

  3.快速排序的实现

    //2.代码实现
    ArrayList.prototype.quickSort = function(){
        this.quick(0,this.array.length-1)
    }
    ArrayList.prototype.quick = function (left, right) {
        //1.结束条件
        if (left >= right) return

        //2.获取枢纽
        var pivot = this.median(left, right)

        //3.定义变量
        var i = left
        var j = right - 1

        //4.开始进行交换
        while (i!=j) {
            while (this.array[++i] < pivot) { }
            while (this.array[--j] > pivot) { }
            if (i < j) {
                this.swap(i, j)
            } else {
                break
            }
        }

        //5.将枢纽放到正确的位置,i的位置
        this.swap(i, right - 1)

        //6.分而治之
        this.quick(left, i - 1)
        this.quick(i + 1, right)
    }

 

  4.快速排序的效率

        (1).快速排序的最坏情况效率

        快速排序最坏的效率就是每次选择的枢纽都是最左边或者最后边的。那么效率等同于冒泡排序。

        (2).快速排序的平均效率

        快速排序的平均效率是O(N * logN).

 

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

数据结构与算法 — 希尔排序 和 快速排序 的相关文章

随机推荐

  • 修改ssh默认端口22

    平滑修改linux中的sshd端口 第一种 xff1a 1 假如要改SSH的默认端口 xff08 22 xff09 xff0c 那么你只要修改 xff1a 代码如下 etc ssh sshd config中Port 22 这里把22改成自己
  • docker and docker-compose安装

    docker 安装 curl sSL https get daocloud io docker sh docker compose 安装 1 curl L https get daocloud io docker compose relea
  • mysql远程登录

    MySQL5 7授权用户远程访问 做个记录 xff0c 每次弄环境的时候 xff0c 特别是弄mysql环境 xff0c 时不时都要用到下面的命令 命令如下 grant all privileges on to 39 root 39 64
  • zabbix5.0快速部署脚本

    bin bash 版本1 0 zabbix 43 nginx版本 welcome cat lt lt EOF 需要需改的配置文件有 xff1a 1 vi etc yum repos d zabbix repo zabbix源 2 vi et
  • openstack创建网络,路由等

    参考链接 xff1a https blog csdn net qq 28540443 article details 109184700 ops request misc 61 amp request id 61 amp biz id 61
  • shell脚本颜色

    https blog csdn net it chang article details 111084116
  • windows11 安装 vmare sphere client 无法启动问题

    被搞了两天特别记录一下 xff1a 现象 xff1a 安装什么都正常双击就是启动不了 解决 xff1a 控制面板 程序和功能
  • ceph delete pool

    参考 xff1a Pools Ceph Documentation 前言 xff1a 网上的写的乱七八糟不是你抄我就是我抄你 写的完全瞎扯 简直看不下去 官网截图 xff1a 准备 1 查看pool名称 ceph osd lspools 创
  • TODS:一款功能强大的多元时间序列异常检测工具

    TODS是一个全栈的自动化机器学习系统 xff0c 主要针对多变量时间序列数据的异常检测 该系统可以处理三种常见的时间序列异常检测场景 xff1a 点的异常检测 xff08 异常是时间点 xff09 模式的异常检测 xff08 异常是子序列
  • Linux防火墙firewalld安全设置

    背景描述 防火墙是具有很好的保护作用 攻击者必须首先穿越防火墙的安全防线 xff0c 才能接触目标计算机 在公司里数据安全是最重要的 xff0c 要求安全部门进行全公司进行服务器防火墙安全搭建 xff0c 在原有的基础上进行安全的防火墙设置
  • STM32F1--FreeRTOS系统学习(一):系统下载移植以及跑马灯测试

    以下内容皆是个人学习过程中的总结 xff0c 记录一下整个过程 xff0c 用于后期复习 xff0c 如有不对之处 xff0c 麻烦各位大佬指出 xff08 喜欢的朋友麻烦点个关注 后期还会进行持续更新 xff09 一 什么是FreeRTO
  • 如何准备国内一流互联网公司面试,如百度、阿里、腾讯、字节等

    入职新公司快半年了 xff0c 今天 xff0c 我就想和大家聊聊 xff0c 关于找工作 面试的一些心得与体会 说实话 xff0c 在这次找工作之前 xff0c 我面试找工作的经历并不丰富 xff0c 反而是当面试官的次数更多 所以呢 x
  • 基于 瑞芯微 RK1126 平台的项目总结(包含AI 画中画 RTSP OSD 录像 双路摄像头)

    其实这个项目结束一两个月了 中间过了个年 就把这事给忘记了 趁现在比较空记录一下 说下概况 项目是基于RK1126平台 硬件配置2个摄像头一个广角一个长焦 需要支持画中画在广角摄像头的画面中 显示长焦摄像头的大概位置 但是由于硬件还是驱动没
  • JavaScript小案例2-实现猜数游戏

    题目要求 xff1a 系统生成一个1 100的数 xff0c 然后让玩家猜数 如果玩家猜对该数 xff0c 则游戏结束 xff1b 如果没猜对 xff0c 则弹出警告框告告知玩家数字猜大了还是猜小了 xff0c 并提示玩家是否继续游戏 xf
  • 【Ubuntu】Linux文件系统简介

    Linux文件系统简介 Linux文件系统简介及类型1 Linux文件系统简介2 Linux文件系统类型 Linux文件系统结构文件操作指令创建新文件命令 touch创建文件夹命令 mkdir文件夹及目录删除命令 rm文件夹 目录 删除命令
  • 嵌入式实时操作系统(RTOS)

    一 项目准备工作 1 创建一个标准库项目 这里不用很麻烦 xff0c 项目能跑就行 xff0c 后面要以这个项目为基础移植 2 下载ucOS 源码 ucos 源码 百度网盘链接 xff1a 提取码 xff1a 1234 xff08 STM3
  • ROS环境安装与配置

    提示 xff1a 文章写完后 xff0c 目录可以自动生成 xff0c 如何生成可参考右边的帮助文档 文章目录 实验环境一 ROS话题二 ROS消息三 C 43 43 编码实现小海龟圆周运动 提示 xff1a 以下是本篇文章正文内容 xff
  • solvepnp参数获取

    1 上参数 xff1a solvePnP 具体参数 xff1a objectPoints xff1a 特征点的世界坐标 xff08 3d点 xff09 xff0c 坐标值需为float型 xff0c 不能为double型 xff0c 可以为
  • 磁力计椭球拟合使用篇 IMU 加速度、电子罗盘校准

    磁力计校准椭球拟合使用篇 xff01 xff01 下方蓝色函数链接 xff01 xff01 matlab 椭球拟合函数链接 串口打印磁力计数据 xff0c 可以选择原始数据不进行任何缩放 xff08 前提是各轴向分辨率一致 xff09 sp
  • 数据结构与算法 — 希尔排序 和 快速排序

    目录 一 希尔排序 1 希尔排序的介绍 1 希尔排序的历史背景 2 插入排序的问题 3 希尔排序的做法 4 选择合适的增量 2 希尔排序的实现 3 希尔排序的效率 1 希尔排序的效率 2 Hibbard 增量序列 3 Sedgewick增量