【数据结构与算法】高级排序(希尔排序、归并排序、快速排序)完整思路,并用代码封装排序函数

USB2.0物理层实战:手把手教你用示波器抓取D+/D-信号(附波形分析) 本文是一份针对硬件工程师的USB2.0物理层信号调试实战指南。文章详细讲解了如何使用示波器捕获和分析D+/D-差分信号,从基础设置、核心信号状态解读,到信号完整性分析与常见问题排查,手把手教你定位USB通信故障。内容涵盖USB2.0协议物理层关键概念,并附有基础解码思路,旨在提升工程师的底层调试能力。 阅读详情

【数据结构与算法】高级排序(希尔排序、归并排序、快速排序)完整思路,并用代码封装排序函数

 

本系列文章【数据结构与算法】所有完整代码已上传 github,想要完整代码的小伙伴可以直接去那获取,可以的话欢迎点个Star哦~下面放上跳转链接

本篇文章来讲解一下更高级的排序算法,顾名思义,它们的排序思想一定更复杂,效率也一定比简单排序更高。为了更方便地理解高级排序算法,还是建议大家先把简单排序了解清楚,因为高级排序也多少借鉴了简单排序的思想,下面放上文章链接

【数据结构与算法】简单排序(冒泡排序、选择排序、插入排序)完整思路,并用代码封装排序函数

那么就让我们来了解一下三种高级排序算法吧

 

排序算法——高级排序

 

一、希尔排序

希尔排序是插入排序的改进版本,弥补了插入排序在某些情况下的缺点。

例如,当长度为100的数组,前面有序区域的数组长度为80,此时我们用第81个数去跟前面有序区域的所有元素比较大小,但恰巧第81个数又是这100个数里最小的,它本应该在索引为1的位置,如图所示

在这里插入图片描述
本例中第81个数据的值为1,那么前面有序区域里的80个元素都要往后移动一个位置,这种情况就非常影响排序性能。

因此,我们就要想办法尽可能早点让小的值靠前,让大的值靠后,这样就能避免上述情况了,这就是希尔排序要解决的问题。

希尔排序也叫做缩小增量排序,它通过先设置一个增量n,大小为数组长度的一半,将间隔为n的元素视作一个组,然后对每个组内部的元素进行从小到大进行插入排序;然后再将增量n缩小一半,再次进行分组插入排序,直到增量n为1,因为增量为1的时候,所有的元素都为同一个组了


为了方便大家理解,我用一个例子来展示一个完整的希尔排序过程,首先数据的初始状态如图所示,这里为了更好地体现希尔排序的优点,我特地把值较大的元素放到了靠左的位置,把值较小的元素放到了靠右的位置

在这里插入图片描述
该数组长度为8,因此我们设置初始的增量为 8 / 2 = 4,那么该数组的分组情况如下图所示:

在这里插入图片描述
图中颜色相同的元素为一组,每组内的各个元素间隔都为4,现在对每个组内进行从小到大排序,排序结果如下图所示:

在这里插入图片描述
此时我们将增量缩小一半,即 4 / 2 = 2,同样的,现在将所有元素重新组合,把所有间隔为2的元素视作一组,分组结果如下图所示:

在这里插入图片描述

图中颜色相同的元素为一组,每组内的各个元素间隔都为2,现在对每个组内进行从小到大排序,排序结果如下图所示:

在这里插入图片描述
我们继续将增量缩小一半,即 2 / 2 = 1,同样的,现在将所有元素重新组合,把所有间隔为1的元素视作一组,此时所有的元素都为同一组了,就相当于对所有的数据进行普通的插入排序,我们可以看到,对比最开始的数据,总得来说,小的值都比较靠左了,大的值也都比较靠右了,这样排序起来效率就很高了。结果如下图所示:

在这里插入图片描述

接下来用一个动图,演示一下完整的希尔排序全过程

在这里插入图片描述
了解完了希尔排序的实现过程,我们现在用代码来封装一下

function shellSort(arr) {
    // 1. 获取数组长度
    let length = arr.length

    // 2.获取初始的间隔长度
    let interval = Math.floor(length / 2)

    // 3. 不断地缩小间隔的大小,进行分组插入排序
    while(interval >= 1) {

        // 4. 从 arr[interval] 开始往后遍历,将遍历到的数据与其小组进行插入排序
        for(let i = interval; i < length; i++) {
            let temp = arr[i]
            let j = i
            while(arr[j - interval] > temp && j - interval >= 0) {
                arr[j] = arr[j - interval]
                j -= interval 
            }

            arr[j] = temp           
        }

        // 5. 缩小间隔
        interval = Math.floor(interval / 2)
    }

    return arr
}

