时间复杂度与空间复杂度
时间复杂度 Time Complexity : 代码执行的次数
O(1)-----常量 函数体执行3次printf
O(n) 一个for循环 3*n+2次,只取最高次幂,并且把系数去掉,所以是O(n)
O(nlog2 n) --------log以2为底 n的对数,外层循环次数*内层
for(int i = 1;i<=n;i*=2)
{
for(int j = 1;j<=n;j++)
p--;
}
O(n^2)---------- 把上面的内层循环里面的n改成i++
例题
for(i = 1;i<=n;i++)
for(j = 1;j<=i;j++)
for(k = 1;k<=j;k++)
p--;
1+(1+2)+(1+2+3)+(1+2+3+...)+...+..(1+2+3+...+n)即为1+3+6+10+...+i*(i+1)/2
把1/2提出去,变成i^2+i,从1累加到n
1^2+2^2+3^2+...+n^2 = n(n+1)(2n+1)/6
所以时间复杂度为O(n^3)
递归的时间复杂度
递归式通式 T(n) = aT(n/b)+f(n)
n : 数据规模
a : 递归的叉数
b : 递归中传进n的个数,比如b=2代表每次递归传了n的长度的一半的参数,b还影响着递归的层数,因为当n/b=1时就不能继续递归了
1.递归树法
T(n) = 3T(n/4)+cn^2
层数 K = log4 n + 1 以4为底
上面的是cn^2*(1+3/16+(3/16)^2+...+(3/16)^k-2) = (16/13)cn^2
最后一层是n^(log以4为底3的对数),两个相加上面的次幂高,所以是O(n^2)
T(n) = 2T(n/2)+1
层数 K = log2 n + 1 以2为底
上面的是1+2+4+8+..+2^k-2 = n-1
最后一层是n,加起来是2n-1,所以是O(n^2)
2.主方法
直接算O(n的logb a 和f(n)进行比较,谁大取谁,一样大为 O(n的logb a * log2 n))
第一个题n^log4 3和cn^2比较后者幂次高,取后者所以是O(n^2)
第二个题n和1比前者幂次高,取前者所以是O(n)
空间复杂度 : 额外申请的空间 包括变量和动态申请的
如果我们额外申请的空间 不随着处理数据量的增大而增大 那么我们称这样的空间复杂度为常量空间复杂度记为O(1)
基数排序:最稳定的排序方法,其他排序方法可能受算法的影响
d------位数 r--------桶的个数
位数决定了要入桶出桶几次
入桶的循环次数是有多少个变量也就是n
出桶的循环次数是有多少个桶也就是r
所以时间复杂度是O(d*(n+r)),由于是拉链法所以是一个指针数组,空间大小为O(n+r)
稳定性:数值相等的两个元素 在排序前后其相对位置未发生改变
名称 | 最好时间复杂度 | 平均时间复杂度 | 最坏时间复杂度 | 空间复杂度 | 稳定性 | |
1 | 冒泡排序 | O(n)正序的时候 | O(n^2) | O(n^2)逆序的时候 | O(1) | 稳定 |
2 | 选择排序 | O(n^2) | O(n^2) | O(n^2) | O(1) | 不稳定 |
3 | 插入排序 | O(n)正序的时候 | O(n^2) | O(n^2)逆序的时候 | O(1) | 稳定 |
4 | 快速排序 | O(n*log2 n)每次都可以二分 | O(n*log2 n) | O(n^2)有序/逆序最坏 | O(log2 n) | 不稳定 |
5 | 希尔排序 | O(n)正序的时候 | O(n的(1.2~1.5)) | O(n^2)逆序的时候 | O(1) | 不稳定 |
6 | 归并排序 | O(n*log2 n) | O(n*log2 n) | O(n*log2 n) | O(n) | 稳定 |
7 | 堆排序 | O(n*(log2 n)) | O(n*(log2 n)) | O(n*(log2 n)) | O(1) | 不稳定 |
8 | 基数排序 | O(d*(n+r)) | O(d*(n+r)) | O(d*(n+r)) | O(n+r) | 稳定 |
稳定性的问题 :
9 5 4 2 5,第一次选择排序后,相同元素的位置发生了交换,所以不稳定
2 5 5 3 4,选4做标准值,到3的时候,第一个5和三交换了位置,所以不稳定
根据规律总结,隔着很多元素交换的排序都不稳定
堆排序的时间复杂度计算:
堆排序分为创建初始堆和调整的过程
1.创建初始堆
设最后一层为k,那么倒数第二层有2^(k-2)个节点,倒数第三层有2^(k-3)个节点
倒数第二层的节点需要比较一次,倒数第三层的节点需要比较两次
所以 S = 2^(k-2)*1+2^(k-3)*2+2^(k-4)*3 + ....+ 1*(k-1) 由于是等差*等比,用乘公比错位相减
2S = 2^(k-1)*1+2^(k-2)*2+2^(k-3)*3 + ... + 2*(k-1)
所以S = 2^k+k-3
又因为是完全二叉树所以 k = log2 n + 1
所以创建初始堆的时间复杂度为O(n)
2.排序
元素的长度为n要循环n次,然后循环中调整的次数为log2 n次
所以排序的时间复杂度为O(n*(log2 n))
整体的时间复杂度为他们两个相加,所以为O(n*(log2 n))