分享好友 最新动态首页 最新动态分类 切换频道
数据结构6 - 排序算法
2024-12-29 12:34

排序也称排序算法(Sort Algorithm)排序是将数据,依指定的顺序进行排过程。

数据结构6 - 排序算法

在进行算法分析时,语句总的执行次数T(n)是关于问题规模n的函数,进而分析T(n)随n的变化情况并确定T(n)的数量级。算法的时间复杂度,也就是算法的时间度量,记作T(n)=O(f(n))。它表示随问题规模n的增大,算法执行时间的增长率和f(n)的增长率相同,称作算法的渐进时间复杂度,简称为时间复杂度。其中f(n)是问题规模n的某个函数。

1) 数阶O(1)

论代码执行了多少行,只要是没有循环等复杂结构,那这个代码的时间复杂度就都是O(1)

2) 对数阶

说明:在while循环里面,每次都将 i 乘以 2,乘完之后i 距离 n 就越来越近了。假设循环x次之后i 就大于 2 ,此时这个循环就退出了,也就是说 2 x 次方等于 n,那么 x = 就是说当循环  次以后,这个代码就结束了。因此这个代码的时间复杂度为O()  O() 的这个2 时间上是根据代码变化的i = i * 3 ,则是 O() .

3) 线性阶O(n)

说明:这段代码for循环里面的代码会执行n,因此它消耗的时间是随着n的变化而变化的,因此这类代码都可以用O(n)来表示它的时间复杂度

4) 线性对数阶

说明:线性对数阶O(nlogN) 其实非常容易理解,将时间复杂度为的代码循环n遍的话,那么它的时间复杂度就是 n * ,也就是

5) 方阶O()

说明:平方阶O(n²) 就更容易理解了,如果把 O(n) 的代码再嵌套循环一遍,它的时间复杂度就是 O(n²)这段代码其实就是嵌套了2n循环,它的时间复杂度就是 O(n*n),即  O(n²) 果将其中一层循环的n改成m那它的时间复杂度就变成了 O(m*n)

6) 方阶O()

7) k次方阶O()

8) 数阶O()

常见的算法时间复杂度由小到大依次为:O(1)O(n)O()O()O() O() ,随着问题规模n的不断增大,上述时间复杂度不断增大,算法的执行效率越

1均时间复杂度是指所有可能的输入实例均以等概率出现的情况下,该算法的运行时间

2坏情况下的时间复杂度称最坏时间复杂度。一般讨论的时间复杂度均是最坏情况下的时间复杂度。 这样做的原因是:最坏情况下的时间复杂度是算法在任何输入实例上运行时间的界限,这就保证了算法的运行时间不会比最坏情况更长

3平均时间复杂度和坏时间复杂度否一致,和算法有关(如下图)

相关术语解释

  • :如果a原本在b前面,而a=b,排序之后a仍然在b的前面
  • 稳定:如果a原本在b的前面,而a=b,排序之后a可能会出现在b的后面
  • 排序:所有排序操作都在内存中完成
  • 排序:由于数据太大,因此把数据放在磁盘中,而排序通过磁盘和内存的数据传输才能进行
  • 间复杂度 一个算法执行所耗费的时间
  • 间复杂度:运行完一个程序所需内存的大小
  • n: 数据规
  • k: 桶”的个
  • In-place:    不占用额外内
  • Out-place: 占用额外内存

1似于时间复杂度的讨论,一个算法的空间复杂度(Space Complexity)义为该算法所耗费的存储空间,它也是问题规模n的函数

2空间复杂度(Space Complexity)是对一个算法在运行过程中临时占用存储空间大小的量度。有的算法需要占用的临时工作单元数与解决问题的规模n有关,它随着n的增大而增大,当n较大时,将占用较多的存储单元,例如快速排序和归并排序算法就属于这种情

3在做算法分析时主要讨论的是时间复杂度。从用户使用体验上看,更看重的程序执行的速度。一些缓存产品(redis, memcache)和算法(基数排序)本质就是用空间换时间。

