数据结构与算法笔记1 数据结构和算法概述

141 阅读5分钟

1. 概念

1.1 数据

数据是信息的载体,是描述客观事物属性的数、字符及所有能输入到计算机中并被计算机程序识别和处理的符号的集合。数据是计算机程序加工的原料。

1.2 数据元素(根据业务需求确定)

数据的基本单位,通常作为一个整体进行考虑和处理。 一个数据元素可由若干数据项组成,数据项是构成数据元素的不可分割的最小单位。

image.png

1.3 数据结构

相互之间存在一种或多种特定关系的数据元素的集合。

1.4 数据对象

具有相同性质的数据元素的集合,是数据的一个子集。

2. 数据结构三要素

数据结构三要素:

1. 逻辑结构
2. 物理结构(存储结构)
3. 数据的运算

2.1 逻辑结构

逻辑结构:数据元素之间的逻辑关系是什么

image.png

2.1.1 集合

image.png

2.1.2 线性结构

image.png

2.1.3 树形结构

image.png

2.1.4 图结构

image.png

2.2 数据的物理结构(存储结构)

image.png

2.2.1 顺序存储

image.png

2.2.2 链式存储

image.png

2.2.3 索引存储

image.png

2.2.4 散列存储

image.png

注意

1. 若采用顺序处存储,各数据元素在物理上必须是连续的;若采用非顺序存储,各数据元素在物理上可以是离散的。

2. 数据的存储结构,影响存储空间分配的方便程度。

3. 数据的存储结构,影响对数据运算的速度。

2.3 数据运算

施加在数据上的运算包括运算的定义和实现。定义是针对逻辑结构的,指出运算的功能,实现是针对存储结构的。指出运算的具体步骤

3. 数据类型和抽象数据类型

数据类型是一个值的集合和定义在此集合上的一组操作的总称。

3.1 数据类型

    1. 原子类型:其值不可再分的数据类型。
    • 如bool型,int类型。
    1. 结构类型。其值可以再分解为若干成分(分量)的数据类型。
    • 如结构体等

3.2 抽象数据类型ADT

是抽象数据组织及与之相关的操作。 ADT用数学化的语言定义数据的逻辑结构、定义运算,与具体实现无关。

注意

  • 数据结构关心的是数据元素之间的关系,而非具体数据项的内容。

  • 探讨一种数据结构时,应该按照这样一种思路

      1. 定义逻辑结构(数据元素之间的关系)
      1. 定义数据的运算(针对现实需求,应该对这种逻辑结构进行什么样的运算)
      1. 确定某种存储结构,实现数据结构,并实现一些对数据结构的基本运算。

4. 算法

image.png

4.1 算法特性

    1. 有穷性,一个算法必须总在执行有穷步之后结束,且每一步都可在有穷时间内完成,

    算法必须是有穷的,程序可以是无穷的。

    1. 确定性,算法中每条指令必须有确切的含义,对于相同的输入只能得到相同的输出。
    1. 可行性,算法中描述的操作都可以通过已经实现的基本运算执行有限次来实现。
    1. 输入,一个算法有0个或多个输入,这些输入取自于某个特定的对象的集合。
    1. 输出,一个算法有1个或多个输出,这些输出是与输入有着某种特定关系的量。

4.2 算法设计目标

    1. 正确性
    • 能够正确解决问题。
    1. 可读性
    • 算法易读,帮助人们理解。
    1. 健壮性
    • 输入非法数据时,算法能适当的做出反应或进行处理,而不会产生莫名其妙的输出结果,
    1. 高效率与低存储量需求。
    • 高效率:执行速度快,时间复杂度低。
    • 低存储量需求:不费内存,空间复杂度低。

4.3 算法效率的度量:时间复杂度

事后统计不可行:

    1. 和机器性能有关
    2. 和编程语言有关
    3. 和编译程序产生的机器指令质量有关
    4. 有的算法不能事后统计

解决方法:

事前预估算法时间开销 T(n)T(n) 与问题规模 nn 的关系。 即算法的时间复杂度。

  • 一个算法的时间开销表达式,可以只考虑阶数高的部分。

    采用大O表示法T1(n)=O(f(n))T_{1}(n) = O (f(n)),大O表示“同阶”,同等数量级。即当n趋于无穷时,二者之比为常数。

4.3.1 运算规则

    1. 加法规则:多项相加,只保留最高阶的项,且系数变为1.
    1. 多项相乘,都保留。

大小关系

O(1)<O(log2n)<O(n)<O(nlong2n)<O(n2)<O(n3)<O(2n)<O(n!)<O(nn)O(1) <O(log_{2}n)<O(n)<O(nlong_{2}n)<O(n^{2})<O(n^{3})<O(2^{n})<O(n!)<O(n^{n})

image.png

不同阶算法的时间开销图示: 常对幂指阶

image.png

4.3.2 如何计算

    1. 顺序执行的代码只会影响常数项,可以忽略
    1. 只需挑循环中的一个基本操作分析它的执行次数和n的关系即可
    1. 如果有多层嵌套循环,只需关注最深层循环循环了几次。

示例1

image.png

示例2 一般只度量算法时间复杂度的一般情况和最坏情况

最坏时间复杂度:最坏情况下的算法时间复杂度

平均时间复杂度:所有输入示例等概率出现情况下,算法的期望运行时间。

image.png

4.4 算法效率的度量:空间复杂度

4.4.1 普通程序的内存开销

系统运行时的内存需求。用S(n)=O(f(n)) S(n) = O(f(n)) 来表示。对于空间复杂度为 O(1) O(1) 阶算法,其所需内存为常量,可称 **算法原地工作。 **

image.png

4.4.2 函数递归调用带来的内存开销

示例1

image.png

示例2

image.png