大话数据结构阅读笔记(一)时间复杂度和空间

大学的数据结构,学的确实不怎么样,算法这一块,也有待提高,每次百度一些BAT笔试题,看到什么时间复杂度,空间复杂度都是一头雾水。最近找实习工作不是很顺利,需要实习生的公司本来就不多,很多公司看到学校咋样,就直接PASS你,不给你机会。不过没关系,一切都会好起来的。趁现在每天时间还算自由,多看看书,争取机会到来的时候一把抓住。开始正题。

先来明确2个名词的概念:

时间复杂度:

书上对于时间复杂度的定义是这样的:在进行算法分析时,语句总的执行次数T(n)是关于问题规模n的函数,进而分析T(n)随n的变化情况进而确定T(n)的数量级。算法的时间复杂度,也就是算法的时间量度,记作T(n)=O(f(n))。它表示随问题规模n的增大,算法执行时间的增长率和f(n)的增长率相同,称作算法的渐进时间复杂度,简称时间复杂度。其中f(n)是时间规模n的某个函数。

如果看的头疼,暂时理解为是衡量一个算法执行需要的计算工作量。

空间复杂度:

书上定义的是通过计算算法所需的存储空间实现,算法空间复杂度的计算公式S(n) = O(f(n)),其中,n为问题规模,f(n)为语句关于n所占存储空间的函数。

暂理解为是指执行这个算法所需要的内存空间。

定义理解完了,书上的理解不了,就理解成简单的。后面深入了解的时候,也许就理解作者的定义了,时间复杂度用的比较多,也较为丰富,我们先来看看时间复杂度。再看时间复杂度之前,我们需要看3个准则。看不懂没关系,知道有他们就好了,后续的内容慢慢就懂了。

如何推导大O阶:


(1)用常数1取代运行时间中的所有加法常数,如O(1)。


(2)在修改后的运行次数函数中,只保留最高阶数,如n²+n 为 O(n²)。


(3)如果最高阶数存在且不是1,则去除与这个项相乘的常数,如3n³ 为 O(n³)。

看一个算法。称为常数阶

  1. int sum = 0, n = 200// 执行一次  
  2. sum = (1 + n) * n / 2// 执行一次  
  3. System.out.println(sum); // 执行一次 
那么他的f(n)=1+1+1=3   时间复杂度O(fn) =1.为什么是1不是3呢?  看第一个准则。不管f(n)等于多大的常数,他的时间复杂度O(fn)都是1.。简单粗暴。

看第二个算法。称为线性阶

  1. for(int i = 0; i < n; i++){  
  2.     时间复杂度为O(1)的程序步奏 
  3. }  
执行次数f(n)=  n   那么时间复杂度O(fn)=n;

看第三个算法。称为对数阶

  1. int count = 1;  
  2. while(count < n){  
  3.     count = count * 2;  
  4. }  
有x个2相乘后大于n就会退出循环,利用高中数学知识由2的x次方等于n --> x = logn 那么O(fn)=O(logn)

看第四个算法。称为平方阶

  1. for(int i = 0; i < n; i++){  
  2.     for(int j = 0; j < n; j++){  
  3.         时间复杂度为O(1)的程序步奏 
  4.     }  
  5. }  
时间复杂度O(n*n)=O(,这个不难,那么看看下面这个算法

  1. for(int i = 0; i < n; i++){  
  2.     for(int j = i; j < n; j++){  
  3.         时间复杂度为O(1)的程序步奏 
  4.     }  
那么需要执行的次数就是n+(n-1)+(n-2)+....+1= n²/2+ n/2那么按照上面的规则其实时间复杂还是   O( )。 所以考验的其实还是高中的数学知识。

常用时间复杂度所耗费时间从小到大依次为:O(1) < O(logn) < O(n) < O(nlogn) < O(n²) < O(n³) < O(2n) < O(n!) < O()

至于空间复杂度,就是一般拿空间换时间了,算法的空间复杂度一般也以数量级的形式给出。如当一个算法的空间复杂度为一个常量,即不随被处理数据量n的大小而改变时,可表示为O(1);当一个算法的空间复杂度与以2为底的n的对数成正比时,可表示为O(log2n);当一个算法的空间复杂度与n成线性比例关系时,可表示为O(n)。用的好像并不多,通常没有说明的时候,一般都是问时间复杂度,时间复杂度是一个非常重要的概念,直接影响到我们的代码执行效率。


你可能感兴趣的:(大话数据结构阅读笔记)