入排序Insertion Sorting)的基本思想:把n个待排序的元素看成为一个有序表和一个无序表开始时有序表中只包含一个元素,无序表中包含有n-1个元素排序过程中每次从无序表中取出第一个元素,把它的排序码依次与有序表元素的排序码进行比较,将它插入到有序表中的适当位置使之成为新的有序表。

  • 从第一个元素开始,该元素可以认为已经被排序
  • 取出下一个元素,在已经排序的元素序列中从后向前扫描
  • 如果已排序元素大于新元素,将已排序元素移到下一位置
  • 重复步骤3,直到找到已排序的元素小于或者等于新元素的位置
  • 将新元素插入到该位置后
  • 重复步骤2~5。

平均情况:T(n) = O(), 最好情况:T(n) = O(n),   最坏情况:T(n) = O()   

假设有数组 arr = {2, 6, 4, 5, 3, 1} 这时需要插入的数 1(最小)这样的过程是

[2, 6, 4, 5, 3, 1]
[2, 4, 6,
5, 3, 1]
[2, 4, 5, 6,
3, 1]
[2, 3, 4, 5, 6,
1]
[1, 2, 3, 4, 5, 6]

当需要插入的数是较小的数时,后移的次数明显增多,对效率有影响。

数组快速打印

 

尔排序是希尔Donald Shell)于1959年提出的一种排序算法。希尔排序也是一种插入排序,它是简单插入排序经过改进之后的一个更高效的版本,也称为缩小增量排

尔排序是把记录按下标的一定增量分组,对每组使用直接插入排序算法排序(就像下面的8和3分为一组,3比8小,所以排序后就是3和8调换顺序;随着增量逐渐减少,每组包含的关键词越来越多,当增量减至1,整个文件恰被分成一组,算法便终止

希尔排序法的示意图

1)交换法(速度慢

2)移动法(速度快

平均情况:T(n) =, 最好情况:T(n) = ,   最坏情况:T(n) =    

冒泡排序Bubble Sorting)的基本思想是:通过对待排序序列从前向从下标较小的元素开始, 依次比较相邻元素的值,若发现逆序则交换 使大的元素逐渐从移向后部,就像水底下的气泡一样逐渐向上冒

平均情况:T(n) = O(), 最佳情况:T(n) = O(n) ,  最差情况:T(n) = O()  

速排序Quicksort)是对冒泡排序的一种改进。(快速排序使用分治法来把一个串分成两个子串) 

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

随机找出一个数为基准数,下面的算法取字符串的第一位数。比基准小的放左边,比基准大的放到右边。
首先 j 指向最后一个数,i 指向第一个数,j 向左移动每次都是 j 先出发,不然最后一步和基准交换的时候会出错,找比基准小的数,i 向右移动,找到比基准大的数,i和 j 分别找到数后把两个数交换位置,直到 i 和 j 碰面时结束,这时把基准数和 i、j 同时指向的这个数交换。
这样交换完左边都是比基准小的,右边都是比较基准大的,这样就将一个数组分成了两个子数组,然后再按照同样的方法把子数组再分成更小的子数组,直到不能分解为止。
 

测试(设置作用域为test

 
 
 

平均情况:T(n) = O(nlogn), 最好情况:T(n) = O(nlogn), 最差情况:T(n) = O()   

表现最稳定的排序算法之一,因为无论什么数据进去都是O()的时间复杂度,所以用到它的时候,数据规模越小越好。唯一的好处可能就是不占用额外的内存空间了吧。理论上讲,选择排序可能也是平时排序一般人想到的最多的排序方法了吧。选择排序(Selection-sort)是一种简单直观的排序算法。它的工作原理首先在未排序序列中找到最小(大)元素,存放到排序序列的起始位置,然后,再从剩余未排序元素中继续寻找最小(大)元素,然后放到已排序序列的末尾。以此类推,直到所有元素均排序完毕。 

选择排序select sorting)也是一种简单的排序方法。它的基本思想:第一次arr[0]~arr[n-1]中选取最小值arr[0]交换,第二次arr[1]~arr[n-1]中选取最小值arr[1]交换,第三次arr[2]~arr[n-1]中选取最小值arr[2]交换,第iarr[i-1]~arr[n-1]中选取最小值arr[i-1]交换…, n-1arr[n-2]~arr[n-1]中选取最小值arr[n-2]交换,总共通过n-1,得到一个按排序码从小到大排列的有序序列。

