HOME 首页
SERVICE 服务产品
XINMEITI 新媒体代运营
CASE 服务案例
NEWS 热点资讯
ABOUT 关于我们
CONTACT 联系我们
创意岭
让品牌有温度、有情感
专注品牌策划15年

    nlogn的排序(nlogn的排序口诀)

    发布时间:2023-04-08 05:19:48     稿源: 创意岭    阅读: 131        

    大家好!今天让创意岭的小编来大家介绍下关于nlogn的排序的问题,以下是小编对此问题的归纳整理,让我们一起来看看吧。

    开始之前先推荐一个非常厉害的Ai人工智能工具,一键生成原创文章、方案、文案、工作计划、工作报告、论文、代码、作文、做题和对话答疑等等

    只需要输入关键词,就能返回你想要的内容,越精准,写出的就越详细,有微信小程序端、在线网页版、PC客户端

    官网:https://ai.de1919.com

    创意岭作为行业内优秀的企业,服务客户遍布全球各地,如需了解SEO相关业务请拨打电话175-8598-2043,或添加微信:1454722008

    本文目录:

    nlogn的排序(nlogn的排序口诀)

    一、排序算法概述

    十大排序算法:冒泡排序,选择排序,插入排序,归并排序,堆排序,快速排序、希尔排序、计数排序,基数排序,桶排序

    稳定 :如果a原本在b前面,而a=b,排序之后a仍然在b的前面;

    不稳定 :如果a原本在b的前面,而a=b,排序之后a可能会出现在b的后面;

    排序算法如果是稳定的,那么从一个键上排序,然后再从另一个键上排序,前一个键排序的结果可以为后一个键排序所用。

    算法的复杂度往往取决于数据的规模大小和数据本身分布性质。

    时间复杂度 : 一个算法执行所耗费的时间。

    空间复杂度 :对一个算法在运行过程中临时占用存储空间大小的量度。

    常见复杂度由小到大 :O(1) < O(logn) < O(n) < O(nlogn) < O(n^2) < O(n^3) < O(2^n)

    在各种不同算法中,若算法中语句执行次数(占用空间)为一个常数,则复杂度为O(1);

    当一个算法的复杂度与以2为底的n的对数成正比时,可表示为O(log n);

    当一个算法的复杂度与n成线性比例关系时,可表示为O (n),依次类推。

    冒泡、选择、插入排序需要两个for循环,每次只关注一个元素,平均时间复杂度为

    (一遍找元素O(n),一遍找位置O(n))

    快速、归并、堆基于分治思想,log以2为底,平均时间复杂度往往和O(nlogn)(一遍找元素O(n),一遍找位置O(logn))相关

    而希尔排序依赖于所取增量序列的性质,但是到目前为止还没有一个最好的增量序列 。例如希尔增量序列时间复杂度为O(n²),而Hibbard增量序列的希尔排序的时间复杂度为 , 有人在大量的实验后得出结论;当n在某个特定的范围后希尔排序的最小时间复杂度大约为n^1.3。

    从平均时间来看,快速排序是效率最高的:

    快速排序中平均时间复杂度O(nlog n),这个公式中隐含的常数因子很小,比归并排序的O(nlog n)中的要小很多,所以大多数情况下,快速排序总是优于合并排序的。

    而堆排序的平均时间复杂度也是O(nlog n),但是堆排序存在着重建堆的过程,它把根节点移除后,把最后的叶子结点拿上来后需要重建堆,但是,拿上的值是要比它的两个叶子结点要差很多的,一般要比较很多次,才能回到合适的位置。堆排序就会有很多的时间耗在堆调整上。

    虽然快速排序的最坏情况为排序规模(n)的平方关系,但是这种最坏情况取决于每次选择的基准, 对于这种情况,已经提出了很多优化的方法,比如三取样划分和Dual-Pivot快排。

    同时,当排序规模较小时,划分的平衡性容易被打破,而且频繁的方法调用超过了O(nlog n)为

    省出的时间,所以一般排序规模较小时,会改用插入排序或者其他排序算法。

    一种简单的排序算法。它反复地走访过要排序的数列,一次比较两个元素,如果它们的顺序错误就把它们交换过来。这个工作重复地进行直到没有元素再需要交换,也就是说该数列已经排序完成。这个算法的名字由来是因为元素会经由交换慢慢“浮”到数列的顶端。

    1.从数组头开始,比较相邻的元素。如果第一个比第二个大(小),就交换它们两个;

    2.对每一对相邻元素作同样的工作,从开始第一对到尾部的最后一对,这样在最后的元素应该会是最大(小)的数;

    3.重复步骤1~2,重复次数等于数组的长度,直到排序完成。

    首先,找到数组中最大(小)的那个元素;

    其次,将它和数组的第一个元素交换位置(如果第一个元素就是最大(小)元素那么它就和自己交换);

    再次,在剩下的元素中找到最大(小)的元素,将它与数组的第二个元素交换位置。如此往复,直到将整个数组排序。

    这种方法叫做选择排序,因为它在不断地选择剩余元素之中的最大(小)者。

    对于未排序数据,在已排序序列中从后向前扫描,找到相应位置并插入。

    为了给要插入的元素腾出空间,我们需要将插入位置之后的已排序元素在都向后移动一位。

    插入排序所需的时间取决于输入中元素的初始顺序。例如,对一个很大且其中的元素已经有序(或接近有序)的数组进行排序将会比对随机顺序的数组或是逆序数组进行排序要快得多。

    总的来说,插入排序对于部分有序的数组十分高效,也很适合小规模数组。

    一种基于插入排序的快速的排序算法。简单插入排序对于大规模乱序数组很慢,因为元素只能一点一点地从数组的一端移动到另一端。例如,如果主键最小的元素正好在数组的尽头,要将它挪到正确的位置就需要N-1 次移动。

    希尔排序为了加快速度简单地改进了插入排序,也称为缩小增量排序,同时该算法是突破O(n^2)的第一批算法之一。

    希尔排序是把待排序数组按一定数量的分组,对每组使用直接插入排序算法排序;然后缩小数量继续分组排序,随着数量逐渐减少,每组包含的元素越来越多,当数量减至 1 时,整个数组恰被分成一组,排序便完成了。这个不断缩小的数量,就构成了一个增量序列。

    在先前较大的增量下每个子序列的规模都不大,用直接插入排序效率都较高,尽管在随后的增量递减分组中子序列越来越大,由于整个序列的有序性也越来越明显,则排序效率依然较高。

    从理论上说,只要一个数组是递减的,并且最后一个值是1,都可以作为增量序列使用。有没有一个步长序列,使得排序过程中所需的比较和移动次数相对较少,并且无论待排序列记录数有多少,算法的时间复杂度都能渐近最佳呢?但是目前从数学上来说,无法证明某个序列是“最好的”。

    常用的增量序列

    希尔增量序列 :{N/2, (N / 2)/2, ..., 1},其中N为原始数组的长度,这是最常用的序列,但却不是最好的

    Hibbard序列:{2^k-1, ..., 3,1}

    Sedgewick序列:{... , 109 , 41 , 19 , 5,1} 表达式为

    归并排序是建立在归并操作上的一种有效的排序算法。该算法是采用分治法的一个非常典型的应用。

    对于给定的一组数据,利用递归与分治技术将数据序列划分成为越来越小的半子表,在对半子表排序后,再用递归方法将排好序的半子表合并成为越来越大的有序序列。

    为了提升性能,有时我们在半子表的个数小于某个数(比如15)的情况下,对半子表的排序采用其他排序算法,比如插入排序。

    若将两个有序表合并成一个有序表,称为2-路归并,与之对应的还有多路归并。

    快速排序(Quicksort)是对冒泡排序的一种改进,也是采用分治法的一个典型的应用。

    首先任意选取一个数据(比如数组的第一个数)作为关键数据,我们称为基准数(Pivot),然后将所有比它小的数都放到它前面,所有比它大的数都放到它后面,这个过程称为一趟快速排序,也称为分区(partition)操作。

    通过一趟快速排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数组变成有序序列。

    为了提升性能,有时我们在分割后独立的两部分的个数小于某个数(比如15)的情况下,会采用其他排序算法,比如插入排序。

    基准的选取:最优的情况是基准值刚好取在无序区数值的中位数,这样能够最大效率地让两边排序,同时最大地减少递归划分的次数,但是一般很难做到最优。基准的选取一般有三种方式,选取数组的第一个元素,选取数组的最后一个元素,以及选取第一个、最后一个以及中间的元素的中位数(如4 5 6 7, 第一个4, 最后一个7, 中间的为5, 这三个数的中位数为5, 所以选择5作为基准)。

    Dual-Pivot快排:双基准快速排序算法,其实就是用两个基准数, 把整个数组分成三份来进行快速排序,在这种新的算法下面,比经典快排从实验来看节省了10%的时间。

    许多应用程序都需要处理有序的元素,但不一定要求他们全部有序,或者不一定要一次就将他们排序,很多时候,我们每次只需要操作数据中的最大元素(最小元素),那么有一种基于二叉堆的数据结构可以提供支持。

    所谓二叉堆,是一个完全二叉树的结构,同时满足堆的性质:即子结点的键值或索引总是小于(或者大于)它的父节点。在一个二叉堆中,根节点总是最大(或者最小)节点。

    堆排序算法就是抓住了这一特点,每次都取堆顶的元素,然后将剩余的元素重新调整为最大(最小)堆,依次类推,最终得到排序的序列。

    推论1:对于位置为K的结点 左子结点=2 k+1 右子结点=2 (k+1)

    验证:C:2 2 2+1=5 2 (2+1)=6

    推论2:最后一个非叶节点的位置为 (N/2)-1,N为数组长度。

    验证:数组长度为6,(6/2)-1=2

    计数排序对一定范围内的整数排序时候的速度非常快,一般快于其他排序算法。但计数排序局限性比较大,只限于对整数进行排序,而且待排序元素值分布较连续、跨度小的情况。

    计数排序是一个排序时不比较元素大小的排序算法。

    如果一个数组里所有元素都是整数,而且都在0-K以内。对于数组里每个元素来说,如果能知道数组里有多少项小于或等于该元素,就能准确地给出该元素在排序后的数组的位置。

    桶排序 (Bucket sort)的工作的原理:假设输入数据服从均匀分布,利用某种函数的映射关系将数据分到有限数量的桶里,每个桶再分别排序(有可能再使用别的排序算法或是以递归方式继续使用桶排序)。

    桶排序利用函数的映射关系,减少了几乎所有的比较工作。实际上,桶排序的f(k)值的计算,其作用就相当于快排中划分,已经把大量数据分割成了基本有序的数据块(桶)。然后只需要对桶中的少量数据做排序即可。

    常见的数据元素一般是由若干位组成的,比如字符串由若干字符组成,整数由若干位0~9数字组成。基数排序按照从右往左的顺序,依次将每一位都当做一次关键字,然后按照该关键字对数组排序,同时每一轮排序都基于上轮排序后的结果;当我们将所有的位排序后,整个数组就达到有序状态。基数排序不是基于比较的算法。

    基数是什么意思?对于十进制整数,每一位都只可能是0~9中的某一个,总共10种可能。那10就是它的基,同理二进制数字的基为2;对于字符串,如果它使用的是8位的扩展ASCII字符集,那么它的基就是256。

    基数排序 vs 计数排序 vs 桶排序

    基数排序有两种方法:

    MSD 从高位开始进行排序

    LSD 从低位开始进行排序

    这三种排序算法都利用了桶的概念,但对桶的使用方法上有明显差异:

    基数排序:根据键值的每位数字来分配桶

    计数排序:每个桶只存储单一键值

    桶排序:每个桶存储一定范围的数值

    有时,待排序的文件很大,计算机内存不能容纳整个文件,这时候对文件就不能使用内部排序了(我们一般的排序都是在内存中做的,所以称之为内部排序,而外部排序是指待排序的内容不能在内存中一下子完成,它需要做内外存的内容交换),外部排序常采用的排序方法也是归并排序,这种归并方法由两个不同的阶段组成:

    采用适当的内部排序方法对输入文件的每个片段进行排序,将排好序的片段(成为归并段)写到外部存储器中(通常由一个可用的磁盘作为临时缓冲区),这样临时缓冲区中的每个归并段的内容是有序的。

    利用归并算法,归并第一阶段生成的归并段,直到只剩下一个归并段为止。

    例如要对外存中4500个记录进行归并,而内存大小只能容纳750个记录,在第一阶段,我们可以每次读取750个记录进行排序,这样可以分六次读取,进行排序,可以得到六个有序的归并段

    每个归并段的大小是750个记录,并将这些归并段全部写到临时缓冲区(由一个可用的磁盘充当)内了,这是第一步的排序结果。

    完成第二步该怎么做呢?这时候归并算法就有用处了。

    二、快速排序算法在平均情况下的时间复杂度为 求详解

    时间复杂度为O(nlogn) n为元素个数

    1. 快速排序的三个步骤:

    1.1. 找到序列中用于划分序列的元素

    1.2. 用元素划分序列

    1.3. 对划分后的两个序列重复1,2两个步骤指导序列无法再划分

    所以对于n个元素其排序时间为

    T(n) = 2*T(n/2) + n (表示将长度为n的序列划分为两个子序列,每个子序列需要T(n/2)

    的时间,而划分序列需要n的时间)

    而 T(1) = 1 (表示长度为1的序列无法划分子序列,只需要1的时间即可)

    T(n) = 2^logn + logn * n (n被不断二分最终只能二分logn次(最优的情况,每次选取

    的元素都均分序列))

    = n + nlogn

    因此T(n) = O(nlogn)

    以上是最优情况的推导,因此快速排序在最优情况下其排序时间为O(nlogn),通常平均情况

    我们也认为是此值。

    在最坏情况下其会退化为冒泡排序,T(n) = T(n - 1) + n (每次选取的元素只能将序列划分为

    一段,即自身是 最小元素或最大元素)

    因此T(n) = n * (n-1) / 2 相当于O(n^2)

    三、o(1), o(n), o(logn), o(nlogn)

            由于平时接触算法比较少,今天看资料看到了o(1),都不知道是什么意思,查资料之后才理解。

            描述算法复杂度时,常用o(1), o(n), o(logn), o(nlogn)表示对应算法的时间复杂度,是算法的时空复杂度的表示。不仅仅用于表示时间复杂度,也用于表示空间复杂度。 

    O后面的括号中有一个函数,指明某个算法的耗时/耗空间与数据增长量之间的关系。其中的n代表输入数据的量。 

            比如时间复杂度为O(n),就代表数据量增大几倍,耗时也增大几倍。比如常见的遍历算法。再比如时间复杂度O(n^2),就代表数据量增大n倍时,耗时增大n的平方倍,这是比线性更高的时间复杂度。比如冒泡排序,就是典型的O(n^2)的算法,对n个数排序,需要扫描n×n次。 

            再比如O(logn),当数据增大n倍时,耗时增大logn倍(这里的log是以2为底的,比如,当数据增大256倍时,耗时只增大8倍,是比线性还要低的时间复杂度)。二分查找就是O(logn)的算法,每找一次排除一半的可能,256个数据中查找只要找8次就可以找到目标。 

            O(nlogn)同理,就是n乘以logn,当数据增大256倍时,耗时增大256*8=2048倍。这个复杂度高于线性低于平方。归并排序就是O(nlogn)的时间复杂度。 

            O(1)就是最低的时空复杂度了,也就是耗时/耗空间与输入数据大小无关,无论输入数据增大多少倍,耗时/耗空间都不变。 哈希算法就是典型的O(1)时间复杂度,无论数据规模多大,都可以在一次计算后找到目标(不考虑冲突的话)

    四、软件设计师考试 | 第三章 数据结构 | 排序

    假设含 n 个记录的文件内容为 {R1,R2,...,Rn} ,相应的关键字为 {k1,k2,...,kn} 。经过排序确定一种排列 {Rj1,Rj2,...,Rjn} ,使得它们的关键字满足以下递增(或递减)关系: kj1<=kj2<=...<=kjn(或kj1>=kj2>=...>=kjn) 。

    排序方法的稳定与不稳定:

    内部排序和外部排序:

    方法: 在插入第 i 个记录时, R1,R2,...,Ri-1 已经排好序,这时将 Ri 的关键字 ki 依次与关键字 ki-1,ki-2 等进行比较,从而找到应该插入的位置并将 Ri 插入,插入位置及其后的记录依次向后移动。

    直接插入排序 是一种 稳定 的排序方法 , 时间复杂度为O(n^2),空间复杂度为O(1)。

    方法: 首先将第一个记录的关键字和第二个记录的关键字进行比较,若为逆序,则交换这两个记录的值,然后比较第二个记录和第三个记录的关键字,依此类推,直到第 n-1 个记录和第 n 个记录的关键字比较过为止。上述过程称为第一趟冒泡排序,然后再进行多次冒泡排序,直到冒泡排序过程中没有进行相邻位置的元素交换处理为止。

    冒泡排序 是一种 稳定 的排序方法 , 时间复杂度为O(n^2),空间复杂度为O(1)。

    方法: 通过 n-i (1<=i<=n) 再次关键字之间的比较,从 n-i+1 个记录中选出关键字最小的记录,并和第 i 个记录进行交换,当 i 等于 n 时所有记录有序排列。

    简单选择排序 是一种 不稳定 的排序方法 , 时间复杂度为O(n^2),空间复杂度为O(1)。

    又称为“缩小增量排序”,它是对直接插入排序方法的改进。

    方法: 先将整个待排序记录分割成若干子序列,然后分别进行直接插入排序,待整个序列中的记录基本有序时,再对全体记录进行一次直接插入排序。具体做法是:先取一个小于 n 的整数 d1 作为第一个增量,把文件的全部记录分成 d1 个组,即将所有距离为 d1 倍数序号的记录放在同一个组中,在各组内进行直接插入排序;然后取第二个增量 d2 (d2<d1) ,重复上述分组和排序工作,依此类推,直到所取的增量 di=1 (di<di-1<...<dc<d1) ,即所有记录放在同一组进行直接插入排序为止。

    希尔排序 是一种 不稳定 的排序方法 , 时间复杂度为O(n^1.3),空间复杂度为O(1)。

    方法: 附设两个位置指示变量 i 和 j ,它们的初值分别指向序列的第一个记录和最后一个记录。设枢轴记录(通常是第一个记录)的关键字为 pivot ,则首先从 j 所指位置起向前搜索,找到第一个关键字小于 pivot 的记录时将记录向前移到 i 指示的位置,然后从 i 所指位置起向后搜索,找到第一个关键字大于 pivot 的记录时将该记录后移到 j 所指位置,重复该过程直至 i 与 j 相等为止。

    快速排序 是一种 不稳定 的排序方法 , 时间复杂度为O(nlogn),空间复杂度为O(logn)。

    方法: 对一组待排序记录的关键字,首先按堆的定义排成一个序列(即建立初始堆),从而可以输出堆顶的最大关键字(对于大根堆而言),然后将剩余的关键字再调整成新堆,便得到次大的关键字,如此反复,直到全部关键字排成有序序列为止。

    堆排序 是一种 不稳定 的排序方法 , 时间复杂度为O(nlogn),空间复杂度为O(1)。

    方法: 将两个或两个以上的有序文件合并成一个新的有序文件。实现方法是:把一个有 n 个记录的无序文件看成是由 n 个长度为 1 的有序子文件组成的文件,然后进行两两归并,得到 n/2 个长度为 2 或 1 的有序文件,再两两归并,如此重复,直到最后形成包含 n 个记录的有序文件为止。

    归并排序 是一种 稳定 的排序方法 , 时间复杂度为O(nlogn),空间复杂度为O(n)。

    方法: 设立 r 个队列,队列的编号分别为 0、1、2、...、r-1 。首先按最低有效位的值把 n 个关键字分配到这 r 个队列中;然后按照队列编号从小到大将各队列中的关键字依次收集起来;接着再按次低有效位的值把刚收集起来的关键字分配到 r 个队列中。重复上述分配和收集过程,直到按照最高有效位分配和收集。这样就得到一个从小到大有序的关键字序列。

    对于 n 个记录,执行一次分配和收集的时间为 O(n+r) 。如果关键字有 d 位,则要执行 d 便。所以总的运算时间为 O(d(n+r)) 。

    基数排序 是一种 稳定 的排序方法 , 时间复杂度为O(d(n+rd)),空间复杂度为O(rd)。

    各个排序方法的性能比较:

    外部排序是对大型文件的排序,待排序的记录存放在外存。

    常用的外部排序方法是归并排序。

    以上就是关于nlogn的排序相关问题的回答。希望能帮到你,如有更多相关问题,您也可以联系我们的客服进行咨询,客服也会为您讲解更多精彩的知识和内容。


    推荐阅读:

    fifaonline3队套排行榜(fifaonline3最强队套)

    chatGPT翻译语音(chat online翻译)

    win7删除winload如何恢复(win7系统删除的文件怎么找回)

    《景观设计要素》(景观设计要素包括哪几个方面)

    母婴品店十大排行榜(母婴品店十大排行榜最新)