算法笔记(一)-时间复杂度、三种简单排序、归并排序

本文深入探讨了算法评价标准,重点关注时间复杂度和额外空间复杂度。介绍了冒泡排序、选择排序和插入排序的时间复杂度,并强调在工程实践中这些简单排序算法的局限性。此外,解释了递归的概念,分析了递归行为的时间复杂度,并通过Master公式举例说明。归并排序作为高效排序算法,其时间复杂度为O(N*logN)。同时,文章提到了小和问题和逆序对问题的解决方案,展示如何利用归并排序优化算法效率。
摘要由CSDN通过智能技术生成

算法评价标准

认识时间复杂度:

常数时间的操作:一个操作如果和数据量没有关系,每次都是固定时间内完成的操作,叫做常数操作。

时间复杂度为一个算法流程中,常数操作数量的指标。常用O(读作big O)来表示。具体的说,在常数操作数量的表达式中,只要高阶项不要低阶项,也不要高阶项的系数,剩下部分如果记作f(N),那么时间复杂度为O(f(N))。

比较两个算法好坏,先拼指标,再拼低阶项和系数。

评价一个算法流程的好坏,先看时间复杂度的指标,然后再分析不同数据样本的下的实际运行时间,也就是常数项的时间。

一个简单例子理解:
在这里插入图片描述
第一个算法O(M*N);
第二个算法O(M*logN)所有不带底数的log,默认2为底
第三个算法O(M*logM)+O(N+M),分析如下:
在这里插入图片描述
外排:先B排序,再两个指针依次进行比较,当b <= a,则b指针移动,否则 a指针移动。复杂度分为两步进行分析:

在这里插入图片描述
通过常数时间操作数量进行分析。ps:如果有两个样本量,此时复杂度不能化简,除非明确知道谁大谁小(样本量确定了),则可以化简。

那么在什么情况下2算法低,什么情况下3算法低?

通过具体样本量分析:如果B大A小,则2算法好,如果A大B小,则3算法好。

排序算法:

冒泡排序

在这里插入图片描述
在这里插入图片描述
end每次–,依次比较,交换,每次循环遍历得到最大的数,沉到最底。
可看for循环估计时间复杂度: O(N2)
在这里插入图片描述

选择排序

时间复杂度:O(N2)
在这里插入图片描述
大循环:
在这里插入图片描述
minIndex记录每次循环的最小值(三目运算),然后再跟第一个数交换。

冒泡排序和选择排序工程上基本用不到了,只是用于教程。

插入排序

类似扑克牌,先抓牌然后整牌,看看新抓的牌能滑倒哪个位置。
在这里插入图片描述
在这里插入图片描述
该排序方法就涉及到最好情况,平均情况,最坏情况,实际时间和数据状况有关系。最好情况O(N),最坏情况O(N2)

一个算法流程怎样评价?当数据状况不同产生的效果不同时,一律按照最坏情况估计

于是插入排序时间复杂度O(N2)。

对数器

好处:自己验证,用于调试。

  1. 没找到线上测试online judge,则可以使用对数器。
  2. 大数据样本出错时,快速找到出错地方。
  3. 贪心策略使用,直接验证是否正确

代码实现

  1. 有一个你想要测试的方法,例如上文所示算法。

  2. 准备一个随机数组(样本)生成器:
    在这里插入图片描述

  3. 再准备一个绝对正确的方法(不用管时间复杂度,好写,好实现,绝对正确即可):
    在这里插入图片描述

  4. 大样本测试(包括实现比对方法)
    测试次数500000;
    在这里插入图片描述
    生成数组,分别用好的/和自己写的算法进行排序

    判断两个数组相等算法,长度一样,数一样。
    在这里插入图片描述
    拷贝数组算法
    在这里插入图片描述

  5. 如果有一个样本由于数组相对较短,所以几乎穷尽了所有情况,如果都正确,则返回正确,一个出错则返回打印看看哪个方法出错。

所需的正确的方法写不对怎么办:则先用小样本测试,手动改正正确的方法,因为自己知道正确答案,则我们可以手动去修改,不断迭代找到完全正确的方法。

额外空间复杂度:

算法流程走完,需要额外申请开辟的空间,和原来目标存储的数据结构没关系,类比时间复杂度。

递归行为时间复杂度:

什么是递归?

即:自己调用自己

例如:数组中找最大值
在这里插入图片描述
递归函数就是系统在帮你压栈,在函数调用子过程之前,会自动保存执行当前函数的行数、局部变量、指针等等信息,相当于保存函数执行的现场,回到该过程时从栈中弹出还原现场,直到执行完毕。
在这里插入图片描述
因此任何递归行为都可以改成非递归,每次通过压栈来分析即可。
通过自己压栈就是迭代了。

递归行为时间复杂度

如何分析递归的时间复杂度呢?

如下图:
在这里插入图片描述
总的时间复杂度(T):子过程时间之和(aT(n/b)),加上除去子过程调用时间,剩下过程的额外花费(O(nd))(看一步即可)。
凡是符合上述公式的过程,都可用master公式可以直接套用估算时间复杂度(见下图)。
在这里插入图片描述

套用公式可得上述算法复杂度为O(N)
在这里插入图片描述
如果满足下图,则时间复杂度为O(N*logN)
在这里插入图片描述
如果满足下图,则时间复杂度为O(N2)
在这里插入图片描述
而下述递归时间复杂度公式,不可套用master公式。
在这里插入图片描述
划分子问题的规模必须一样!

归并排序时间复杂度

归并排序
在这里插入图片描述
左右侧部分分别排好序,准备一个辅助数组,用外排方式,用两个指针指向左右侧部分的数组,依次比较填入,最后拷贝回原数组。

时间复杂度计算:
在这里插入图片描述
根据master公式,可得时间复杂度O(N*logN),相较于O(N2)好太多,额外空间复杂度O(N)。代码实现:
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
不返回help

小和问题和逆序对问题

在这里插入图片描述
第一种解法,直接2pass遍历,但是复杂度高O(N2),可用作对数器的绝对正确的方法。
第二种方法,采用归并排序,思路为寻找该数有多少后面的数比他大,就产生多少个该数做累加,通过归并分批榨取。如下图:
在这里插入图片描述
在这里插入图片描述
代码如下所示:
在这里插入图片描述
跟上述归并排序代码基本一致,多了一行代码,利用res变量存储当前归并函数下榨取出来的小和,依次归并,则不会漏算,重复计算。
在这里插入图片描述

上述写法可以防止溢出,安全。且位运算比算数运算快很多.

逆序对问题
在这里插入图片描述
同样的思路,归并排序中求后面的部分有多少个数比该数小。
由于使用归并:一个组内比较次数不会浪费,且跨组比较,所以快。而遍历,会浪费比较次数。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值