平均情况:T(n) = O(),  最佳情况:T(n) = O(),   最差情况:T(n) = O()   

(时间比冒泡排序短

堆排序(Heapsort)是指利用堆这种数据结构所设计的一种排序算法。堆积是一个近似完全二叉树的结构,并同时满足堆积的性质:即子结点的键值或索引总是小于(或者大于)它的父节点。

1排序是利用这种数据结构而设计的一种排序算法,堆排序是一种选择排序它的最坏,最好,平均时间复杂度均为O(nlogn),它也是不稳定排序

2是具有以下性质的完全二叉树每个结点的值都大于或等于其左右孩子结点的值,称为大顶堆 : 有要求结点的左孩子的值右孩子的值的大小关系。

3每个结点的值都小于或等于其左右孩子结点的值,称为小顶堆

4大顶堆举例说明

我们对堆中的结点按层进行编号,映射到数组中就是下面这个样:

大顶特点arr[i] >= arr[2*i+1] && arr[i] >= arr[2*i+2]   // i 对应第几个节点i0开始编号

5小顶堆举例说明

顶堆arr[i] <= arr[2*i+1] && arr[i] <= arr[2*i+2]  // i 对应第几个节点i0开始编

6升序采用大顶堆降序采用小顶堆 

  • 待排序序列构造成一个大顶堆。
  • ,整个序列的最大值就是堆顶的根节点
  • 其与末尾元素进行交换,此时末尾就为最大值
  • 后将剩余 n - 1 个元素重新构造成一个堆,这样会得到 个元素的次小值。如此反复执行,便能得到一个有序序列了。

可以看到在构建大顶堆的过程中,元素的个数逐渐减少,最后就得到一个有序序列了。

要求:给你一个数组{4,6,8,5,9},要求使用堆排序,将数组升序排序。

步骤一:构造初始堆。将给定无序序列构造成一个大顶堆

① 假设给定无序序列结构如下

② 此时我们从最后一个非叶子结点开始(叶结点自然不用调整,第一个非叶子结点 arr.length / 2 - 1 = 5 / 2 = 1,也就是下面的6结点,从左至右,从下至上进行调整。

③ 找到第二个非叶子结点4,由于{4,9,8}中9元素最大,4和9交换。

④ 这时,交换导致了子根{4,5,6}结构混乱,继续调整,[4,5,6]中6最大,交换4和6.

此时,我们就将一个无序序列构造成了一个大顶堆。

步骤二将堆顶元素与末尾元素进行交换,使末尾元素最大。然后继续调整堆,再将堆顶元素与末尾元素交换,得到第二大元素。如此反复进行交换、重建、交换。

① 将堆顶元素9和末尾元素4进行交换。

② 重新调整结构,使其继续满足堆定义

③ 再将堆顶元素8与末尾元素5进行交换,得到第二大元素8

④后续过程,继续进行调整,交换,如此反复进行,最终使得整个序列有序。

和选择排序一样,归并排序的性能不受输入数据的影响,但表现比选择排序好的多,因为始终都是O(n log n)的时间复杂度。代价是需要额外的内存空间。

并排序MERGE-SORT)是利用归并的思想实现的排序方法,该算法采用经典的分治divide-and-conquer)策略(分治法将问题(divide)成一些小的问题然后递归求解,而(conquer)的阶段则将分的阶段得到的各答案"修补"在一起,即分而治之)

归并排序是一种稳定的排序方法。将已有序的子序列合并,得到完全有序的序列;即先使每个子序列有序,再使子序列段间有序。若将两个有序表合并成一个有序表,称为2-路归并。 

