数据结构第十周笔记——排序(下2)(慕课浙大版本--XiaoYu)

简介: 表排序和基数排序,还有他们之间的对比

10.2 表排序

10.2.1 算法概述

什么时候会用到表排序:

  1. 待排元素不是一个简单的整数,而是一个庞大的结构(比如说是一本书)
  2. 表排序在实际上是不需要移动原始数据的,移动的是指向他们位置的指针

间接排序:

  1. 不移动元素本身,只移动指针
  2. 定义一个指针数组作为"表"(table)
    网络异常,图片无法展示
    |

  3. 交换的只是table的整数(指针),得到
    网络异常,图片无法展示
    |

10.2.2 物理排序

N个数字的排列由若干个独立的环组成,意思如下:

网络异常,图片无法展示
|
table值的3跳到1再跳到5最后跳到0形成一个环。而环与环之间是独立互不交集(不相干)的

如何判断一个环的结束?每访问一个空位i后,就令table[i]=i。当发现table[i]==i时,环就结束了。

复杂度分析

  1. 最好情况:初始即有序
  2. 物理排序过程的最坏情况是:有N/2个环,每个环包含2个元素。需要3N/2次元素移动
  3. T = O(mN),m是每个A元素的复制时间

10.3 基数排序

仅仅基于比较进行的排序所有的这些算法他的最坏时间复杂度下界是O(NlogN),也就是说不管有多快我们总能制造出一个最坏的情况让他用最快的算法跑他也只能跑到NlogN。

这个时候除了比较之外有没有更快的排序呢?有,那就是基数排序

10.3.1 桶排序

基数排序是桶排序的升级版

网络异常,图片无法展示
|

count是数组,这个数组的每一个元素都是一个指针,一开始被初始化为空链表的头指针,所以一开始有101个空链表(对应了101个空的桶 )

假设一个学生考88分:先找到88这个桶,然后把学生信息插到这个链表的表头里

网络异常,图片无法展示
|

伪码描述

voidBucket_Sort(ElementTypeA[],intN)

{

   count[]初始化;

   while(读入一个学生成绩grade)

       将该生插入count[grade]链表;

   for( i=0;i<M;i++){

       if( count[i] )//桶不为空

           输出整个count[i]链表;

   }

}

桶排序算法的时间复杂度T(M, N)是多少?  T(N,M) =O(M+N)

   当M非常小的时候(例如4w个学生只有101个不同成绩值,那这个时候其实就相当于一种线性的算法)

10.3.2 基数排序

如果M>>N的话怎么办?

网络异常,图片无法展示
|

值是0-999之间,最多一共就三位数。我们在考虑三位数的时候每一位数只有十种可能。

基数就是这个进制的基数,二进制的基数就是2,八进制基数就是8,所以十进制的基数自然就是10

输入序列:64,8,216,512,27,729,0,1,343,125

   "次位优先"(LeastSignificantDigit)=>简称LSD算法

   //什么是次位优先?假设目前手里是216,这个时候6 个位数是最次位,2 百位数是主位(有一种算法是主位优先)

   //比较先从个位数开始

第一步:建立十个桶

网络异常,图片无法展示
|

第二步:根据个位数把他们放入相应的桶里面

网络异常,图片无法展示
|

第三步:根据十位数放入相应的桶里面:

网络异常,图片无法展示
|

最后一步:根据百位数放入相应的桶里面:

网络异常,图片无法展示
|

设元素个数为N,整数进制为B,LSD的趟数为P,则最坏时间复杂度是:T=O(P(N+B))

次位优先LSD算法

对于给定范围在0-999之间的10个关键字{64,8,216,512,27,729,0,1,343,125}

① 先为最次位关键字建立桶(10个),将关键字按最次位分别放到10个桶中

② 然后将①中得到的序列按十位放到相应的桶里

③ 做一次收集,扫描每一个桶,收集到一个链表中串起来

④ 将③中得到的序列按最主位放到桶中

⑤ 最后做一次收集,这样就得到一个有序的序列了

10.3.3 多关键字的排序

基数排序不仅仅用于处理整数的基数,还可以用于处理有多关键字的排序

网络异常,图片无法展示
|

采用"主位优先"(MostSignificantDigit)排序:为花色建4个桶

   在每个桶内分别排序,最后合并结果

   =>其实我们还是需要在每个桶内调用相应的排序算法来解决,但是总体的时间复杂度会比我们把它完整的看成一个待排数组来排稍微好一点

