时间复杂度

算法时间复杂度计算方式

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)

posted @ 2019-12-11 14:38  zgddan  阅读(335)  评论(0)    收藏  举报