数据结构基础之《(1)—复杂度》

一、评估算法优劣的核心指标是什么?

1、时间复杂度(流程决定)
2、额外空间复杂度(流程决定)
3、常数项时间(实现细节决定)

二、常数操作

1、什么是常数时间的操作?
如果一个操作的执行不以具体样本量为转移,每次执行时间都是固定时间。称这样的操作为常数时间的操作。
比如:执行一个数组的寻址,执行的时间和数据量没关系,第1000个位置和第1000万个位置,时间是一样的,计算机用偏移量获得。

2、常见的常数时间的操作
(1)常见的算术运算(+、-、*、/、%等)
(2)常见的位运算(>>、>>>、<<、|、&、^等)
>>是带符号右移,>>>是不带符号右移
(3)赋值、比较、自增、自减操作等
(4)数组寻址操作
总之,执行时间固定的操作都是常数时间的操作。
反之,执行时间不固定的操作,跟样本量有关的,都不是常数时间的操作。

3、什么不是常数时间操作
LinkedList,底层是一个双向列表。
要在list里面get一个数据,它不会像数组寻址一样,因为它不是连续区间。它是从0位置往下数。

4、时间复杂度就是来衡量流程中发生了多少次常数操作这件事
举例:选择排序
(1)先在0到n-1中,找到最小值位置在哪儿,然后把最小值和0位置的数交换
(2)0位置的数搞定了
(3)在1到n-1中,找到最小值的位置在哪儿,然后把最小值和1位置的数交换
(4)然后重复2到n-1,3到n-1。。。一直到n-1到n-1

这个流程发生了多少次常数操作?
步骤:
(1)单次:看+比
(2)一次换

n * (看+比) + 1
(n-1) * (看+比) + 1
(n-2) * (看+比) + 1
...

看是1次,比也是1次

总的表达式变为:
n * (2) + 1
(n-1) * (2) + 1
(n-2) * (2) + 1
...

= 2 * (n + n-1 + n-2 + ... + 1) + n

等差数列可以化简为(n(1+n)/2把系数换成a、b加个常数c)
= 2an² + bn + n + c
a、b、c是常数

最终的时间复杂度是抹掉常数项、高阶项系数和低阶项,最终得到n²(n的平方)

三、如何确定算法流程的总操作数量与样本数量之间的表达式关系?

1、想象该算法流程所处理的数据状况,要按照最差情况来。
2、把整个流程彻底拆分为一个个基本动作,保证每个动作都是常数时间操作。
3、如果数据量为N,看基本动作的数量和N是什么关系。

四、如何确定算法流程的时间复杂度?

当完成了表达式的建立,只要把最高阶项留下即可。低阶项都去掉,高阶项的系数也去掉。
记为:O(忽略掉系数的高阶项)

当样本量大到足够大的时候,决定算法快慢的就是高阶项的东西。

五、时间复杂度的意义

1、抹掉了好多东西,只剩下了一个最高阶项,那这个东西有什么意义呢?
2、时间复杂度的意义在于:
当我们要处理的样本量很大很大时,我们会发现低阶项是什么不是最重要的;每一项的系数是什么,不是最重要的。真正重要的就是最高阶项是什么。
3、这就是时间复杂度的意义,它是衡量算法流程的复杂度的一种指标,该指标只与数据量有关,与过程之外的优化无关。

六、实践时间复杂度的估算

1、选择排序
分析:见上面

	public static void selectionSort(int[] arr) {
		if (arr == null || arr.length < 2) {
			return;
		}
		// 0~n-1
		// 1~n-1
		// 2~n-1
		for (int i=0; i<arr.length-1; i++) { // i~n-1
			// 最小值在哪个位置上i~n-1
			int minIndex = i;
			for (int j=0; j<arr.length; j++) { // i~n-1上找最小值的下标
				minIndex = arr[j] < arr[minIndex] ? j : minIndex;
			}
		}
	}
	
	public static void swap(int[] arr, int i, int j) {
		int tmp = arr[i];
		arr[i] = arr[j];
		arr[j] = tmp;
	}

2、冒泡排序

3、插入排序

  • 3
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值