来用刚才举得例子来验证一下我们封装的希尔排序是否正确

let arr = [63, 76, 13, 44, 91, 8, 82, 3]
let res = shellSort(arr)
console.log(res)
/* 打印结果
[3, 8, 13, 44, 63, 76, 82, 91]
*/

上述情况中,希尔排序最坏情况下的时间复杂度为O(n²)。其实希尔排序的时间复杂度跟增量也有关系,我们上面是通过数组长度一直取一半获取的增量,其实还有一些别的增量规则,可以使得希尔排序的效率更高,例如Hibbard增量序列、Sedgewick增量序列,本文就不对这两种增量做过多的讲解了,大家可以去网上搜索一下。

二、归并排序

归并排序的实现是使用了一种分而治之的思想,即将一个数组不断地通过两两分组的方式进行比较大小,最后直到所有元素都被分到一组里,那自然就是整体有序的了。

我们来看一下归并排序的主要思路,首先有如下图所示排列的一组数据:

在这里插入图片描述
首先从左往右,每两个元素视为一组,组合前要分别判断一下这两个元素的大小,小的在左,大的右,如图所示

在这里插入图片描述
继续再取两个元素组成一组并比较大小,如图所示:

在这里插入图片描述
继续上一个步骤,如图所示:

在这里插入图片描述
此时,原数组的所有元素都被两两分组完毕了,现在整个数组的长度变成了3,如下图所示:

在这里插入图片描述
此时,我们要重新从左向右,每次取两个元素组成一组,同时分别比较两个元素内的所有子元素的大小,因为此时的两个元素内部是有序的,所以我们比较两者大小的话,只需要每次比较数组的第一个元素即可,过程如下图所示:

在这里插入图片描述
此时原数组中只剩下一个元素了,所以就不对其做任何组合处理了,此时的数组是这样的:

在这里插入图片描述
此时的数组内只有两个元素了,所以我们只需要不断比较两个元素内部的子元素大小,即可获得完整的有序数组了,过程如下图所示:

在这里插入图片描述
这就是一个完整的归并排序的过程,接下来我们用代码来实现一下吧

function mergeSort(arr) {
    
    // 将所有元素不断地两两组合,直到所有元素都被组合成一个组
    while(arr.length > 1){
        // 获取一下遍历前的数组长度,方便下面判断需要组合几次
        let length = arr.length
        
        // 创建空的新数组,用于存放所有组合后的元素
        let next_arr = []
        
        // 取两个元素进行组合,一共取 length / 2 次
        for(let i = 0; i < Math.floor(length / 2); i++){
            // 取出第一个元素
            let left = [].concat(arr.shift())
            // 取出第二个元素
            let right = [].concat(arr.shift())
            // 创建另一个新的空数组,用于存放组合后的所有元素
            let new_arr = []

            // 取两个数组中头部最小的值放到新数组中,直到一个数组为空
            while(left.length > 0 && right.length > 0){
                let min = left[0] > right[0]? right.shift() : left.shift()
                new_arr.push(min)
            }
            // 将合并好的数组添加到新的数组中
            next_arr.push(new_arr.concat(left.length == 0? right : left))
        }
        // 判断是否有一个未成组的数组
        if(arr.length == 1) next_arr.push(arr[0]);
        
        // 将所有组合后的元素构成的新数组作为下一次遍历的对象
        arr = next_arr
    }

    // 返回完整有序数组
    return arr[0]
}

我们来使用一下该方法,看看是否正确,为了方便大家理解,我在归并排序的函数里加了一条打印的代码,可以看到每次遍历后的数组情况,结果如下

let arr = [19, 97, 9, 17, 1, 8]
mergeSort(arr)

/* 打印结果:
第一次组合后:[ [ 19, 97 ], [ 9, 17 ], [ 1, 8 ] ]
第二次组合后:[ [ 9, 17, 19, 97 ], [ 1, 8 ] ]
第三次组合后:[ [ 1, 8, 9, 17, 19, 97 ] ]
*/

查看代码我们不难发现,归并排序运行起来非常得占内存,因为在组合的过程中,我们不断得在创建新的数组,然后又进行合并。但其比较次数却非常得少,只在每次合并元素时进行比较,因此归并排序的效率还是非常得高的。

三、快速排序