归并排序思想示意图1 - 基本思想

说明可以看到这种结构很像一棵完全二叉树,本文的归并排序我们采用递归去实现(也可采用迭代的方式去实现)。阶段可以理解为就是递归拆分子序列的过

归并排序思想示意图2 - 并相邻有序子序列

再来看看阶段,我们需要将两个已经有序的子序列合并成一个有序序列,比如上图中的最后一次合并,要将[4,5,7,8][1,2,3,6]两个已经有序的子序列,合并为最终序列[1,2,3,4,5,6,7,8],来看下实现步骤

  • 把长度为n的输入序列分成两个长度为n/2的子序列
  • 对这两个子序列分别采用归并排序
  • 将两个排序好的子序列合并成一个最终的排序序列。

平均情况:T(n) = O(nlogn),  最好情况:T(n) = O(n),   最坏情况:T(n) = O(nlogn)  

计数排序的核心在于将输入的数据值转化为键存储在额外开辟的数组空间中。 作为一种线性时间复杂度的排序,计数排序要求输入的数据必须是有确定范围的整数。计数排序(Counting sort)是一种稳定的排序算法。计数排序使用一个额外的数组C,其中第i个元素是待排序数组A中值等于i的元素的个数。然后根据数组C来将A中的元素排到正确的位置。它只能对整数进行排序。

  • 找出待排序的数组中最大和最小的元素
  • 统计数组中每个值为i的元素出现的次数,存入数组C的第i项
  • 对所有的计数累加(从C中的第一个元素开始,每一项和前一项相加
  • 反向填充目标数组:将每个元素i放在新数组的第C(i)项,每放一个元素就将C(i)减去1。

桶排序是计数排序的升级版。它利用了函数的映射关系,高效与否的关键就在于这个映射函数的确定。桶排序 (Bucket sort)的工作的原理假设输入数据服从均匀分布,将数据分到有限数量的桶里,每个桶再分别排序(有可能再使用别的排序算法或是以递归方式继续使用桶排序进行排。

  • 人为设置一个BucketSize,作为每个桶所能放置多少个不同数值(例如当BucketSize==5时,该桶可以存放{1,2,3,4,5}这几种数字,但是容量不限,即可以存放100个3
  • 遍历输入数据,并且把数据一个一个放到对应的桶里去
  • 对每个不是空的桶进行排序,可以使用其它排序方法,也可以递归使用桶排序
  • 从不是空的桶里把排好序的数据拼接起来。 

注意,如果递归使用桶排序为各个桶排序,则当桶数量为1时要手动减小BucketSize增加下一循环桶的数量,否则会陷入死循环,导致内存溢出。

桶排序最好情况下使用线性时间O(n),桶排序的时间复杂度,取决与对各个桶之间数据进行排序的时间复杂度,因为其它部分的时间复杂度都为O(n)。很显然,桶划分的越小,各个桶之间的数据越少,排序所用的时间也会越少。但相应的空间消耗就会增大。 最佳情况:T(n) = O(n+k)   最差情况:T(n) = O(n+k)   平均情况:T(n) = O(n2)  

基数排序也是非比较的排序算法,对每一位进行排序,从最低位开始排序,复杂度为O(kn),n为数组长度,k为数组中的数的最大的位数;基数排序是按照低位先排序,然后收集;再按照高位排序,然后再收集;依次类推,直到最高位。有时候有些属性是有优先级顺序的,先按低优先级排序,再按高优先级排序。最后的次序就是高优先级高的在前,高优先级相同的低优先级高的在前。基数排序基于分别排序,分别收集,所以是稳定的。

1) 数排序radix sort)属于“分配式排序”distribution sort,又称“桶子法”bucket sort)或bin sort,顾名思义,它通过键值的各个位的值将要排序的元素分配至某些“桶”中,达到排序的作用。基数排序是使用空间换时间的经典算法。

2) 数排序法是属于稳定性的排基数排序法的是效率高的稳定性排序法。

