zoukankan      html  css  js  c++  java
  • 数据结构与算法教程(一)——数据结构基础

    文章目录

    1. 复杂度

      1.1 定义

      1.2 表示方法

      1.3 复杂度计算方法遵循的原则

        1.3.1 复杂度与常系数无关

        1.3.2 选择高阶的复杂度作为结果

      1.4 经验数值

    2. 代码优化的方法论

      2.1 暴力解题

      2.2 剔除掉无用的参数或者存储

      2.3 时空转换

    3. 数据结构基础

      3.1 数据处理的基本操作

      3.2 链表的分类(单向/循环/双向/双向循环)

      3.3 链表的增删查

    1. 复杂度

    1.1 定义

    复杂度是衡量代码运行效率的重要的度量因素计算机执行一段程序,消耗的是计算时间和存储空间,需要衡量的就是时间复杂度和空间复杂度。引入复杂度这个概念,我们就能用它来衡量程序运行的效率。

    1.2 表示方法

    复杂度是与计算的数据量个数n有关的函数。假设你的代码复杂度是 f(n),那么就用个大写字母 O 和括号,把 f(n) 括起来就可以了,即 O(f(n))。

    例如:

      O(n):表示计算的个数n与复杂度线性相关

      O(logn):表示计算的个数n与复杂度对数相关

    1.3 复杂度计算方法遵循的原则

    1.3.1 复杂度与常系数无关

    如某段程序的复杂度是O(2n),O(2n) = O(n) + O(n),那最终这段程序的复杂度还是记作O(n)。

    1.3.2 选择高阶的复杂度作为结果

    如某段程序的复杂度是O(n2 + n) ,O(n2 + n) = O(n2) + O(n),随着n的增大,n2增大的幅度要远远大于n,所以最终复杂度记为O(n2)。

    注:O(1)表示一个特殊的复杂度

    1.4 经验结论

    •  一个顺序结构的代码,时间复杂度是 O(1)。
    • 二分查找,或者更通用地说是采用分而治之的二分策略,时间复杂度都是 O(logn)。
    • 一个简单的 for 循环,时间复杂度是 O(n)。
    • 两个顺序执行的 for 循环,时间复杂度是 O(n)+O(n)=O(2n),其实也是 O(n)。
    • 两个嵌套的 for 循环,时间复杂度是 O(n²)

        

    2. 代码优化的方法论

    程序优化的核心思路如 2.1 ~ 2.3 所示的三步

    2.1 暴力解题

    暴力解法即不计时间和空间资源的消耗,把题目做出来。

    2.2 剔除掉无用的参数或者存储

    将代码中的无效操作,无效计算或者存储剔除掉,来降低时间或者空间复杂度。

    2.3 时空转换

    代码执行过程计算机的内存空间不够,可以采购更高性能的计算机;但消耗的的时间则是无法弥补的,所以说空间是廉价的,时间是无价的。所以我们需要将时间复杂度向空间复杂度进行转换。具体方式是采用更复杂的数据结构,进行时间复杂度向空间复杂度的转换

    3. 数据结构基础

    3.1 数据处理的基本操作

    要想灵活使用数据结构,就要先知道数据结构在代码中被处理的基本动作或操作。数据基本操作包括以下三种情况。

    • 找:看能否在数据结构中查找到这个数据。
    • 加:针对没有出现的情况,在数据结构中增加这个数据。
    • 除:在数据结构中对这个数据进行删除的操作。

    要想降低复杂度,就要设计合理的数据结构。而合理的数据结构,就要从问题本身出发,我们可以按照下面列举的三步来考虑

    • 首先,我们要看代码对数据进行了怎样的操作
    • 然后,再根据分析出来的基本操作,看哪个操作最影响效率?对时间复杂度的损耗最大?
    • 最后,选择合理的数据结构,看哪种数据结构最能帮助你提高数据操作的使用效率。

    这3步构成了设计合理数据设计的方法论,也是设计数据结构的核心思想。

    3.2 链表的分类

     线性表:线性表是n个数据元素的有限序列,最常用的是链式表达,常叫做线性链表或者链表。在链表中存储的数据元素叫做节点,一个节点就存储一条数据。每个节点包括两个部分:

    • 第一是具体的数值;
    • 第二是指向下一个节点的指针

           

    在链表的最前端,通常会有一个头指针指向第一个节点。在链表的最后一个节点,由于它之后再没有节点,所以它的指针是一个空指针

          

    上述链表只能通过上一个节点的指针找到下一个节点,反之则不行,所以这种链表称为单向链表

    为了弥补单向链表的不足,我们对之改造:

    • 把链表最后一个节点的指针指向第一个节点,则得到循环链表
    • 给链表添加一个指向上一个节点的指针,这样得到了双向链表

         

          

    再结合双向链表和循环链表,就可以得到双向循环链表

            

     3.3 链表的增删查

     

      

    参考资料:《重学数据结构与算法》——公瑾,中科院博士,资深算法专家。

    日拱一卒,功不唐捐
  • 相关阅读:
    Java 读取txt文件,读取结果保存到数据库
    Java 读取大文件方法
    利用File类过滤器列出目录下的指定目录或文件
    Java 读取指定目录下的文件名和目录名
    利用js日期控件重构WEB功能
    简洁js日历控件的使用
    Tomcat中配置URIEncoding="UTF-8"来处理中文的方法
    Java MVC 增删改查 实例
    严重:The web application [web01] appears to have started a thread named ...
    警告: [SetPropertiesRule]{Server/Service/Engine/Host/Context} 解决方法
  • 原文地址:https://www.cnblogs.com/YLLLike/p/12937263.html
Copyright © 2011-2022 走看看