数据结构-概念了解

前提

这只是我的一些笔记

数据结构算法广义理解:

  • 数据结构就是指一组数据的存储结构。
  • 算法就是操作数据的一组方法

数据结构与算法的全面知识点
## 学习数据结构准备

10个数据结构:

  • 数组、链表、栈、队列、散列表、二叉树、堆、跳表、图、Trie树;

10个算法:

  • 递归、排序、二分查找、搜索、哈希算法、贪心算法、分治算法、回溯算法、动态规划、字符串匹配算法

怎么学习

  1. “边学边练”这一招非常有用。建议你每周花1~2个小时的时间,集中把这周的三节内容涉及的数据结构和算法,全都自己写出来,用代码实现一遍。

  2. 知识需要沉淀,不要想试图一下子掌握所有

复杂度分析:

时间复杂度

大O时间复杂度表示法

大O时间复杂度实际上并不具体表示代码真正的执行时间,而是表示代码执行时间随数据规模增长的变化趋势,所以,也叫作渐进时间复杂度(asymptotic time complexity),简称时间复杂度

时间复杂度分析

  1. 只关注循环执行次数最多的一段代码

  2. 加法法则:总复杂度等于量级最大的那段代码的复杂度

  3. 乘法法则:嵌套代码的复杂度等于嵌套内外代码复杂度的乘积

几种常见时间复杂度分析

粗略分为多项式量级非多项式量级。其中非多项式量级只有两个:O( 2 n 2{n} )和O( 2 ! 2! )。
在这里插入图片描述

  1. O(1)

  2. O( l o g n log{n} )O( n l o g n nlog{n} )

    O( l o g n log{n} )

    i=1;
     while (i <= n)  
     {   i = i * 3; }
    

    归并排序、快速排序的时间复杂度都是 n l o g n nlog{n}

    • 不管是以2为底、以3为底,还是以10为底,我们可以把所有对数阶的时间复杂度都记为O( l o g n log{n} )。为什么呢?

      O( l o g 3 n log_3{n} )就等于O( l o g 3 2 log_3{2} ) × \times O( l o g 2 n log_2{n} ) ,所以O( l o g 3 n log_3{n} ) = O(C × \times l o g 2 n log_2{n} ),其中C= l o g 3 2 log_3{2} 是一个常量。在采用大O标记复杂度的时候,可以忽略系数,即O(Cf(n)) = O(f(n))。所以,O( l o g 2 n log_2{n} )就等于O( l o g 3 n log_3{n} )。因此,在对数阶时间复杂度的表示方法里,我们忽略对数的“底”,统一表示为O(logn)。

  3. O(m+n)、O(m × \times n)

    代码的复杂度由两个数据的规模来决定。

    int cal(int m, int n) {
      int sum_1 = 0;
      int i = 1;
      for (; i < m; ++i) {
        sum_1 = sum_1 + i;
      }
    
      int sum_2 = 0;
      int j = 1;
      for (; j < n; ++j) {
        sum_2 = sum_2 + j;
      }
    
      return sum_1 + sum_2;
    }
    

    m和n是表示两个数据规模,不能简单地利用加法法则,省略掉其中一个。所以,上面代码的时间复杂度就是O(m+n)。

    但是乘法法则继续有效:T1(m)*T2(n) = O(f(m) * f(n))。

空间复杂度分析

空间复杂度全称就是渐进空间复杂度(asymptotic space complexity),表示算法的存储空间与数据规模之间的增长关系

我们常见的空间复杂度O(1)、O(n)、O(n2 )

img

课后思考

  • 有人说,我们项目之前都会进行性能测试,再做代码的时间复杂度、空间复杂度分析,是不是多此一举呢?而且,每段代码都分析一下时间复杂度、空间复杂度,是不是很浪费时间呢?你怎么看待这个问题呢?

    我不认为是多此一举,渐进时间,空间复杂度分析为我们提供了一个很好的理论分析的方向,并且它是宿主平台无关的,能够让我们对我们的程序或算法有一个大致的认识,让我们知道,比如在最坏的情况下程序的执行效率如何,同时也为我们交流提供了一个不错的桥梁,我们可以说,算法1的时间复杂度是O(n),算法2的时间复杂度是O(logN),这样我们立刻就对不同的算法有了一个“效率”上的感性认识。

    当然,渐进式时间,空间复杂度分析只是一个理论模型,只能提供给粗略的估计分析,我们不能直接断定就觉得O(logN)的算法一定优于O(n), 针对不同的宿主环境,不同的数据集,不同的数据量的大小,在实际应用上面可能真正的性能会不同,个人觉得,针对不同的实际情况,进而进行一定的性能基准测试是很有必要的,比如在统一一批手机上(同样的硬件,系统等等)进行横向基准测试,进而选择适合特定应用场景下的最有算法。

    综上所述,渐进式时间,空间复杂度分析与性能基准测试并不冲突,而是相辅相成的,但是一个低阶的时间复杂度程序有极大的可能性会优于一个高阶的时间复杂度程序,所以在实际编程中,时刻关心理论时间,空间度模型是有助于产出效率高的程序的,同时,因为渐进式时间,空间复杂度分析只是提供一个粗略的分析模型,因此也不会浪费太多时间,重点在于在编程时,要具有这种复杂度分析的思维。

最好、最坏、平均、均摊时间复杂度

  • 最好情况时间复杂度就是,在最理想的情况下,执行这段代码的时间复杂度**。

  • 平均时间复杂度的全称应该叫加权平均时间复杂度或者期望时间复杂度

  • 最坏情况时间复杂度就是,在最糟糕的情况下,执行这段代码的时间复杂度

  • 均摊时间复杂度

猜你喜欢

转载自blog.csdn.net/qq_39009130/article/details/104956931