快速排序相信大家一定不陌生,就算没用过也一定听过,拥有这么大的名声,那么它的排序效率一定很高。而且快速排序也是面试中经常会被问到的,可能会让你当场手写哦~所以大家一定要掌握它的核心思想

快速排序也用到了分而治之的思想,它的实现思路非常得有意思:

  1. 先选一个元素作为基点pivot
  2. 将其余元素中所有比pivot小的值放到pivot的左边;将所有比pivot大的值放到pivot的右边
  3. 然后分别对pivot左边的所有元素、pivot右边的所有元素从步骤1开始排序依次,直到所有元素完整有序

思路看着很简单,那么我们来用一个例子具体看一下快速排序的全过程吧

首先有这样一组数据,如下图所示:

在这里插入图片描述
首先我们要选取一个元素作为基点pivot,最后排序完后,pivot左边的所有元素都是小于pivot的,右边的所有元素都是大于pivot的,因此我们希望的是尽量是两边平均一下,所以这里将采用一种方式寻找到一个大概的中点,即取数组两头的索引,分别为left 、right,再取一个中点 center,结果如下图:

在这里插入图片描述

然后在这三个元素中找到一个中等大小的值,并将其放到数组的开头位置,如下图所示:

在这里插入图片描述

到此,我们就可以将该数组的第一个元素作为此次遍历的基点pivot了,同时,我们将引入两个指针,即 i 和 j,分别指向 left 和 right,如图所示

在这里插入图片描述

接下来就可以进行遍历了,这里我们把遍历过程称为填坑法,因为现在我们取到了数组的第一个值为pivot,所以可以假设这个位置上没有元素了,留了一个坑,需要我们将别的元素填进来。所以我们要从指针 j 开始往右寻找到一个比pivot小的值,若找到了,则将找到的值填到坑里,但要注意的是,指针 j 不能找到 指针 i 的左边去,即当指针 j 与 指针 i 重合时就停止移动。

过程如下图所示:

在这里插入图片描述

此时我们可以看到,指针 j 找到了一个小于pivot的值 8,并将找到的值填到了坑里,那么此时指针 j 所指向的位置就留下了一个坑,又需要别的元素来填坑,所以此时我们就要让指针 i 向右找一个大于pivot的值,并将值填到坑里,同样的,指针 i 也不能找到指针 j 的右边,即当指针 i 与 指针 j 重合时就停止移动。

过程如下图所示:

在这里插入图片描述

指针 i 找到了一个大于pivot的值 97 并将其填到了坑里,此时指针 i 所在的位置就留下了一个坑,因此我们又要让指针 j 往左找小于pivot的值并填到坑里,过程如图所示:

在这里插入图片描述

紧接着,指针 i 又要向右找大于pivot的值,但是移动了两个位置都没有找到,并且此时指针 i 指针 j 重合了,此时我们只需要将pivot填入到坑里就实现了pivot左边的所有元素小于它,右边所有的元素都大于它了,如图所示:

在这里插入图片描述

接下来的操作,就是我们要单独对此时pivot的左边所有元素和右边的所有元素进行上述的一系列操作,就可以实现快速排序了。本例中的左右两边区域的元素个数都是小于等于3个的,因此直接将这几个值互相进行比较大小比较方便,过程如下图:

在这里插入图片描述

了解了快速排序的实现思路,我们来用代码来实现一下

function quickSort(arr) {
    // 两个数据进行交换
    function exchange(v1, v2) {
        let temp = arr[v1]
        arr[v1] = arr[v2]
        arr[v2] = temp
    }
    
    // 找到相对合适的元素放到数组索引为0的位置作为基点pivot
    function init(left, right) {
        let center = Math.floor((left + right) / 2)

        // 比较索引为left、center、right三个值的大小,从小到大排列
        if(arr[left] > arr[right]) exchange(left, right)
        if(arr[center] > arr[right]) exchange(center, right)
        if(arr[left] > arr[center]) exchange(left, center)

        // 判断数组长度是否大于3,若小于3,则数组已经排序好了,不需要做任何处理
        if(right - left > 2) exchange(left, center)
    }

    function quick(left, right) {
        init(left, right)
        // 若数组长度小于等于2,则不需要做任何操作了,因为init函数已经排序好了
        if(right - left <= 2) return;
        
        // 创建指针i和j,分别指向left和right
        let i = left
        let j = right
        // 将该数组区域的第一个元素作为基点pivot
        let pivot = arr[i]

        // 不断让指针i和j寻找合适的值填坑,直到两个指针重合
        while(i < j) {
            // 指针j不断向左找小于pivot的值,但指针j不能找到指针i的左边
            while(arr[j] > pivot && j > i) {
                j --
            }
            // 将找到的小于pivot的值填到指针i所指向的坑中
            arr[i] = arr[j]

            // 指针i不断向右找大于pivot的值,但指针i不能找到指针j的右边
            while(arr[i] < pivot && i < j) {
                i ++
            }
            // 将找到的大于pivot的值填到指针j所指向的坑中
            arr[j] = arr[i]
        }

        // 将pivot填到指针i和指针j共同指向的坑中
        arr[i] = pivot

        // 对此时pivot的左边所有元素进行快排
        quick(left, i - 1)
        // 对此时pivot的右边所有元素进行快排
        quick(i + 1, right)
    }

    quick(0, arr.length - 1)

    return arr  
}

