【学习重点】
1. 数据结构及相关概念;
2. 数据的逻辑结构和存储结构,二者之间的关系;
3. 算法及特性;
4. 大0记号。
【学习难点】
1. 抽象数据类型的理解和使用;
2. 伪代码的理解和使用;
3. 算法的时间复杂度分析。
1.1 数据结构在程序设计中的作用
1.2 本书讨论的主要内容
本书讨论的非数值问题的数据组织和处理,主要内容有如下4点。
1. 数据的逻辑结构:线性表、树、图等数据结构,其核心是如何组织待处理的数据以及数据之间的关系。
2. 数据的存储结构:如何将线性表、树、图等数据结构存储到计算机的存储器中,其核心是如何有效地存储数据以及数据之间的逻辑关系。
3. 算法:如何基于数据的某种存储结构实现插入、删除、查找等基本操作,其核心是如何有效地处理数据。
4. 常用数据处理技术:包括查找技术、排序技术、索引技术等。
1.3数据结构的基本概念
1.3.1 数据结构
1、数据是信息的载体,在计算机科学中是指所有能输入到计算机中并能被计算机程序识别和处理的符号集合。
数值数据:整数、实数
非数值数据:文字、声音、图形和图像
2、数据元素:一般来说,能独立、完整地描述问题世界的一切实体都是数据元素。在计算机程序中通常作为一个整体进行考虑和处理。
数据项:构成数据元素的不可分割的最小单位。
如图1-5所示。
图1-5 数据元素和数据项
3、数据结构是指相互之间存在一定关系的数据元素的集合。数据元素是讨论数据结构时涉及的最小数据单位。
逻辑结构
顺序存储结构:用一组连续的存储单元依次存储数据元素,据元素之间的逻辑关系由元素的存储位置来表示
链接存储结构:用一组任意的存储单元存储数据元素,数据元素之间的逻辑关系用指针来表示。
逻辑结构:数据元素之间逻辑关系的整体。用户视图,面向问题。
存储结构:数据及其逻辑结构在计算机中的表示。实质上是内存分配,在具体实施时依赖于计算机语言。具体实现的视图。面向计算机。
一般来说,一种数据的逻辑结构可以用多种存储结构来存储,而采用不同的存储结构,其数据处理的效率往往是不同的。
1.3.2 抽象数据类型
数据类型:是一组值的集合以及定义于这个值集上的一组操作的总称。规定了该类型数据的取值范围和对这些数据所能采取的操作。
抽象数据类型(ADT):是一个数据结构以及定义在该结构上的一组操作的总称。
数据类型和ADT的区别:
数据类型指的是高级程序设计语言支持的基本数据类型。由类成员变量来实现。
ADT 指的是自定义的数据类型。ADT的每个操作由类的成员函数来实现。
1.4 算法及算法分析
1.4.1 算法及其描述方法
1、算法:对特定问题求解步骤的一种描述,是指令的有限序列。
算法的5个重要特性:输入、输出、有穷性、确定性、可行性。
算法 程序
一个好的算法还需要满足:正确性、鲁棒性、简单性、抽象分级、高效性。
2、
算法的描述方法
自然语言:优点:容易理解。 缺点:容易出现二义性,并且算法通常都很冗长。
流程图:优点:直观易懂。缺点:严密性不如程序设计语言,灵活性不如自然语言。
程序设计语言
伪代码
伪代码不是一种实际的编程语言,但在表达能力上类似于编程语言,同时极小化了描述算法的不必要的技术性细节。
1.4.2 算法分析
1、
度量算法效率的方法
事后统计:1.实现算法 2.输入适当的数据运行 3.测算其时间和空间开销。
缺点:(1)编写程序实现算法将花费较多的时间和精力;(2)所得实验结果依赖于计算机的软硬件等环境因素,有时容易掩盖算法本身的优劣。
事前分析估算——渐进复杂度:是对算法所消耗资源的一种估算方法。
2.算法的时间复杂度
问题规模:是指输入量的多少,一般可以从问题描述中得到。
运行算法所需要的时间T是问题规模n的函数。记作T(n)。
为了客观地反映一个算法的执行时间,可以用算法中基本语句的执行次数来度量算法的工作量。
基本语句:是执行次数与整个算法的执行次数成正比的语句。
当问题规模充分大时,算法中基本语句执行的次数在渐进意义下的阶,称作算法的渐进时间复杂度,简称时间复杂度。通常用大o(读作“大欧”)记号表示。
定义1-1 若存在两个正的常数c和n0,对于任意n>=n0,都有T(n)<=c*f(n),则称T(n)=O(f(n))(或称算法在O(f(n))中)。
算法的时间复杂度分析实际上是一种估算技术,若两个算法中一个总比另一个“稍快一点”时,它并不能判断那个“稍快一点”的算法的相对优越性。
3.最好、最坏和平均情况:
对于某些算法,即使问题规模相同,如果输入数据不同,其时间开销也不同。
4.算法的空间复杂度:
算法的空间复杂度是指在算法的执行过程中,需要的辅助空间数量。辅助空间是指除算法本身和输入输出数据所占据的空间外,算法临时开辟的存储空间。通常记作:
S(n)=O(f(n))
其中,n为问题规模,分析方法与算法的时间复杂度类似。
5.算法分析举例
分析算法的时间复杂度的基本方法是:找出所有语句中执行次数最大的那条语句作为基本语句,计算基本语句的执行次数,取其数量级放入大O中即可。
定理1-1:若A(n)=amnm+am-1nm-1+…+a1n+a0 是一个m次多项式,则A(m)=O(nm)
定理1-1 说明,在计算任何算法的时间复杂度时,可以忽略所有低次幂和高次幂的系数,这样能够简化算法分析,并且使注意力集中在最重要的一点增长率上。
思想火花——好算法是反复努力和重新修正的结果