3) 基数排序(Radix Sort)桶排序的扩展。

4) 基数排序是1887年赫尔曼·何乐礼发明的。它是这样实现的将整数按位数切割成不同的数字,然后按每个位数分别比

1) 将所有待比较数值统一为同样的数位长度,数位较短的数前面补零。然后,从最低位开始,依次进行一次排序。这样从最低位排序一直到最高位排序完成以后, 数列就变成一个有序序列。

2) 样说明,比较难理解,下面我们看一个图文解释,理解基数排序的步骤

平均情况:T(n) = O(n * k),  最佳情况:T(n) = O(n * k) ,  最差情况:T(n) = O(n * k)  


最新文章
新站外链建设规划与执行方案
对于新站来说,外链建设是至关重要的。外链可以帮助网站建立权威性,提高排名,并吸引更多流量。本文将提供一个详细的新站外链建设规划和执行方案,帮助您为新站建立强大的外链基础。外链建设目标在开始外链建设之前,重要的是要确定您的目
第1章 人在诛仙,开局加入聊天群!
第一章人在诛仙,开局加入聊天群!青云门,小竹峰。一名容貌俊逸的年轻人正在闭目修炼。只不过。从对方那微微皱眉的表情来看,似乎修炼的并不顺利。“还是不行吗?”“玉清境四层,果然是一道天堑啊!”太极玄清道。乃是叶逸所修炼的功法,
成人用品现在市场前景怎么样?深度剖析行业发展新趋势与潜在机遇
随着人们生活水平的提高以及生活观念的改变,现如今谈性色变的时代已经成为过去式。反之人们对其需求却在持续的增长,从而使得成人用品成为现如今小本投资创业的首选项目。那么成人用品现在市场前景怎么样?开店需要多少钱?今天来给大家详
美国奥运选手是怎么选出来的 近日更新
美国奥运选手是怎么选出来的大家好,站长来为大家解答以上问题,《美国奥运选手是怎么选出来的 》很多人还不知道,现在让我们一起来看看答案吧!奥运会闭幕式上,各国旗手是怎么选出来的一直以来,奥运会开幕式上除了开幕式主题之外,奥运
权威外链蓝图:微信外链引入攻略107
前言微信作为中国最大的社交媒体平台,拥有庞大的用户群体和丰富的生态系统。对于网站主和内容创作者而言,通过微信引入优质外链至关重要。本文将提供一份全面的网站外链规划师,指导您逐步建立一个完善的外链建设策略,有效提升网站权重和
排水横管的标准坡度和最小坡度
1、生生活活污污水水排排水水横横管管的的标标准准坡坡度度和和最最小小坡坡度度管材管径(mm)坡度生活污水接户管道埋设深度不得高于土壤冰冻线以上0.15m,且覆土深度不小于0.3m。标准坡度最小坡度mm塑料管500.0260.012150 冰冻线750.0260
科技新纪元引领未来,朝天椒智能新品掀起热潮,开启智能生活新篇章
步入智能科技高速发展的时代,我们迎来了全新的朝天椒智能新品——一款引领未来生活新潮流的高科技产品,在12月13日这个充满创新与变革的日子里,让我们一起领略朝天椒智能新品的风采,感受科技如何改变生活,激发科技爱好者的无限兴趣。朝
抖音seo矩阵系统是什么?怎么做?
抖音seo现在来量非常大,而且非常简单,关键在于你去不去干,只要你执行了想效果立竿见影!那抖音seo矩阵系统又是什么?有什么作用,具体怎么做呢??其实非常简单,如果你只是一个号,那你算是深耕,但是50个号100个号,就是矩阵模式了!
济南SEO优化,企业互联网营销的专属加速器
济南SEO优化定制服务,针对企业个性化需求,提升网站排名,增强互联网营销效果,是企业抢占网络市场的重要工具。通过专业优化策略,助力企业实现线上业务增长。随着互联网的普及,越来越多的企业开始意识到网络营销的重要性,在这个的时代
相关文章
推荐文章
发表评论
0评