我们可以简单来验证一下快速排序的正确性

let arr = [19, 97, 9, 17, 8, 1]
console.log(quickSort(arr))
/* 打印结果为:
	[1, 8, 9, 17, 19, 97]
*/

四、结束语

排序算法中的高级排序(希尔排序、归并排序、快速排序)就已经讲完啦,下一篇文章为动态规划

大家可以关注我,之后我还会一直更新别的数据结构与算法的文章来供大家学习,并且我会把这些文章放到【数据结构与算法】这个专栏里,供大家学习使用。

然后大家可以关注一下我的微信公众号:Lpyexplore的编程小屋,等这个专栏的文章完结以后,我会把每种数据结构和算法的笔记放到公众号上,大家可以去那获取。

或者也可以去我的github上获取完整代码,欢迎大家点个Star

我是Lpyexplore,一个因Python爬虫而进入前端的探索者。创作不易,喜欢的加个关注,点个收藏,给个赞~

Autosar诊断实战系列05-Dcm之0x27加解密服务配置开发详解 UDS 0x27服务实战开发介绍,对解锁尝试次数及delay时间进一步解释。 阅读详情

相关推荐

树莓派4B串口舵机控制全攻略:从pigpio库安装到Python脚本调试

本文详细介绍了如何在树莓派4B上通过pigpio库和Python脚本实现串口舵机的精确控制。从硬件串口配置、pigpio库安装到舵机通信协议解析和Python脚本开发,提供了完整的解决方案和调试技巧,适用于机械臂控制等实际项目应用。

k8s6orchestrator的博客 429

四个高级排序算法

一、希尔排序 希尔排序是插入排序算法的一个改进,比如[5,4,3,2,1,0]这种倒序序列,数组末端的0要回到首位置很是费劲。希尔排序是通过自定义控制增量来将一组数据分成若干组,对每个组内元素先进行插入排序,然后再控制增量变小使每个组内的元素越来越多,当增量减小至1时,算法终止,排序就完成了。 比如[5,4,3,2,1]如果直接用插入排序,外层循环会从4开始以增量1一步步扩大有序序列。 而使用希尔排序,我们可以控制增量gap = arr.length/2 = 5/2 = 2 . 那么 最终会将此数据分

鱼儿往上游的博客 659

别再手动拷贝文件了!用Keil MDK的Pack Installer一键搞定STM32上的RT-Thread Nano移植

本文详细介绍了如何使用Keil MDK的Pack Installer一键快速移植RT-Thread Nano到STM32项目,告别繁琐的手动拷贝和配置过程。通过自动化版本管理和依赖处理,移植时间从47分钟缩短至3分钟,大幅提升开发效率。文章还提供了实战步骤、高级配置技巧和常见问题解决方案,帮助开发者轻松实现RTOS集成。

weixin_29194817的博客 363

Java 数据结构和算法(九):高级排序

Java数据结构和算法(九)——高级排序   在Java数据结构和算法(三)——冒泡、选择、插入排序算法中我们介绍了三种简单的排序算法,它们的时间复杂度大O表示法都是O(N2),如果数据量少,我们还能忍受,但是数据量大,那么这三种简单的排序所需要的时间则是我们所不能接受的。接着我们在讲解递归的时候,介绍了归并排序,归并排序需要O(NlogN),这比简单排序要快了很多,但是归并排序有个缺点,它需要的空间是原始数组空间的两倍,当我们需要排序的数据占据了整个内存的一半以上的空间,那么是不能使用...

dd2016124的博客 414

【文献阅读笔记】之基于注意力机制的深度学习路面裂缝检测

