第一章 绪论
目录
文章目录
前言
20世纪60年代初期,“数据结构”有关的内容散见于操作系统、编译原理等课程中。 1968年,“数据结构”作为一门独立的课程被列人美国一些大学计算机科学系的教学计划。同年,著名计算机科学家唐纳德 •克努特(D.E.Knuth)教授发表了 《计算机程序设计艺术》第一卷《基本算法》。这是第一本较系统地闸述“数据结构” 基本内容的著作。之后,随着大型程序和大规模文件系统的出现,结构化程序设计成为程序设计方法学的主要研究方向,人们普遍认为程序设计的实质就是为所处理的问题选择一种好的数据结构,并在此结构基础上施加一种好的算法,著名科学家洪斯( Wirth)教授的 《算法+数据结构-程序》 正是这种观点的集中体现。
目前,数据结构在计算机科学中是一门综合性的专业基础课。数据结构的研究不仅涉及计算机硬件(特别是编码理论、存储装置和存取方法等)的研究范围,而且和计算机软件的研究有着密切的关系,无论是编译程序还是操作系统都涉及数据元素在存储器中的分配问题。在研兖信息检秦时也必须考虑如何组织数据,以使查找和存取数据元素更为方便。因此,可以认为,数据结构是介于数学、计算机硬件和软件三者之间的一门核心课程。
有关“数据结构〞 的研究仍不断发展,一方面,面向各专门领城中特殊问题的数据结构正在研究和发展;另一方面,从抽象数据类型的观点来讨论数据结构,已成为一种新的趋势,越来越被人们所重视。
数据结构的基本概念和术语
数据、数据元素、数据项和数据对象
- 数据:是客观事物的符号表示,是所有能输入计算机中并被计算机程序处理的符号的总称
- 数据元素:是数据的基本单位
- 数据项:是组成数据元素的、有独立含义的、不可分割的最小单位
- 数据对象:是性质相同的数据元素的集合,是数据的一个子集
数据结构
数据结构:是相互之间存在一种或多种特定关系的数据元素的集合,数据结构包括逻辑结构和存储结构两个层次
- 逻辑结构
- 是从逻辑关系上描述数据,它与数据的存储无关是独立于计算机的,抽象的数据模型
- 数据的逻辑结构通常有4类基本逻辑结构,有2种划分方式
- 集合结构:数据元素之间除了“属于同一集合”的关系外,别无其它关系
- 线性结构:数据元素之间存在一对一的关系
- 树结构:数据元素之间存在一对多的关系
- 图结构或网状结构:数据元素之间存在多对多的关系
- 存储结构(物理结构)
- 顺序存储结构
- 链式存储结构
数据类型和抽象数据类型
- 数据类型
- 是一个值的集合和定义在这个值集上的一组操作的总称
- 抽象数据类型(Abstract Data Type, ADT)
- 一般由用户定义的、表示应用问题的数学模型,以及定义在这个模型上的一组操作的总称,具体包括三个部分:数据对象,数据对象上关系的集合以及对数据对象的基本操作的集合
- 抽象数据类型的定义格式如下
ADT 抽象数据类型名{
数据对象:<数据对象的定义>
数据关系:<数据关系的定义>
基本操作:<基本操作的定义>
}ADT 抽象数据类型名
算法和算法的分析
算法的定义及特性
- 算法是为了解决某类问题而规定的一个有限长的操作序列
- 算法有5个重要特性
- 有穷性
- 确定性
- 可行性
- 输入
- 输出
评价算法优劣的基本标准
- 正确性
- 可读性
- 健壮性
- 高效性
算法的时间复杂度
- 算法效率分析的目的是看算法实际是否可行,并在同一问题存在多个算法时,可进行时间和空间性能上的比较,选优的算法
- 衡量算法效率的方法主要有两类:事后统计法和事前估算法
时间复杂度的分析举例
- 常量阶示例 T(n) = O(1)
{
x++;
s = 0;
}
- 线性阶示例 T(n) = O(n)
for(i = 0; i < 10000; i++)
{
x++;
s = 0;
}
- 平方阶示例 T(n) = O ( n 2 ) (n^2) (n2)
x = 0;y = 0;
for (k = 1; k <= n; k++)
{
x++;
}
for (i = 1; i <= n; i++)
{
for (j = 1; j <= n; j++)
{
y++;
}
}
- 立方阶示例 T(n) = O ( n 3 ) (n^3) (n3)
x = 1;
for(i = 1; i <= n; i++)
{
for(j = 1; j <= i; j++)
{
for(k = 1; k <= j; k++)
{
x++;
}
}
}
有内向外分析出语句执行次数为:
∑ i = 1 n ∑ j = 1 i ∑ k = 1 j 1 = ∑ i = 1 n ∑ j = 1 i j = ∑ i = 1 n i ( i + 1 ) 2 = 1 2 [ n ( n + 1 ) ( 2 n + 1 ) 6 + n ( n + 1 ) 2 ] \sum_{i=1}^{n}\sum_{j=1}^{i}\sum_{k=1}^{j}1 = \sum_{i=1}^{n}\sum_{j=1}^{i}j = \sum_{i=1}^{n}\frac{i(i+1)}{2} = \frac{1}{2}[\frac{n(n+1)(2n+1)}{6}+ \frac{n(n+1)}{2}] i=1∑nj=1∑ik=1∑j1=i=1∑nj=1∑ij=i=1∑n2i(i+1)=21[6n(n+1)(2n+1)+2n(n+1)]
- 对数阶示例 T(n) = O ( l o g 2 n ) (log_2n) (log2n)
for(i = 1; i <= n; i=i*2)
{
x++;
s = 0;
}
设循环体内两条基本语句频度为 f ( n ) f(n) f(n),则有 2 f ( n ) ≤ n 2^{f(n)} \leq n 2f(n)≤n, f ( n ) ≤ l o g 2 n f(n) \leq log_2n f(n)≤log2n
算法的空间复杂度
空间复杂度的分析举例
实现:数组逆序,将一维数组a中的n个数逆序存放到原数组中
- 算法1 S(n) = O ( 1 ) (1) (1)
for(i = 1; i < n/2; i++)
{
t = a[i];
a[i] = a[n-i-1];
a[n-i-1] = t;
}
- 算法2 S(n) = O ( n ) (n) (n)
for(i = 1; i < n/2; i++)
b[i] = a[n-i-1];
for(i = 1; i < n/2; i++)
a[i] = b[i];
此算法借助了一个大小为n的辅助数组b
这里是Xavier学习数据结构之路 欢迎各位兄弟批评指正!🙏