采用"次位优先"(LeastSignificantDigit)排序:为面值建13个桶

   这个方便就不需要再排序了,直接将结果合并,然后再为花色建4个桶就ok了

   

从上面两个例子来看,我们可以看出次位优先比主位优先要聪明得多,时间复杂度也快不少

10.4 排序算法的比较

前三个是简单排序,时间复杂度都是比较差的。优点在于程序非常好写,很短且不需要额外的空间

冒泡排序跟直接插入排序因为每次都交换两个相邻的元素,虽然慢,但是稳定

简单选择排序是跳着交换的,导致它是不稳定的

希尔排序是最先打破下界的算法,d最坏情况下是2,这个还是取决于增量排序,因为这是跳着排,所以也不稳定

堆排序跟归并排序理论来说,他们的时间复杂度都是最好的为NlogN

归并排序的缺点:需要一个额外的空间。当我们要排的数据量非常大的时候,归并排序会导致我们只能排一半的数据,本来可以排下的数据因为空间的问题而排不下。但好处在于稳定

网络异常,图片无法展示
|

目录
相关文章
|
2月前
|
算法 搜索推荐 Java
数据结构与算法学习十三:基数排序,以空间换时间的稳定式排序,速度很快。
基数排序是一种稳定的排序算法,通过将数字按位数切割并分配到不同的桶中,以空间换时间的方式实现快速排序,但占用内存较大,不适合含有负数的数组。
38 0
数据结构与算法学习十三:基数排序,以空间换时间的稳定式排序,速度很快。
|
2月前
|
存储 搜索推荐 算法
【用Java学习数据结构系列】七大排序要悄咪咪的学(直接插入,希尔,归并,选择,堆排,冒泡,快排)以及计数排序(非比较排序)
【用Java学习数据结构系列】七大排序要悄咪咪的学(直接插入,希尔,归并,选择,堆排,冒泡,快排)以及计数排序(非比较排序)
29 1
|
2月前
|
搜索推荐 索引
【初阶数据结构】深度解析七大常见排序|掌握底层逻辑与原理(二)
【初阶数据结构】深度解析七大常见排序|掌握底层逻辑与原理
|
2月前
|
搜索推荐 C++
【初阶数据结构】深度解析七大常见排序|掌握底层逻辑与原理(一)
【初阶数据结构】深度解析七大常见排序|掌握底层逻辑与原理
|
2月前
|
算法
蓝桥杯宝藏排序 | 数据结构 | 快速排序 归并排序
蓝桥杯宝藏排序 | 数据结构 | 快速排序 归并排序
05_用一个栈实现另一个栈的排序
05_用一个栈实现另一个栈的排序
|
2月前
|
人工智能 搜索推荐 算法
【初阶数据结构】深度解析七大常见排序|掌握底层逻辑与原理(三)
【初阶数据结构】深度解析七大常见排序|掌握底层逻辑与原理
|
1月前
|
C语言
【数据结构】栈和队列(c语言实现)(附源码)
本文介绍了栈和队列两种数据结构。栈是一种只能在一端进行插入和删除操作的线性表,遵循“先进后出”原则;队列则在一端插入、另一端删除,遵循“先进先出”原则。文章详细讲解了栈和队列的结构定义、方法声明及实现,并提供了完整的代码示例。栈和队列在实际应用中非常广泛,如二叉树的层序遍历和快速排序的非递归实现等。
184 9
|
1月前
|
存储 算法
非递归实现后序遍历时,如何避免栈溢出?
后序遍历的递归实现和非递归实现各有优缺点,在实际应用中需要根据具体的问题需求、二叉树的特点以及性能和空间的限制等因素来选择合适的实现方式。
32 1
|
23天前
|
存储 缓存 算法
在C语言中,数据结构是构建高效程序的基石。本文探讨了数组、链表、栈、队列、树和图等常见数据结构的特点、应用及实现方式
在C语言中,数据结构是构建高效程序的基石。本文探讨了数组、链表、栈、队列、树和图等常见数据结构的特点、应用及实现方式,强调了合理选择数据结构的重要性,并通过案例分析展示了其在实际项目中的应用,旨在帮助读者提升编程能力。
44 5