预推免面试-算法-排序算法

目录

快速排序

算法步骤

复杂度分析

稳定性分析

为什么快速排序不稳定?

归并排序

算法步骤

复杂度分析

稳定性

插入排序

复杂度分析

稳定性

选择排序

复杂度分析

稳定性

为什么选择排序是不稳定的?

冒泡排序

复杂度分析

稳定性

希尔排序

算法步骤

算法细节

怎么确定步长?

复杂度分析

稳定性

为什么希尔排序是不稳定的?

堆排序

算法步骤

算法细节

怎么通过数组存储数据结构堆?

最大堆的性质

怎么维护最大堆?

怎么确定最后一个父节点的下标?

复杂度分析

稳定性

为什么堆排序是不稳定的?

计数排序

算法步骤

复杂度分析

为什么复杂度优于O(nlogn)?

稳定性

基数排序

复杂度分析

稳定性

桶排序

复杂度分析

稳定性

总结计数排序、基数排序、桶排序


快速排序

算法步骤

  1. 在给定的序列中选择一个数A[n]作为主元pivot
  2. 定义指针i,j(i:指针之前都是小于pivot的元素,j:遍历指针)
  3. j从序列的头部开始,一旦发现A[j]<=pivot,交换A[j]和A[++i]
  4. 直到j遍历到n-1结束,交换A[i+1]和A[n]
  5. 对于1..i和i+2..n递归调用上述过程

复杂度分析

取决于pivot的选取

最坏情况时间复杂度:O(n^2)

平均情况时间复杂度:O(nlogn)

稳定性分析

不稳定

为什么快速排序不稳定?

在算法中,我们将序列分为四个部分:

lower | higher | unvisited | pivot

在unvisited部分遍历到需要放到lower部分的元素时,需要和higher部分的第一个交换,在这个过程中,higher元素的相对位置发生了变化

归并排序

算法步骤

  1. 将序列分为较平均的两部分,分别对这两个部分继续调用步骤1
  2. 直到序列的元素无法进行分割
  3. 对排序好的序列两两进行合并:依次从左至右比较大小,将较小的存入新开的数组中

复杂度分析

最坏情况和平均情况时间复杂度:O(nlogn)

空间复杂度:O(n)

稳定性

稳定

本质上还是相邻元素之间的比较和交换

插入排序

复杂度分析

平均情况时间复杂度:O(n^2)

空间复杂度:O(1)

稳定性

稳定

选择排序

将未排序部分当前最小的交换到未排序部分的最开始

复杂度分析

平均情况时间复杂度:O(n^2)

空间复杂度:O(1)

稳定性

不稳定

为什么选择排序是不稳定的?

未排序部分的最小元素和未排序部分的第一个元素交换时,会产生相对位置变化

冒泡排序

复杂度分析

平均情况时间复杂度:O(n^2)

空间复杂度:O(1)

稳定性

稳定

希尔排序

算法步骤

  1. 确定步长,相隔步长的元素直接采取插入排序
  2. 步长缩小一倍,继续进行步骤1
  3. 直到步长缩小为1,进行一次插入排序后完成排序

算法细节

怎么确定步长?

通常步长选择为元素个数的一半,第一次的插入排序的元素每组只有两个

复杂度分析

平均时间复杂度:O(nlogn)

最差时间复杂度:O(n^2)

空间复杂度:O(1)

稳定性

不稳定

为什么希尔排序是不稳定的?

拥有相同的值的元素在不同的分组中进行排序的过程中,相对位置可能会发生变化

堆排序

算法步骤

  1. 堆数据结构用数组存储
  2. 维护最大堆
  3. 将堆顶的元素和最后一个元素交换,并除去该元素,维护最大堆
  4. 重复步骤3

算法细节

怎么通过数组存储数据结构堆?

下标为i的元素的子节点是2i+1和2i+2

下标为i的元素的父节点是(i-1)/2向下取整

最大堆的性质

父节点的值大于其子节点的值

怎么维护最大堆?

  1. 从最后一个父节点开始,比较其值和其子节点的值,并和较大的子节点交换
  2. 对于交换后的子节点递归的调用维护最大堆(max_heap函数传入参数是父节点的下标)
  3. 直到所有的父节点处理完

怎么确定最后一个父节点的下标?

通过求最后一个元素的父节点就可以得到

复杂度分析

时间复杂度O(nlogn)

稳定性

不稳定

为什么堆排序是不稳定的?

在堆顶的元素和最后一个元素交换的操作,会将相同的值的元素的相对位置靠后的那一个,变成相对靠前的那一个

计数排序

算法步骤

  1. 找出数组的最大值max,并定义一个max+1大小的数组
  2. 用该数组统计每个数字出现的个数
  3. 将数组进行累加,确定在整个序列中的位置

复杂度分析

时间复杂度:O(n+m)  m:给出的最大值

在m=O(n)的情况下认为是O(n)的时间复杂度

空间复杂度:O(n+m)

为什么复杂度优于O(nlogn)?

因为不是基于比较的排序算法

在m=O(n)的情况下,我们一般采用计数排序

稳定性

稳定

基数排序

从最低位到最高位依次采用一个稳定的排序:计数排序

这个算法就是相对于计数排序适用于大数据

复杂度分析

总的时间复杂度为O(d*(n+r))

其中d为位数,n为最多元素个数,r为桶数

空间复杂度是O(m+n)

稳定性

稳定

桶排序

将待排序数据平均切分为几个区间(不同区间之间本身就是有序的),叫做桶,每个桶各自将元素排序好,再将桶内数据合并即可完成排序

复杂度分析

在桶内选择快排,平均时间复杂度为O(n+m)

最差情况O(n^2)

稳定性

稳定

总结计数排序、基数排序、桶排序

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

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

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值