8.排序算法--时间复杂度和空间复杂度
排序分类
1.内部排序
只将需要处理的所有数据都加载到内存寄存器中(内存)进行排序。
2.外部排序
数据量过大,无法全部加载到内存中,需要借助外部存储(文件等)进行排序。
算法的时间复杂度
度量一个程序(算法)的执行时间的两种方式。
1.事后统计的方式
这种方法可行,但是有两个问题:一是要对设计的算法的运行性能进行评测,需要实际运行改程序;二是所得时间的统计量依赖计算器的硬件,软件等环境因素。
这种方法,要在同一台计算器的相同状态下运行,才能比较哪一个算法速度更快。
2.事前估算的方法。
通过分析某个算法的时间复杂度来判断哪个算法更优。
算法的时间复杂度
时间频度:一个算法花费的时间以算法中与句的执行次数成正比,哪个算法中语句执行次数多,大话费的时间就多。一个算法中的语句执行次数称之为语句频度或者时间频度。
记为T(n)
举例如下;
1.忽略常数项
2.忽略低次项
3.忽略系数
算法的时间复杂度
算法的时间复杂度举例
1.常数阶O(1)
无论代码执行多少行,只要没有循环等复杂结构,那这个代码的时间复杂度就都是O(1)
int i=1;
int j=2;
++i;
j++;
int num=i+j;
上述代码在执行的时候,他消耗的时间并不随着某个变量的增长而增长,那么无论这类似代码有多长?,即使几万几十万行,都可以用O(1)来表示时间复杂度
2.对数阶O(log₂n)
对数公式是数学中的一种常见公式,如果a^x=N(a>0,且a≠1),则x叫作以a为底N的对数,记做x=log(a)(N),其中a要写于log右下。其中a叫作对数的底,N叫作真数。通常我们将以10为底的对数叫作常用对数,以e为底的对数称为自然对数
int i=1;
while(i<n){
i=i*2;
}
说明:
在while循环种,每次都将i乘于2,乘完以后,i距离n原来越近,假设循环x次后,i就大于n了,也就是说2的x次方等于n,那么x=log₂n,也就是说当循环log₂n次后,这个代码就结束了
因此这个代码的时间复杂度为:O(log₂n),O(log₂n)的这个2时间上是根据代码上变化的,如果是i=i*3,则是O(log₃n)
3.线性阶O(n)
for(int i=1;i<=n;i++){
j=i;
j++;
}
说明:
这段代码中,for循环里面的代码会执行n遍,因此他消耗的时间就是随着n的变化而变化的,这类代码的时间复杂度就用O(n)表示.
4.线性对数阶
for(int m=1;m<n;m++){
int i=1;
while(i<n){
i=i*2;
}
}
说明:
将时间复杂度为O(logn)的代码执行n遍,他的时间复杂度就是n*O(nlogN),也就是O(nlogN).
5.平方阶O(n²)
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
m=i*j;
}
}
说明 :
平方阶O(n²)就是两层for循环,将O(n)的代码在嵌套执行一遍,这段代码其实就是嵌套了2层n循环,如果将其一层的n改为m,他的时间复杂度就是O(m*n)
6.立方阶O(n³)和k次方阶O(n^k)
说明:多层for循环而已
平均时间复杂度和最坏时间复杂度
算法的空间复杂度
1.类似于时间复杂度的讨论,一个算法的空间复杂度(Space Complexity)定义为该算法所耗费的存储空间。,他也是问题规模n的函数
2.空间复杂度是对一个算法在运行过程中临时占用的存储空间大小的量度,有的算法需要占用的临时工作单元数以解决问题的规模n有关,它随着n的增大而增大。当n较大时,将占用较多的存储单元。例如快速排序和归并排序算法
3.在做算法分析时,主要讨论的时间复杂度。从用户体验上来看,更看重的是程序的执行速度。一些缓存产品(redis,memcache)和算法(基数排序)本质就是利用空间换时间。