中文,计算机辅助设计与图形学学报,第 32 卷 第 8 期,2020 年 8 月。 DOI: 10.3724/SP.J.1089.2020.18059 摘要: 为实现自动准确地检测路面裂缝, 提升路面裂缝检测效果, 提出了一种基于注意力机制的裂缝检测网络 (attention-based crack networks, ACNet). 该网络采用编码器-解码器网络构架, 编码器采用 ResNet34 为骨干网, 提取路面裂缝特征; 在编码器和解码器间加入基于注意力机制的特征模块(attention-b

qq_44785998的博客 7592

PnP 单目相机位姿估计(二):solvePnP利用二维码求解相机世界坐标

前言 原理简介 输入参数准备 1 objectPoints特征点世界坐标 2 imagePoints特征点在摄像头下的像素点坐标 3cameraMatrixdistCoeffs内参矩阵和畸变矩阵 相机世界坐标的求解 1求世界坐标中的点在相机坐标系下的坐标 2求相机在世界坐标中的坐标 3效果求解相机在世界坐标系下的坐标点 4求解代码1.前言  很多时候,当我们利用单目相机获取图像时,往往只能获取图像中

cocoaqin的博客 5万+

【数据结构-C语言】快速排序,希尔排序

快排是一种递归思想的排序算法,先比较其他的排序算法,它需要更多内存空间,但快排的语句频度是最低的,理论上时间效率是最高的。 快速排序的基本思路是:在待排序序列中随便选取一个数据,作为所谓“支点”,然后所有其他的数据与之比较,以从小到大排序为例,那么比支点小的统统放在其左边,比支点大的统统放在其右边,全部比完之后,支点将位与两个序列的中间,这叫做一次划分(partition)。

sakura0908的博客 382

Modbus4J vs EasyModbus4J:哪个Java库更适合你的工业项目?

本文深入对比了Java领域两大Modbus通信库Modbus4J与EasyModbus4J。Modbus4J设计稳健、类型安全,适合复杂业务集成;EasyModbus4J基于Netty,在高并发场景下性能更优。文章从架构、性能、API及生产环境多维度分析,为工业物联网项目选型提供决策依据。

weixin_28475533的博客 309

快速排序和希尔排序

title: “快速排序和希尔排序” author: Sun-Wind date: January 2, 2021 背景:复习使用 快速排序 思想和时间复杂度 快速排序是由东尼·霍尔所发展的一种排序算法。 在平均状况下,排序 n 个项目要 Ο(nlogn) 次比较。在最坏状况下则需要 Ο(n2) 次比较,但这种状况并不常见。 快速排序又是一种分而治之思想在排序算法上的典型应用。 虽然 Worst Case 的时间复杂度达到了 O(n²),但是在大多数情况下都比平均时间复杂度为 O(n logn) 的排.

qq_52537838的博客 773

解决国内网页无法加载reCaptcha的方法

科普: reCaptcha是Google公司的验证码服务,方便快捷,改变了传统验证码需要输入n位失真字符的特点。reCaptcha在使用的时候是这样的: 只需要点一下复选框,Google会收集一些鼠标轨迹、网络信息、浏览器信息等等,依靠后端的神经网络判断是机器还是人,绝大多数验证会一键通过,无需像传统验证码一样。但是reCaptcha使用了google.com的域名,这个域名在国内是被墙的。所以,也就导致了官网上无法注册/登录的问题,挡住了不少人入正的脚步。 解决办法: 【第一步】安装fir

调皮李小怪博客 25万+

Vue Print Designer——一款让打印模板的设计变简单的可视化打印设计器

Vue Print Designer——一款让打印模板的设计变简单的可视化打印设计器

bjzhang75的博客 682

十大经典排序算法详解(二)希尔排序,归并排序,快速排序

十大经典排序算法-希尔排序,归并排序,快速排序 1-希尔排序 算法思想: 算法图解: 示例代码: 在这里插入代码片 复杂度分析: 2-归并排序 算法思想: 算法图解: 示例代码: 在这里插入代码片 复杂度分析: 3-快速排序 算法思想: 算法图解: 示例代码: 在这里插入代码片 复杂度分析: ...

lovely__RR的博客 3117

【微服务】SpringBoot 对接飞书审批流程使用详解

SpringBoot 对接飞书审批流程使用详解

congge_study的博客 3767

【七大排序算法】插入排序、希尔排序、选择排序、冒泡排序、堆排序、快速排序、归并排序

所谓排序,就是把一堆杂乱的数据,排成升序或降序(递增/增减)。假设一组数据[1,2,9,5,5,6,8],进行升序排序后,两个5的相应位置不发生改变,即称为稳定的排序,否则就是不稳定排序。数据元素全部放在内存中进行排序。即将待排序的记录存储在外存中,排序时再把数据一部分一部分地调入内存进行排序,在排序过程中需要多次进行内存和外存之间地交换。

Original0的博客 3623

深度学习工具包 DeepLearningToolbox

深度学习工具包Deprecation notice.-----This toolbox is outdated and no longer maintained.There are much better tools available for deep learning than this toolbox, e.g. [Theano](http://deeplearning.net/software/theano/), [torch](http://torch.ch/) or [tensorflow](http://www.tensorflow.org/)I would suggest you use one of the tools mentioned above rather than use this toolbox.Best, Rasmus.DeepLearnToolbox================A Matlab toolbox for Deep Learning.Deep Learning is a new subfield of machine learning that focuses on learning deep hierarchical models of data.It is inspired by the human brain's apparent deep (layered, hierarchical) architecture.A good overview of the theory of Deep Learning theory is[Learning Deep Architectures for AI](http://www.iro.umontreal.ca/~bengioy/papers/ftml_book.pdf)For a more informal introduction, see the following videos by Geoffrey Hinton and Andrew Ng.* [The Next Generation of Neural Networks](http://www.youtube.com/watch?v=AyzOUbkUf3M) (Hinton, 2007)* [Recent Developments in Deep Learning](http://www.youtube.com/watch?v=VdIURAu1-aU) (Hinton, 2010)* [Unsupervised Feature Learning and Deep Learning](http://www.youtube.com/watch?v=ZmNOAtZIgIk) (Ng, 2011)If you use this toolbox in your research please cite [Prediction as a candidate for learning deep hierarchical models of data](http://www2.imm.dtu.dk/pubdb/views/publication_details.php?id=6284)```@MASTERSTHESIS\{IMM2012-06284, author = "R. B. Palm", title = "Prediction as a candidate for learning deep hierarchical models of data", year = "2012",}```Contact: rasmusbergpalm at gmail dot comDirectories included in the toolbox-----------------------------------`NN/` - A library for Feedforward Backpropagation Neural Networks`CNN/` - A library for Convolutional Neural Networks`DBN/` - A library for Deep Belief Networks`SAE/` - A library for Stacked Auto-Encoders`CAE/` - A library for Convolutional Auto-Encoders`util/` - Utility functions used by the libraries`data/` - Data used by the examples`tests/` - unit tests to verify toolbox is workingFor references on each library check REFS.mdSetup-----1. Download.2. addpath(genpath('DeepLearnToolbox'));Example: Deep Belief Network---------------------```matlabfunction test_example_DBNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit RBM and visualize its weightsrand('state',0)dbn.sizes = [100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);figure; visualize(dbn.rbm{1}.W'); % Visualize the RBM weights%% ex2 train a 100-100 hidden unit DBN and use its weights to initialize a NNrand('state',0)%train dbndbn.sizes = [100 100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);%unfold dbn to nnnn = dbnunfoldtonn(dbn, 10);nn.activation_function = 'sigm';%train nnopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.10, 'Too big error');```Example: Stacked Auto-Encoders---------------------```matlabfunction test_example_SAEload mnist_uint8;train_x = double(train_x)/255;test_x = double(test_x)/255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit SDAE and use it to initialize a FFNN% Setup and train a stacked denoising autoencoder (SDAE)rand('state',0)sae = saesetup([784 100]);sae.ae{1}.activation_function = 'sigm';sae.ae{1}.learningRate = 1;sae.ae{1}.inputZeroMaskedFraction = 0.5;opts.numepochs = 1;opts.batchsize = 100;sae = saetrain(sae, train_x, opts);visualize(sae.ae{1}.W{1}(:,2:end)')% Use the SDAE to initialize a FFNNnn = nnsetup([784 100 10]);nn.activation_function = 'sigm';nn.learningRate = 1;nn.W{1} = sae.ae{1}.W{1};% Train the FFNNopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.16, 'Too big error');```Example: Convolutional Neural Nets---------------------```matlabfunction test_example_CNNload mnist_uint8;train_x = double(reshape(train_x',28,28,60000))/255;test_x = double(reshape(test_x',28,28,10000))/255;train_y = double(train_y');test_y = double(test_y');%% ex1 Train a 6c-2s-12c-2s Convolutional neural network %will run 1 epoch in about 200 second and get around 11% error. %With 100 epochs you'll get around 1.2% errorrand('state',0)cnn.layers = { struct('type', 'i') %input layer struct('type', 'c', 'outputmaps', 6, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %sub sampling layer struct('type', 'c', 'outputmaps', 12, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %subsampling layer};cnn = cnnsetup(cnn, train_x, train_y);opts.alpha = 1;opts.batchsize = 50;opts.numepochs = 1;cnn = cnntrain(cnn, train_x, train_y, opts);[er, bad] = cnntest(cnn, test_x, test_y);%plot mean squared errorfigure; plot(cnn.rL);assert(er<0.12, 'Too big error');```Example: Neural Networks---------------------```matlabfunction test_example_NNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);% normalize[train_x, mu, sigma] = zscore(train_x);test_x = normalize(test_x, mu, sigma);%% ex1 vanilla neural netrand('state',0)nn = nnsetup([784 100 10]);opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samples[nn, L] = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.08, 'Too big error');%% ex2 neural net with L2 weight decayrand('state',0)nn = nnsetup([784 100 10]);nn.weightPenaltyL2 = 1e-4; % L2 weight decayopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex3 neural net with dropoutrand('state',0)nn = nnsetup([784 100 10]);nn.dropoutFraction = 0.5; % Dropout fraction opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex4 neural net with sigmoid activation functionrand('state',0)nn = nnsetup([784 100 10]);nn.activation_function = 'sigm'; % Sigmoid activation functionnn.learningRate = 1; % Sigm require a lower learning rateopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex5 plotting functionalityrand('state',0)nn = nnsetup([784 20 10]);opts.numepochs = 5; % Number of full sweeps through datann.output = 'softmax'; % use softmax outputopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex6 neural net with sigmoid activation and plotting of validation and training error% split training data into training and validation datavx = train_x(1:10000,:);tx = train_x(10001:end,:);vy = train_y(1:10000,:);ty = train_y(10001:end,:);rand('state',0)nn = nnsetup([784 20 10]); nn.output = 'softmax'; % use softmax outputopts.numepochs = 5; % Number of full sweeps through dataopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, tx, ty, opts, vx, vy); % nntrain takes validation set as last two arguments (optionally)[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');```[![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/rasmusbergpalm/deeplearntoolbox/trend.png)](https://bitdeli.com/free "Bitdeli Badge")

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

【数据结构】排序合集(直接插入排序、希尔排序、冒泡排序、堆排序、选择排序、快速排序、归并排序、计数排序)

完希望这篇小小文章可以为你解答疑惑!若上述文章有什么错误,欢迎各位大佬及时指出,我们共同进步!

2401_85054434的博客 1483

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

高级排序之希尔排序,归并排序,快速排序详解

Java学习+面试指南:https://javaxiaobear.cn。

Java全能学习+面试指南 1418

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

数据结构实验——实现希尔排序的算法、实现快速排序的算法、实现堆排序的算法

partition(RecType R[],ints,int t):对 R[s..]元素进行一趟划分(以该区间中第一个元素为基准)。·Sift(RecType R[],int low,int high):对R[low .. high」进行堆筛选的算法。·QuickSort(RecType R[],int s,intt):对 R[s..]的元素进行递增快速排序。·disppart(RecType R[],ints,int t):显示 R[s..t]划分后的结果。

u014114223的博客 1238

快速排序,归并排序,希尔排序,堆排序(讲解及C++实现)

算是学数据结构之前我对快速排序,希尔排序,归并排序和堆排序的一次总结

sbsbsb666666的博客 2250

七大排序算法,冒泡排序 选择排序 插入排序 希尔排序 堆排序 快速排序 归并排序的深度讲解

排序方法最好平均最坏空间复杂度稳定性冒泡排序O(n)O(n^2)O(n^2)O(1)稳定插入排序O(n)O(n^2)O(n^2)O(1)稳定选择排序O(n^2)O(n^2)O(n^2)O(1)不稳定希尔排序O(n)O(n^1.3)O(n^2)O(1)不稳定堆排序O(1)不稳定快速排序O(n^2)不稳定归并排序O(n)稳定。

m0_62747332的博客 2371

七大排序(插入排序,希尔排序,选择排序,堆排序,冒泡排序,快速排序,归并排序)

七大排序(插入排序,希尔排序,选择排序,堆排序,冒泡排序,快速排序,归并排序) 1.插入排序:把待排序的记录按其关键码值的大小逐个插入到一个已经排好序的有序序列中,直到所有的记录插入完为止,得到一个新的有序序列 。 2.希尔排序:先选定一个整数,把待排序文件中所有记录分成gap/2个组,所有距离为的记录分在同一组内,并对每一组内的记录进行排序。然后取,重复上述分组和排序的工作。当到达gap...

gp1330782530的博客 3185

希尔排序和归并排序以及快速排序

高级排序 高级排序高级排序1.希尔排序2.归并排序3.快速排序4.快速排序和归并排序的区别5.几种快速排序的测试6.排序的稳定性 所谓高级排序就是在比时间复杂度上比简单排序更快一点,尤其是排序数量大时,排序起来耗费时间少,这是最根本的,常见的简单排序中冒泡排序,选择排序,插入排序,它们的时间复杂度都是O(N^2),而高级排序,希尔排序,归并排序,和选择排序的时间复杂度要小一点,可以更好的提高效率。 1.希尔排序 希尔排序是插入排序的一种,又称“缩小增量排序”,是插入排序算法的一种更高效的改进版本。 选

m0_53048901的博客 1159

数据结构与算法 3.高级排序(希尔排序) 后续补充快速排序

文章目录前言一. 希尔排序1.1 排序原理1.2 希尔排序api设计和代码实现1.3 测试1.4 希尔排序的时间复杂度分析二.2.12.22.3三.3.13.23.3 前言 冒泡排序,选择排序、插入排序,在最坏情况下的时间复杂度都是O(N^2),随着输入规模的增大,时间成本将急剧上升,所以冒泡排序,选择排序、插入排序不能处理大规模的问题 一. 希尔排序 1.1 排序原理 希尔排序是插入排序的一种,是插入排序算法的一种更高效的改进版本。    1.选定一个增长量h,按照增长量h作为数据分组的依据,对数据进

不是一枚开发 5万+

数据结构与算法学习十二:希尔排序、快速排序(递归、好理解)、归并排序(递归、难理解)

文章目录前言一、希尔排序1.1 简单插入排序存在的问题1.2 基本介绍1.3 思路分析1.4 代码实现1.5 测试结果二、快速排序2.1 基本介绍2.2 思路分析2.3 代码实现2.4 测试结果三、归并排序3.1 基本介绍3.2 思路分析3.3 代码实现3.4 测试结果 前言 上节的三个排序算法:冒泡、选择、插入,较为简单,好理解,使用比较、交换的思想。但也都是基础。 这节的三个排序算法:希尔、...

冯安晨 954

[排序]选择排序、冒泡排序、插入排序、希尔排序、归并排序、快速排序、堆排序算法及比较

[排序]选择排序、冒泡排序、插入排序、希尔排序、归并排序、快速排序、堆排序算法及比较 1.选择排序     从数组中选择最小的元素,将它与数组的第一个元素交换位置,再讲数组剩下的元素中选择最小的元素,将它与数组的第二个元素交换位置,重复操作,直到将整个数组排序。 选择排序需要N2/2次比较和N次交换,对已经排序的数组也需要这么多次比较和交换操作。 public void sort(int[] nums) { int len=nums.length(); for(

何猫七的博客 1168

排序算法(希尔排序、归并排序、快速排序、堆排序)、KMP算法

1、希尔排序 1.1排序原理 文字 图解 1.2代码实现 在这里插入代码片 int shell_sort(int* data, int length) { int gap = 0; int temp; int i = 0, j = 0; for (gap = length / 2; gap >= 1; gap /= 2) { //分组 对应步长 for (i = gap; i < length; i++) { temp = data[i]; //用临时变量存储

weixin_44416814的博客 1166

希尔排序、快速排序、归并排序的实现分析以及时间复杂度

我在另一篇文章中说插入排序的时候,会有一个不太好的现象,如果已排序的分组元素为{2,5,7,9,10},未排序的分组 元素为{1,8},那么下一个待插入元素为1,我们需要拿着1从后往前,依次和10,9,7,5,2进行交换位置,才能完成真 正的插入,每次交换只能和相邻的元素交换位置。希尔排序是按照不同步长对元素进行插入排序 ,虽然一次插入排序是稳定的,不会改变相同元素的相对顺序,但在不同的插入排序过程中,相同的元素可能在各自的插入排序中移动,最后其稳定性就会被打乱,所以希尔排序是不稳定的。

何冽冽的博客 2300
上一篇: 【数据结构与算法】简单排序(冒泡排序、选择排序、插入排序)完整思路,并用代码封装排序函数
下一篇: mysql重点知识详解
Java_2017_csdn
博客等级 码龄10年 329粉丝 49原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值