时间复杂度及空间复杂度直白理解/快排/冒泡
常常在算法类的文章里看到时间复杂度,空间复杂度的名词,但是对其中的意思不是很清楚,但是大概是知道,复杂度代表了一个算法的运行效率,复杂度越大说明这个算法运行效率越差,但是在一些数据统计的项目中,使用的数量级是无法估量的, 所以算法的效率问题就尤为重要
时间复杂度
定义
标准定义 (from wiki)
在计算机科学中,算法的时间复杂度(Time complexity)是一个函数,它定性描述该算法的运行时间。这是一个代表算法输入值的字符串的长度的函数。时间复杂度常用大O符号表述,不包括这个函数的低阶项和首项系数。使用这种方式时,时间复杂度可被称为是渐近的,亦即考察输入值大小趋近无穷时的情况。例如,如果一个算法对于任何大小为 n (必须比 n0 大)的输入,它至多需要 5n3 + 3n 的时间运行完毕,那么它的渐近时间复杂度是 O(n3)。
个人理解
时间复杂度代表的就是一个函数的运行时间随传入的变量 n 大小增加的而增长的加速度,加速度我們都知道最直觀的表现加速度的方法就是把运行的时间的增长用函数表示,然后画在坐标轴上
从上上图我们就可以很明显的看出 O(2n)这种复杂度的运行时间随n的变大,呈指数爆炸 ,而O©得运行时间不随n变大而变大 (c代表常数) 所以我们尽量不要选择复杂度为O(2n)得算法
下面我们来看看一个算法/函数得复杂度是怎么计算的
既然时间复杂度肯定是要计算运行时间的,但是具体时间肯定跟电脑等硬件等原因有关,所以我们直接认为每行代码得运行速度是相等的,所以我们只要直接计算代码运行得行数就行了
例如
function (n) {
for(let i,i = 1;i < n;i++) { // n次
for(let j,j = 1;j < n;j++){ // n^2次
console.log(i) //n^2次
}
}
}
所以上面的函数一共运行了 2n^2 + n行代码
但是在复杂度计算得规则就是: 去低阶项,去掉常数项,去掉高阶项的常参得到, 所以上面的 函数得时间复杂度是 O(n2)
一般需要嵌套循环的算法复杂度都是O(n2)
冒泡排序: 复杂度O(n2)
fun = function(arr) {
let n = arr.length
for(let i = 0;i < n-1;i++ ) {
for(let j = 0;j < n -1 -i;j++) {
if(arr[j] > arr[j + 1]) {
let temp = arr[j + 1]
arr[j + 1] = arr[j]
arr[j] = temp
}
}
}
return arr
}
快排: 复杂度O(nlog2n) ,和因为二分法的复杂度为 O(log2n) ,所以快排相当于n个二分法
var quickSort = function(arr) {
if (arr.length <= 1) { return arr; }
var pivotIndex = Math.floor(arr.length / 2);
var pivot = arr.splice(pivotIndex, 1)[0];
var left = [];
var right = [];
for (var i = 0; i < arr.length; i++){
if (arr[i] < pivot) {
left.push(arr[i]);
} else {
right.push(arr[i]);
}
}
return quickSort(left).concat([pivot], quickSort(right));
};
常见的排序复杂度
从上图可以的值,对数的排序复杂度是比较低的,所以快排的效率比冒泡排序要快
空间复杂度
定义(from wiki)
类似于时间复杂度的讨论,一个算法的空间复杂度(SpaceComplexity)S(n)定义为该算法所耗费的存储空间,它也是问题规模n的函数。渐近空间复杂度也常常简称为空间复杂度。空间复杂度(SpaceComplexity)是对一个算法在运行过程中临时占用存储空间大小的量度。一个算法在计算机]存储器上所占用的存储空间,包括存储算法本身所占用的存储空间,算法的输入输出数据所占用的存储空间和算法在运行过程中临时占用的存储空间这三个方面。算法的输入输出数据所占用的存储空间是由要解决的问题决定的,是通过参数表由调用函数传递而来的,它不随本算法的不同而改变。存储算法本身所占用的存储空间与算法书写的长短成正比,要压缩这方面的存储空间,就必须编写出较短的算法。算法在运行过程中临时占用的存储空间随算法的不同而异,有的算法只需要占用少量的临时工作单元,而且不随问题规模的大小而改变,这种算法是“就地"进行的,是节省存储的算法。
个人理解
空间复杂度就是,在算法运行中所占用的内存, 因为有些算法需要存储临时的变量等 ,都需要占用多的存储空间.但是在实际的算法中 ,时间复杂度和空间复杂度通常是鱼与熊掌的关系 ,两者不可得兼, 选择时间复杂度较低,通常会牺牲空间复杂度 . 通常是根据具体情况来判断要选哪种算法 ,但是个人认为对于一个项目来说运行的效率通常是第一要素 ,而消耗资源总是放在第二位 ,所以通常会以空间来换取时间的减少