- 数据结构
数据结构是一门研究非数值计算的程序设计问题中的操作对象,以及它们之间的关系和操作等相关问题的学科。 - 数据
是信息的载体,描述客观事物属性的数、字符以及所有能输入到计算机中且能被计算机识别和处理的符号集合。包括数值型和非数值型。
(两个前提:该符号能输入到计算机中;能被计算机程序处理。) - 数据元素
数据的基本单位,通常作一个整体进行考虑和处理,由若干数据项组成,也被称为记录。(数据的组成部分) - 数据项
数据项是数据不可分割的最小单位,也称字段或域。
(数据元素的组成部分) - 数据对象
具有相同性质的数据元素的集合,是数据的子集。
(相同数据项的数据元素)
数据>数据对象>数据元素>数据项
- 数据结构
相互之间存在一种或多种特定关系的数据元素的集合。 - 数据结构三要素
- 1.数据的逻辑结构
指数据对象中数据元素之间的相互关系,即从逻辑关系上描述数据,与数据的存储无关,独立于计算机。
逻辑结构与数据元素本身形式、相对位置、所含数据元素个数和数据存储无关。
逻辑结构的表示方法:有图表和二元组(详见后数据类型)。
数据的逻辑结构分为线性结构和非线性结构。线性表是常见的线性结构;集合、树和图是典型的非线性结构。
逻辑结构的类型- 集合结构
数据元素除同属于一个集合关系外别无其他关系。 - 线性结构
数据元素之间是一对一的线性关系。
开始元素和终端元素唯一;
除开始元素外,其余元素有且仅有一个前驱元素;
除终端元素外,其余元素有且仅有一个后继元素。 - 树形结构
数据元素之间是一对多的层次关系。
开始元素唯一,终端元素不唯一;
除开始元素外,其余元素有且仅有一个前驱元素;
除终端元素外,其余元素至少有一个后继元素。 - 图形结构
数据元素之间是多对多的关系。
- 集合结构
- 2.数据的存储结构
指数据的逻辑结构在计算机中的存储形式,也称映像或物理结构。
包括数据元素的表示和关系的表示,即既要存储逻辑结构中的每一个数据元素,又要存储数据元素之间的逻辑关系。
数据的存储结构是逻辑结构用计算机语言的实现,依赖于计算机语言。
数据的存储结构分为顺序结构和非顺序结构。顺序存储是常见的顺序结构;链式存储、索引存储和散列存储是非顺序结构。
存储结构的类型- 顺序存储结构
把数据元素存放在地址连续的存储单元里,即逻辑上相邻的数据元素存储在物理位置上也相邻的存储单元。其数据间的逻辑关系和物理关系是一致的,元素之间的关系可以有存储单元的邻接关系来体现。
优点:可以实现随机存取;存储密度大,每个元素占用最少的存储空间;
缺点:动态操作效率差;只能使用相邻的一整块存储单元,因此可能产生较多的外部碎片。 - 链式存储结构
将数据元素存放在任意的存储单位里,不要求逻辑上相邻的元素在物理位置上也相邻。 物理关系并不能反映其逻辑关系,需借助指示元素存储地址的指针表示元素之间的逻辑关系。
优点:不会出现碎片现象,充分利用所有存储单元;便于动态操作;
缺点:每个元素因存储指针而占用额外的存储空间,并且只能实现顺序存取。 - 索引存储结构
在存储元素的信息同时,还建立附加的索引表。索引表中的每一项称为索引项,一般形式是:(关键字,地址),指示存储结点的存储位置(下标)或存储区间的端点(下标,非稠密索引),兼有动态和静态特性。
优点:检索速度快;
缺点:建立索引表,增加空间开销;操作数据时要修改索引表,增加时间开销。 - 散列存储结构
根据元素的关键字通过哈希函数计算出该元素的存储地址,又称hash存储。
优点:检索速度快;
缺点:hash存储只存储元素的数据,不存储元素的逻辑关系;
只适合要求对数据能够进行快速查找和插入的场合;
解决hash冲突时,增加了时间和空间的开销。
- 顺序存储结构
- 3.数据的运算
施加在数据上的运算包括运算的定义和实现。
运算的定义是针对逻辑结构,指出运算的功能;
运算的实现是针对存储结构,指出运算的具体操作步骤。
- 1.数据的逻辑结构
数据逻辑结构和存储结构的关联:一种数据逻辑结构根据需要可以用多种存储结构进行存储,而采用不同的存储结构,其数据处理的效率往往是不同的。
例如:线性表的插入、删除操作,在顺序存储方式下平均移动一半的元素,时间复杂度为O(n);在链式存储方式下,插入和删除的时间复杂度都是O(1)。
- 数据类型
是指一组性质相同的值的集合及定义在此集合上的一些操作的总称。- 原子类型:其值不可分解的基本数据类型。
- 结构类型:由若干个类型组合而成,可以再分解为若干成分(分量)的数据类型。
例如数组。 - 抽象数据类型:抽象数据组织和与之相关的操作。
- 抽象数据结构
Abstract Data Type(ADT):是指一个数据(数学)模型及定义在该模型上的一组操作。(从问题的数学模型中抽象出来的逻辑数据结构和逻辑数据结构上的运算,而不考虑计算机的具体存储结构和运算的具体实现方法。)
抽象数据类型的定义仅取决于它的一组逻辑特性,而与其在计算机内部的表示和实现无关,即不论其内部结构如何变化,只要数学特性不变,不影响其外部的使用。(数据对象和数据运算的声明与数据对象的表示和数据运算的实现相互分离)
“抽象”的意义在于数据类型的数学抽象特性。(定义了:一个数据对象、数据对象中各数据元素间的关系、数据元素的操作)。
抽象数据类型体现了程序设计中问题分解、抽象和信息隐藏的特性。 - 数据结构表示方法
- 二元组
数据结构形式化描述为Data-Structure= (D,R)
D = {di|1≤ i ≤ n,n ≥ 0} D是数据元素的有限集
R = {rj|1≤ i ≤ m,m ≥ 0} R是D上的关系有限集
R中的一个关系r是序偶的集合,对于r中的任一序偶<x,y>(x,y∈D),表示元素x和元素y是相邻的,即x在y前,y在x后,x称为该序偶的第一元素,y称为该序偶的第二元素。x是y的直接前驱,即前驱元素;y是x的直接后继,即后继元素。若某个元素没有前驱元素,则称该元素为开始元素;若某个元素没有后继元素,则称该元素为终端元素。 - 三元组
ADT包括数据对象(即数据元素的集合)、数据关系和基本运算三方面内容。
一个抽象数据类型可用 (D,S,P) 三元组表示。
其中D是数据对象,S是定义在D上的关系集,P是D中数据运算的基本运算集。
- 二元组
- 算法
对特定问题求解步骤的一种描述,是指令的有限序列,其中每条指令表示一个或多个操作。(即解决问题的步骤序列)
一个算法具有5个重要特性:有穷性、确定性、可行性、输入和输出。
一个好算法的目标:正确性、可读性、健壮性和效率与低存储量需求。 - 算法分析
指分析算法占用计算机资源的多少。
分析算法占用CPU时间的多少称为时间性能分析;
分析算法占用内存空间的多少称为空间性能分析。 - 算法效率的度量
- 时间复杂度
-
算法的两种时间性能方法
1.事后统计法:编写算法对应程序,统计执行时间。
2.事前分析法:算法的执行时间是问题规模的函数 -
算法的频度T(n)
一个语句的频度指该语句在算法中被重复执行的次数。
算法中所以语句的频度之和称为算法的频度,记作T(n),是该算法问题规模n的函数。 -
T(n)的“O”表示
时间复杂度只要分析T(n)的数量级。算法中的基本运算(最深层循环内的语句)的频度与T(n)同数量级,所以通常采用算法中基本运算的频度f(n)来分析算法的时间复杂度。
取f(n)中随n增长最快的项将其系数置为1作为时间复杂度。
例如f(n)=an3+bn2+cn+d,则其时间复杂度为O(n3)。
因此,算法的时间复杂度记为T(n)=O(f(n)),
上式中O是T(n)的数量级,为T(n)找一个上界f(n)。
数学定义:若T(n)和f(n)是定义在正整数集合上的两个函数,则存在正常数C和n0,使得当n≥n0时,都满足0≤ T(n) ≤ C*f(n)。
lim x → n 0 ∣ T ( n ) ∣ ∣ f ( n ) ∣ = C ≠ 0 \lim_{x\to n0}\frac{|T(n)|}{|f(n)|}=C \neq 0 limx→n0∣f(n)∣∣T(n)∣=C̸=0 成立
所以算法时间复杂度也称为渐进时间复杂度,它表示随问题规模n的增大,算法执行时间的增长率和f(n)的增长率相同。 -
时间复杂度
算法的时间复杂度不仅依赖于问题规模n,也取决于待输入数据的性质。
最坏时间复杂度:在最坏情况下,算法的时间复杂度。
平均时间复杂度:所有可能输入实力在等概率出现的情况下,算法期望运
行时间。
最好时间复杂度:在最好情况下,算法的时间复杂度。
一般情况下总考虑最坏时间复杂度,以保证算法的运行时间不会超出。分析一个算法的时间复杂性,有如下规则:
加法规则:
T(n) = T1(n)+T2(n) = O(f(n)) + O(g(n)) = O(max(f(n),g(n)))
乘法规则:
T(n) = T1(n)*T2(n) = O(f(n)) * O(g(n)) = O(f(n)*g(n)) -
常见的时间复杂度
O(1)<O(log2n)<O(n)<O(nlog2n)<O(n2)<O(n3)<O(2n)<O(n!)<O(nn)
-
- 空间复杂度
算法的空间复杂度S(n),定义为该算法所耗费的存储空间,它是问题规模n的函数渐进时间复杂度也称为空间复杂度,记作S(n)=O(g(n))。
一个上机程序除了需要存储空间来存放本身所用的指令、常数、变量和输入数据外,也需要一些对数据进行操作的工作单元和存储一些为实现计算所需信息的辅助空间。若输入数据所占空间只取决于问题本身和算法无关,则只需分析除输入和程序之外的额外空间。
算法原地工作是指算法所需辅助空间是常量,即O(1)。
- 时间复杂度