前言
- 数据结构:是指相互之间存在一种或多种特定关系的数据元素的集合用计算机存储、组织数据的方式。数据结构分别为逻辑结构、(存储)物理结构和数据的运算三个部分。
1.1. 概念术语
- 数据(Data)是能被计算机处理的符号或符号集合
- 数据元素(data element)是数据的基本单位
- 数据项(data item)组成数据元素的最小单位
- 数据对象(data object)是性质相同的数据元素的集合,是数据的一个子集
- 数据结构(data structure)是数据的组织形式,数据元素之间存在的一种或多种特定关系的数据元素集合
- 数据类型(data type)是按照数据值的不同进行划分的可操作性。在C语言中还可以分为原子类型和结构类型。原字类型是不可以再分解的基本类型,包括整型、实型、字符型等。结构类型是由若干个类型组合而成,是可以再分解的
1.2. 逻辑结构
- 集合结构:集合的数据元素没有其他关系,仅仅是因为他们挤在一个被称作“集合”的盒子里。
- 线性结构:线性的数据元素结构关系是一对一的,并且是一种先后的次序
- 树形结构:树形的数据元素结构关系是一对多的
- 图形结构:图的数据元素结构关系是多对多的
1.3. 数据存储结构
存储结构(storage structure)也称为物理结构(physical structure),指的是数据的逻辑结构在计算机中的存储形式。数据的存储结构一般可以反映数据元素之间的逻辑关系
- 顺序存储结构:是把数据元素存放在一组存储地址连续的存储单元里,其数据元素间的逻辑关系和物理关系是一致的
- 链式存储结构:是把数据元素存放在任意的存储单元里,这组存储单元可以是连续的,也可以是不连续的,数据元素的存储关系并不能反映其逻辑关系,因此需要借助指针来表示数据元素之间的逻辑关系
总结 逻辑结构是面向问题的,而物理结构就是面向计算机的. 其基本的目标就是将数据以及逻辑关系存储到计算机的内存中.
1.4. 抽象数据类型
1.4.1 数据类型
数据类型: 是指一组性质相同值的集合以及定义在此集合的一些操作的总称。在C语言中,按照取值不同,数据类型可以分为2类:
- 原子类型: 是不可以在分解的基本数据类型,包含整型,浮点型,字符型等;
- 结构类型: 由若干类型组合而成,是可以再分解的.例如,整型数组就是由若干整型数据组成的.
1.4.2 抽象数据类型
抽象数据类型(abstract data type,ADT)是描述具有某种逻辑关系的数据模型,并对在数学模型上进行的一组操作。抽象数据类型描述的是一组逻辑上的特性,与在计算机内部表示无关,计算机中的整数数据类型是一个抽象数据类型,不同处理器可能实现方法不同,但其逻辑特性相同,即加、减、乘、除等运算是一致的。“抽象”的意思是数据类型的数学抽象特性而不是指它们的实现方法。抽象数据类型体现了程序设计中的问题分解、抽象、信息隐藏等特性,可以把现实中的大问题分解为多个规模小且容易处理的小问题,然后建立起一个能被计算机处理的数据,并把每个功能模块的实现细节作为一个独立的单元,从而使具体实现过程隐藏起来。就类似建一栋房子,分成若干个小任务,如地皮规划、图纸设计、施工、装修等,整个过程与抽象数据类型中的问题分解类似。而搬砖人不需要了解图纸设计如何,设计图纸人员不需要了解施工的地基、砌墙的具体细节,装修工人不用关系图纸和搬砖过程,这就是抽象类型中的信息隐藏。
抽象数据类型的概念可能让初学者不太容易理解。例如线性表的抽象数据类型的描述数据对象集合:线性表的数据对象集合为{a1,a2,a3,····,an},每个元素的类型均为DataType。其中,除了第一个元素a1外,每一个元素有且只有一个直接前驱元素;除了最后一个元素an外,每一个元素有且只有一个直接后继元素。数据元素之间的关系是一对一的。
1.5算法
算法(algorithm)是解决特定问题求解步骤的描述,在计算机中表现为有限的操作序列。在数据类型建立起来之后,就要对这些数据类型进行操作,建立起运算的集合即程序。运算的建立、方法好坏直接决定着计算机程序原型效率的高低。
1.5.1. 数据结构和算法的关系
两者基友联系又有区别。联系是程序=算法+数据结构。数据结构是算法实现的基础,算法总是要依赖某种数据结构来实现的。算法的操作对象是数据结构。区别是数据结构关注的是数据的逻辑结构、存储结构有一集基本操作,而算法更多的是关注如何在数据结构的基本上解决实际问题。算法是编程思想,数据结构则是这些思想的基础。
1.5.2. 特性
- 输入
- 输出
- 有穷性: 指的是算法在执行有限的步骤之后,自动结束而不会出现无限循环,且每一个步骤在可接受的时间内完成.
- 确定性: 算法的每一个步骤都具有确定的含义,不能出现二义性; 算法在一定条件下,只有一条执行路径,相同的输入只能有唯一的输出结果.
- 可行性
1.5.3. 算法设计要求
- 正确性
- 可读性
- 健壮性
- 时间效率高和存储量低
1.6. 时间复杂度
时间复杂度,又称时间复杂性,算法的时间复杂度是一个函数,它定性描述该算法的运行时间。时间复杂度常用大O符号表述。
为了更好地描述时间复杂度有以下规定:
- 所有的常数时间复杂度用1表示。
- 只保留最高阶的时间复杂度。
- 去除最高阶时间复杂度的系数。
算法的时间复杂度是衡量一个算法好坏的重要指标。一般情况下,随着规模n的增大,次数T(n)的增长较慢的算法为最优算法。常见时间复杂度从小到大依次排列:
O(1) < O(logn) < O(n)< O(nlogn) < O(n²)<O(n³) < O(2^n) <O(n!) < O(n^n)
常见的时间复杂度
- 常数阶
- 线性阶
- 对数阶
- 平方阶
- 立方阶
- nlogn阶
- 指数阶
时间复杂度描述的是算法的最坏情况。
1.7 空间复杂度
空间复杂度(space complexity)作为算法所需存储空间的量度,记做S(n) = O (f(n))。其中,n为问题的规模;f(n)为语句关于n的所占存储空间的函数。
对于一个算法,所有的变量、指令、结果都需要存储空间,另外在算法的执行过程中,临时变量和临时结果也需要保留下来以便下一步计算,这些称为算法执行时的辅助空间。
空间复杂度主要定性描述算法所需的辅助空间。
对一个算法,其时间复杂度和空间复杂度往往会互相影响. 当追求一个较好的时间空间复杂度时,可能会导致占用较多的存储空间. 即可能会使用空间复杂度的性能变差.反之亦然. 不过,通常情况下,鉴于运算空间较为充足,人们都以算法时间空间复杂度作为算法优先的衡量指标。