时间复杂度
算法时间复杂度计算方式
1.找出算法中重复执行次数最多的语句的频度(操作次数)来估算算法的时间复杂度
2.保留算法的最高次幂,忽略所有低次幂和高次幂的系数
3.将算法执行次数的数量级放入大Ο记号中
*、
O(1):常量阶
操作次数为常数,与数据规模n无关
n = 10000000;
n1 = 100000001;
temp = n;
n = n1;
n1 = temp;
O(logn):对数阶
操作数量与输入规模n的比例是log2(n)
//二分法查找数,(二分法必须是一组有序的数列)例如1,3,5,9 找出7
//如果当前数列全部便利一次的频度为n,二分法每次砍断一般为n/2,随着次数的增加、
查询次数 时间频度
1 n/2
2 n/2^2
3 n/2^3
4 n/2^4
K n/2^k
当最后找到7的时间频率为1也就是
n/2^k = 1 ==> n=2^k ==> k=log2n
O(n):线性阶
操作数量与输入规模n成正比
//普通循环查找数列中一个数,例如1,3,5,9 找出7
//如果当前数列全部便利一次的频度为n,第二次就为n-1
查询次数 时间频度
1 n
2 n-1
3 n-2
k n-(k-1)
当最后找到7的时间频率为1也就是
n-(k-1) = 1 ==> n=k ==> k=n
O(nlogn): 对数阶,如快速排序算法
上面二分法查找,k为logN(logN没写底数,为log2N)
线性对数阶就是在logN的基础上多了一个线性阶
//对data进行排序,使用快速排序
//找到标杆数X,大于x放一堆,小于或者等于x放一堆儿,再对2堆儿分别进行找标杆数X进行排序
var data = [5, 4, 7, 8, 2, 7, 8, 5, 6, 3];
function quicksort(data) {
var x = data[0];
var i = 1;
var j = data.length-1;
//当数组长度小于等于1时直接返回data
if(data.length <= 1) return data;
//单词循环,x为5,i为1,j为9,j主动往后移动,当所在数字小于或等于x,i往前移动,找到所在位置数大于x后,与j所在位置数交换
//j继续往后移动,当j=i时停止结束单词循环,冰与x交换值
while(j > i) {
if(data[j] <= x) {
if(data[i] > x) {
var temp = data[i];
data[i] = data[j];
data[j] = temp;
} else {
i++;
}
} else {
j --;
}
}
//当j=i时,如果data[j]<x交换data[j]和x的位置
if(data[j] <= x) {
data[0] = data[j];
data[j] = x;
}
//j右边的一定小于等于j
var leftData = data.slice(0, j);
//j左边的一定大于等于j
var rightData = data.slice(j);
return quicksort(leftData).concat(quicksort(rightData));
}
console.log(quicksort(data));
由于单次查询中有while循环得知,单词查询中
查询次数 while时间频度
1 n
2 n-1
3 n-2
K n-(k-1)
由此得知单次查询 n-(k-1) = 1 ==> k = n ==> f(n) = O(n);
单词循环时间复杂度为O(n)
快速排序为递归查询,假设第一次查询的时间复杂度为f(n)
查询次数 递归时间频度
1 n
2 n/2
3 n/2^2
K n/2^(k-1)
由此的得出n/2^(k-1) = 1 ==> n = 2^(k-1) ==> k = log2n + 1
时间复杂度计算忽略第次幂和高次幂系数,故次递归算法时间富足都为log2n
故总排序算法为while循环时间复杂度x递归循环时间复杂度 ==>n*log2N==> nlog2n==> O(n) = nlog2n
O(n^2):平方阶,如选择排序,冒泡排序
//冒泡排序,选择数组第一项和后面所有项比较,找出最小一个放到最前面,依次进行
function bubbleSort(data) {
for(var i = 0; i < data.length -1; i ++) {
for(var j = i + 1; j < data.length; j ++) {
if(data[j] < data[i]) {
var temp = data[i];
data[i] = data[j];
data[j] = temp;
}
}
}
return data;
}
查询次数 循环时间频度
1 n*(n-1)
2 (n-1)*(n-2)
3 (n-2)*(n-3)
K (n-k+1)*(n-k) ==> 忽略所有低次幂和高次幂的系数 n^2 - k = 1
由此的得出k = n^2
//选择排序,首先从未排序序列中找到最大的元素,放到已排序序列的末尾重复上述步骤
function selectSort(data) {
for(var i = 0; i < data.length -1; i ++) {
var index = i;
for(var j = i + 1; j < data.length; j ++) {
if(data[j] < data[index]) {
index = j;
}
}
if(index != i) {
var temp = data[index];
data[index] = data[i];
data[i] =temp;
}
}
return data;
}
查询次数 循环时间频度
1 n*(n-1)
2 (n-1)*(n-2)
3 (n-2)*(n-3)
K (n-k+1)*(n-k) ==> 忽略所有低次幂和高次幂的系数 n^2 - k = 1
由此的得出k = n^2
O(n^3):立方阶 三次for循环
查询次数 循环时间频度
1 n*(n-1)*(n-2)
2 (n-1)*(n-2)*(n-3)
3 (n-2)*(n-3)**(n-4)
K (n-k+1)*(n-k)*(n-k-1) ==> 忽略所有低次幂和高次幂的系数 n^3 - k = 1
由此的得出k = n^3
O(2^n):指数阶
//数组长度 子集数量
//0 1
//1 2
//2 f(1) + f(1)
//3 f(2) + f(2)
//n f(n-1) + f(n-1)
console.log(allChild(data));/
function allChild(n) {
if(n == 0) return 1;
if(n == 1) return 2;
return allChild(n-1) + allChild(n-1);
}
//反向推导法
数字大小 运行次数
1 1
2 3
3 7
n 2^n -1 ==>
由此的得出O(2^n)
常用的时间复杂度所耗费的时间从小到大依次是:
O(1) < O(logn) < O(n) < O(nlogn) < O(n^2) < O(n^3) < O(2^n) < O(n!) < O(n^n)

浙公网安备 33010602011771号