数据结构绪论 | 青训营笔记

23 阅读6分钟

这是我参与「第五届青训营 」伴学笔记创作活动的第 14 天

基本概念和术语

数据

数据元素

数据项 数据项是数据不可分割的最小单位

数据对象:是性质相同的数据元素的集合,是数据的子集 数据对象简称为数据

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

数据是数据元素的集合

image-20220408093455215

逻辑结构与物理结构

逻辑结构

逻辑结构分为以下四种:

  1. 集合结构 集合结构中的数据元素除了同属于一个集合外,它们之间没有其他关系。
  2. 线性结构 一对一
  3. 树形结构 一对多
  4. 图形结构 多对多

将每一个数据元素看做一个结点,用圆圈表示。

元素之间的逻辑关系用结点之间的连线表示.如果这个关系是有方向的,那么用

带箭头的连线表示。

物理结构

物理结构:是指数据的逻辑结构在计算机中的存储形式

数据元素的存储结构形式有两种:顺序存储和链式存储。

顺序储存结构

顺序存储结构:是把数据元素存放在地址连续的存储单元里,其数据间的逻辑关 系和物理关系是一致的

链式存储结构

链式存储结构:是把数据元素存放在任意的存储单元里,这组存储单元可以是连 续的,也可以是不连续的。

数据元素的存储关系并不能反映其逻辑关系,因此需要用 一个指针存放数据元素的地址,这样通过地址就可以找到相关联数据元素的位置

image-20220408094503856

抽象数据类型

数据类型

数据类型:是指一组性质相同的值的集合及定义在此集合上的一些操作的总称。

数据类型是按照值的不同进行划分的。

■ 原子类型:是不可以再分解的基本类型,包括整型、实型、字符型等。

■ 结构类型:由若干个类型组合而成,是可以再分解的。例如,整型数组是由若干整 型数据组成的。

抽象是指抽取出事物具有的普遍性的本质

抽象数据类型(Abstract Data Type, ADT):是指一个数学模型及定义在该模型 上的一组操作。抽象数据类型的定义仅取决于它的一组逻辑特性,而与其在计算机内 部如何表示和实现无关。

image-20220408093325993

算法

五个基本特性

算法具有五个基本特性:输入、输出、有穷性、确定性和可行性。

输入输出

算法具有零个或多个输入

算法至少有一个或多个输 出,算法是一定需要输岀的,不需要输出,你用这个算法干吗?输出的形式可以是打 印输出,也可以是返回一个或多个值等。

有穷性

有穷性:指算法在执行有限的步骤之后,自动结束而不会出现无限循环,并且每 一个步骤在可接受的时间内完成。

确定性

确定性:算法的每一步骤都具有确定的含义,不会出现二义性。

可行性

可行性:算法的每一步都必须是可行的,也就是说,每一步都能够通过执行有限 次数完成

综上,好的算法,应该具有正确性、可读性、健壮性、髙效率和低存储量的特 征。

比较时间效率

事后分析估算方法 一般不用 不准确误差较大

事前分析估算方法 重要的是把基本操作的数量与输入规模关联 起来,即基本操作的数量必须表示成输入规模的函数

函数的渐近增长

image-20220409093641276

结论

  1. 与最高次项相乘的常数并不重要
  2. 最高次项的指数大 的,函数随着n的增长,结果也会变得增长特别快
  3. 判断一个算法的 效率时,函数中的常数和其他次要项常常可以忽略,而更应该关注主项(最高阶项) 的阶数。

事前估算方法的理论依据,通过算法时间复杂度 来估算算法时间效率。

某个算法,随着n的增大,它会越来越优于另一算法,或 者越来越差于另一算法

算法时间复杂度

定义

image-20220409095849958

image-20220409100032258

大O记法:这样用大写O()来体现算法时间复杂度的记法,

一般情况下,随着n的增大,T(n)增长最慢的算法为最优算法。

image-20220409100400276

推导大O阶方法

  1. 用常数1取代运行时间中的所有加法常数。
  2. 在修改后的运行次数函数中,只保留最高阶项。
  3. 如果最高阶项存在且不是1,则去除与这个项相乗的常数。得到的结果就是大0阶。

常数阶

高斯定律的算法 这个算法的运行次数函数是f (n) =3。根据我们推导大。阶的方法,第一步就是 把常数项3改为1。在保留最高阶项时发 现,它根本没有最高阶项,所以这个算法的 时间复杂度为0(1)。

3次和12次执行的差异。这种与问 题的大小无关(n的多少),执行时间恒定的算法,我们称之为具有0(1)的时间复杂 度,又叫常数阶。

不管这个常数是多少,我们都记作。⑴,而不能是0(3)、0(12)等其他任 何数字,这是初学者常常犯的错误。

对于分支结构而言,无论是真,还是假,执行的次数都是恒定的,不会随着n的 变大而发生变化,所以单纯的分支结构(不包含在循环结构中),其时间复杂度也是 0(1) 。

线性阶

我们要分析算法的复杂度,关键就是要分 析循环结构的运行情况

它的循环的时间复杂度为0(n),因为循环体中的代码须要执行n 次

对数阶

image-20220409102044459

平方阶

循环的时间复杂度等于循环体的复杂度乘以该循环运行 的次数。

image-20220409102457398

常见的时间复杂度

image-20220409103908110

image-20220409103955816

最坏情况与平均情况

最坏情况运行时间是一种保证,那就是运行时间将不会再坏了。在应用中,这是 一种最重要的需求,通常,除非特别指定,我们提到的

运行时间都是最坏情况的运行时间。

平均运行时间是所有情况中最有意义的,因为它是期望的运行时间。也就是说, 我们运行一•段程序代码时,是希望看到平均运行时间

的。可现实中,平均运行时间很 难通过分析得到,一般都是通过运行一定数量的实验数据后估算出来的。

算法空间复杂度

定义

image-20220409105434732

image-20220409105733657

通常,我们都使用“时间复杂度”来指运行时间的需求,使用“空间复杂度”指 空间需求。当不用限定词地使用“复杂度”时,通常都是指时间复杂度。

总结

image-20220409105900626

image-20220409110022104