目录 公共基础部分(上篇) 第1章数据结构与算法. 。3 11算法 3 12据结构 1.3线性表及顺序存储结构 1.4栈和队列 1.5线性链表 1.6树与二叉树 .15 1.7查找技术」 23 1.8排序技术 1.9本章小结 习题1 ·25 第2章程序设计基础。 .27 2.1程序设计风格与方法 27 2.2结构化程序设计 30 2.3面向对象的程序设计 2.4本章小结 3 习题2 34 第3章软件工程基础 35 3.1软件工程概述 36 32结物化分析方法 30 3.3结构化设计方法 3.4软件的测试 .50 35程序的调试 53 3.6软件工程管理 54 37本音小结 习题3」 第4章 数据库基本原理。 41数据库技术 .58 42数提橙型 64 43关系数据陶 70 45 本章小结 题4 VF程序设计部分(下篇) .82 第5章Visual FoxPro6.0基础. .82 5.1启动和退出Visual FoxPro6.0 82 52设罗工作环培 g 53 Visual FoxPro60的 工作方式 7 5.4 Visual FoxPro6.0的文件类型 5.5项目管理器 .89 5.6本章小结 92
1 目录 公共基础部分(上篇) 第 1 章 数据结构与算法. 3 1.1 算法. 3 1.2 数据结构. 6 1.3 线性表及顺序存储结构. 7 1.4 栈和队列. 9 1.5 线性链表. 12 1.6 树与二叉树. 15 1.7 查找技术. 23 1.8 排序技术. 23 1.9 本章小结. 25 习 题 1. 25 第 2 章 程序设计基础. 27 2.1 程序设计风格与方法. 27 2.2 结构化程序设计. 29 2.3 面向对象的程序设计. 31 2.4 本章小结. 34 习 题 2. 34 第 3 章 软件工程基础 . 35 3.1 软件工程概述. 36 3.2 结构化分析方法. 39 3.3 结构化设计方法. 42 3.4 软件的测试. 50 3.5 程序的调试. 53 3.6 软件工程管理. 54 3.7 本章小结. 55 习 题 3. 57 第 4 章 数据库基本原理. 58 4.1 数据库技术. 58 4.2 数据模型. 64 4.3 关系数据库. 70 4.5 本章小结. 81 习 题 4. 81 VF 程序设计部分(下篇). 82 第 5 章 Visual FoxPro 6.0 基础. 82 5.1 启动和退出 Visual FoxPro 6.0. 82 5.2 设置工作环境. 84 5.3 Visual FoxPro 6.0 的工作方式. 87 5.4 Visual FoxPro 6.0 的文件类型. 88 5.5 项目管理器. 89 5.6 本章小结. 92
习题5. 第6章Visual FoxPro基本数据元素 93 6.1常量 变量和数据类型 6.2 表达式与运算符. .99 6.3常用函数 102 6,4本章小结 112 习题6 112 第7章Visual Foxpro数据库的基本操作 7.1 Visual Foxpro项目 7.2 Visual Foxpro数据库 .116 7.3 Visua1 Foxpr0表 123 7.4数据记录的操作 143 7.5多表的操作 7.6查询与视图 13 77本章小结 184 习题7 184 第8章关系型数据库标准语言SQL 16 Q 1 O概述 1Q6 82SQL的数据定义功能 8.3SQL的数据操纵功能 .19 8.4SQL的数据查询功能 191 8.5视图 197 8.6本煮小结 8 8 第9章 项目管理器、设计器和向导使用 .200 9,1项目管理器的功能及使用 200 9.2设计器的使用. 206 9,3向导的使用 773 9.4本章小结 题9 233 第10章Visual FoxPro程序设计基础 .235 10.1程序文件的建立与运行 235 10.2简单的输入输出命令 237 10.3程序设计的基本结构 10.4模块化程序设 250 10.5本章小结 .255 习题10 .255 附录 258 Visual FoxPro数据库程序设计试卷套题(一) 158 ua】 字设计试卷套趣(二) 63 参考答案 .271 参考文就 .275
2 习 题 5. 92 第6章 Visual FoxPro 基本数据元素 . 93 6.1 常量、变量和数据类型. 93 6.2 表达式与运算符. 99 6.3 常用函数.102 6.4本章小结.112 习 题 6.112 第 7 章 Visual Foxpro 数据库的基本操作 .114 7.1 Visual Foxpro 项目.114 7.2 Visual Foxpro 数据库 .116 7.3 Visual Foxpro 表 .123 7.4 数据记录的操作.143 7.5 多表的操作.169 7.6 查询与视图.173 7.7 本章小结.184 习 题 7 .184 第 8 章 关系型数据库标准语言 SQL.186 8.1 SQL 概述.186 8.2 SQL 的数据定义功能.187 8.3 SQL 的数据操纵功能.190 8.4 SQL 的数据查询功能.191 8.5 视图.197 8.6 本章小结.198 习 题 8.198 第 9 章 项目管理器、设计器和向导使用 .200 9.1 项目管理器的功能及使用 .200 9.2 设计器的使用.206 9.3 向导的使用.223 9.4 本章小结.233 习 题 9.233 第 10 章 Visual FoxPro 程序设计基础 .235 10.1 程序文件的建立与运行.235 10.2 简单的输入输出命令.237 10.3 程序设计的基本结构 .240 10.4 模块化程序设计 .250 10.5 本章小结.255 习 题 10.255 附录.258 Visual FoxPro 数据库程序设计试卷套题(一).258 Visual FoxPro 数据库程序设计试卷套题(二).263 参考答案.271 参考文献.275
第1章数据结构与算法 从事各种工作和活动,都必须事先想好进行的步骤,然后按部就班地进行,才能避免产 生错乱。因此为解决一个问题而采取的方法和步骤,就称为“算法”。 对同一个问趣,可以有不同的解题方法和步骤。方法有优劣之分。有的方法只需进行很 少的步骤,而有些方法则需要较多的步骤。一般说,希望采用简单的和运算步骤少的方法。 因此 ,为了有效地进行解愿,不仅需要保证算法正确,还要考虑算法的质量,选择合适的 算法。 1.1算法 11.1算法的基本概念 计算机解题的过程实际上是在实施某种算法,这种算法称为计算机算法。 算法(algorithm)是一组严谨地定义运算顺序的规则,并且每一个规则都是有效的, 时是明确的:此顺序将在有限的次数后终止。算法是对特定问恩求解步骤的一种描述 它是 指令的有限序列,其中每一条指令表示一个或多个操作。 1、算法的基本特征 (1)可行性(effectiveness):针对实际问题而设计的算法,执行后能够得到满意的结果 (2)确定性(definiteness):算法中的每一个步骤都必须有明确的定义,不允许有模棱 两可的解释和多义性 (3)有穷性(finiteness):算法必需在有限时间内做完,即算法必需能在执行有限个步 骤之后终止。 (4④)拥有足够的情报:要使算法有效必需为算法提供足够的情报当算法拥有足够的情报 时,此算法才最有效的:而当提供的情报不够时,算法可能无效。 2、算法的基本要素 ()算法中对数据的运算和操作:每个算法实际上是按解题要求从环境能进行的所有探 作中选择合适的操作所组成的一组指令序列。 计算机可以执行的基本操作是以指令的形式描述的。一个计算机系统能执行的所有指令 的集合,称为该计算机系统的指令系统。计算机程序就是按解题要求从计算机指令系统中选 择合话的指今所组成的指今序列在 一般的计算机系统中,基本的运算和操作有以下4类: ①算术运算:主要包括加 减、乘、 等运算: ②逻辑运算:主要包括“与”、 “或”、 “非”等运算: ③关系运算:主要包括“大于”、“小于”、“等于”、“不等于”等运算: ④数据传输:主要包括赋值、输入、输出等操作。 (2)算法的控制结构: 一个算法的功能不仅仅取决于所选用的操作,而且还与各操作之 间的执行顺序有关。算法中各操作之间的执行顺序称为算法的控制结构 算法的控制结构给出了算法的基本框架,它不仅决定了算法中各操作的执行顺序,而且 也直接反映了算法的设计是否符合结构化原则。描述算法的工具通常有传统流程图、N-$结 构化流程图、算法描述语言等。一个算法一般都可以用顺序、选择、循环3种基本控制结构 3
3 第 1 章 数据结构与算法 从事各种工作和活动,都必须事先想好进行的步骤,然后按部就班地进行,才能避免产 生错乱。因此为解决一个问题而采取的方法和步骤,就称为“算法”。 对同一个问题,可以有不同的解题方法和步骤。方法有优劣之分。有的方法只需进行很 少的步骤,而有些方法则需要较多的步骤。一般说,希望采用简单的和运算步骤少的方法。 因此 ,为了有效地进行解题,不仅需要保证算法正确,还要考虑算法的质量,选择合适的 算法。 1.1 算法 1.1.1 算法的基本概念 计算机解题的过程实际上是在实施某种算法,这种算法称为计算机算法。 算法(algorithm)是一组严谨地定义运算顺序的规则,并且每一个规则都是有效的,同 时是明确的;此顺序将在有限的次数后终止。算法是对特定问题求解步骤的一种描述,它是 指令的有限序列,其中每一条指令表示一个或多个操作。 1、算法的基本特征 (1)可行性(effectiveness):针对实际问题而设计的算法,执行后能够得到满意的结果。 (2)确定性(definiteness):算法中的每一个步骤都必须有明确的定义,不允许有模棱 两可的解释和多义性。 (3)有穷性(finiteness):算法必需在有限时间内做完,即算法必需能在执行有限个步 骤之后终止。 (4)拥有足够的情报:要使算法有效必需为算法提供足够的情报当算法拥有足够的情报 时,此算法才最有效的;而当提供的情报不够时,算法可能无效。 2、算法的基本要素 (1)算法中对数据的运算和操作:每个算法实际上是按解题要求从环境能进行的所有操 作中选择合适的操作所组成的一组指令序列。 计算机可以执行的基本操作是以指令的形式描述的。一个计算机系统能执行的所有指令 的集合,称为该计算机系统的指令系统。计算机程序就是按解题要求从计算机指令系统中选 择合适的指令所组成的指令序列在一般的计算机系统中,基本的运算和操作有以下 4 类: ①算术运算:主要包括加、减、乘、除等运算; ②逻辑运算:主要包括“与”、“或”、“非”等运算; ③关系运算:主要包括“大于”、“小于”、“等于”、“不等于”等运算; ④数据传输:主要包括赋值、输入、输出等操作。 (2)算法的控制结构:一个算法的功能不仅仅取决于所选用的操作,而且还与各操作之 间的执行顺序有关。算法中各操作之间的执行顺序称为算法的控制结构。 算法的控制结构给出了算法的基本框架,它不仅决定了算法中各操作的执行顺序,而且 也直接反映了算法的设计是否符合结构化原则。描述算法的工具通常有传统流程图、N-S 结 构化流程图、算法描述语言等。一个算法一般都可以用顺序、选择、循环 3 种基本控制结构
组合而成: 3、算法设计的基本方法 计算机算法不同于人工处理的方法,下面是工程上常用的几种算法设计,在实际应用时, 各种方法之间往往存在着一定的联系。 (1)列举法 列举法是计算机算法中的一个基础算法。列举法的基本思想是,根据提出的问题,列举 所有可能的情况,并用问题中给定的条件检验哪些是需要的,哪些是不需要的。 去的特点是算法比较简单 举的可能情况 多时,执行列举算法的工作量将 会很大。因此,在用列举法设计算法时,使方案优化,尽量减少运算工作量,是应该重点注 意的。 (2)归纳法 归纳法的基本思想是,通过列举少量的特殊情况,经过分析,最后找出一般的关系。从 本质上讲,归纳就是通过观察一些荷单而特殊的情况,最后总结出一般性的结论 ③)递推 递推是指从已知的初始条件出发,逐次推出所要求的各中间结果和最后结果。其中初始 条件或是问题本身已经给定,或是通过对问题的分析与化简而确定。递推本质上也属于归钠 法,工程上许多弟推关系式实际上是通过对实际问题的分析与归纳而得到的,因此,递推关 系式往往是归纳的结果。对于数值型的递推算法必须要注意数值计算的稳定性问题。 (递归 人们在解决一些复杂问题时,为了降低问题的复杂程度(如问题的规模等),一般总是将 问题逐层分解,最后归结为一些最简单的问题。这种将问题逐层分解的过程,实际上并没有 对问题进行求解,而只是当解决了最后那些最简单的问题后,再沿着原来分解的逆过程逐步 井行综合,这就是递归的基木思想 递归分为直接递归与间接递归两种 (⑤)减半递推技术 实际问题的复杂程度往往与问题的规模有着密切的联系。因此,利用分治法解决这类实 际问题是有效的。工程上常用的分治法是减半递推技术。 所谓“减半”,是指将问题的规模减半,而问题的性质不变:所谓“递推”,是指重复 “减半”的过程。 (6)回溯法 在工程上,有些实际问题很难归纳出一组简单的递推公式或直观的求解步骤,并且也不 能进行无限的列举。对于这类问题,一种有效的方法是“试”。通过对问题的分析,找出 个解决问题的线索,然后沿着这个线索逐步试探,若试探成功,就得到问题的解,若试探失 败,就逐步回退,换别的路线再逐步试探。 4、算法设计的要求 通常一个好的算法应达到如下目标: (1)正确性(correctness) 正确性大体可以分为以下4个层次: ①程序不含语法错误 ②程序对于几组输入数据能够得出满足规格说明要求的结果 ③程序对于精心选择的典型、苛刻而带有刁难性的几组输入数据能够得出满足规格说明 要求的结果: ④程序对于一切合法的输入数据都能产生满足规格说明要求的结果。 (2)可读性(readability)
4 组合而成。 3、算法设计的基本方法 计算机算法不同于人工处理的方法,下面是工程上常用的几种算法设计,在实际应用时, 各种方法之间往往存在着一定的联系。 (1)列举法 列举法是计算机算法中的一个基础算法。列举法的基本思想是,根据提出的问题,列举 所有可能的情况,并用问题中给定的条件检验哪些是需要的,哪些是不需要的。 列举法的特点是算法比较简单。但当列举的可能情况较多时,执行列举算法的工作量将 会很大。因此,在用列举法设计算法时,使方案优化,尽量减少运算工作量,是应该重点注 意的。 (2)归纳法 归纳法的基本思想是,通过列举少量的特殊情况,经过分析,最后找出一般的关系。从 本质上讲,归纳就是通过观察一些简单而特殊的情况,最后总结出一般性的结论。 (3)递推 递推是指从已知的初始条件出发,逐次推出所要求的各中间结果和最后结果。其中初始 条件或是问题本身已经给定,或是通过对问题的分析与化简而确定。递推本质上也属于归纳 法,工程上许多递推关系式实际上是通过对实际问题的分析与归纳而得到的,因此,递推关 系式往往是归纳的结果。对于数值型的递推算法必须要注意数值计算的稳定性问题。 (4)递归 人们在解决一些复杂问题时,为了降低问题的复杂程度(如问题的规模等),一般总是将 问题逐层分解,最后归结为一些最简单的问题。这种将问题逐层分解的过程,实际上并没有 对问题进行求解,而只是当解决了最后那些最简单的问题后,再沿着原来分解的逆过程逐步 进行综合,这就是递归的基本思想。 递归分为直接递归与间接递归两种。 (5)减半递推技术 实际问题的复杂程度往往与问题的规模有着密切的联系。因此,利用分治法解决这类实 际问题是有效的。工程上常用的分治法是减半递推技术。 所谓“减半”,是指将问题的规模减半,而问题的性质不变;所谓“递推”,是指重复 “减半”的过程。 (6)回溯法 在工程上,有些实际问题很难归纳出一组简单的递推公式或直观的求解步骤,并且也不 能进行无限的列举。对于这类问题,一种有效的方法是“试”。通过对问题的分析,找出一 个解决问题的线索,然后沿着这个线索逐步试探,若试探成功,就得到问题的解,若试探失 败,就逐步回退,换别的路线再逐步试探。 4、算法设计的要求 通常一个好的算法应达到如下目标: (l)正确性(correctness) 正确性大体可以分为以下 4 个层次: ①程序不含语法错误; ②程序对于几组输入数据能够得出满足规格说明要求的结果; ③程序对于精心选择的典型、苛刻而带有刁难性的几组输入数据能够得出满足规格说明 要求的结果; ④程序对于一切合法的输入数据都能产生满足规格说明要求的结果。 (2)可读性(readability)
算法主要是为了方便入的阅读与交流,其次才是其执行。可读性好有助于用户对算法的 理解:晦涩难懂的程序易于隐藏较多错误,难以调试和修改。 (3)健壮性(rot tness 当输入数据非法时,算法也能适当地做出反应或进行处理,而不会产生莫名其妙的输出 结果。 (4)效率与低存储量需求 效率指的是程序执行时,对于同一个问题如果有多个算法可以解决,执行时间短的算法 效率高:存储量需求指算法执行过程中所需要的最大存储空间。 1.1.2算法的复杂度 1、算法的时间复杂度 算法的时间复杂度,是指执行算法所需要的计算工作量。同一个算法用不同的语言实 现,或者用不同的编译程序进行编译,或者在不同的计算机上运行,效*均不同。这表明使 用绝对的时间单位衡量算法的效率是不合适的。撇开这些与计算机硬件、软件有关的因素, 可以认为一个特定算法“运行工作量”的大小,只依赖于问题的规模(通常用整数表示) 它是问的规模函数。即 算法的L作量=f(n) 例如,在N×N矩阵相乘的算法中,整个算法的执行时间与该基本操作(乘法)重复执行 的次数成正比,也就是时间复杂度为3,即 f(n)=0(n3 在有的情况下,算法中的基本操作重复执行的次数还随问题的输入数据集不同而不 例如在起泡排序的算法中,当要排序的数组a初始序列为自小至大有序时,基本操作的执行 次数为n(-1)/2。对这类算法的分析,可以采用以下两种方法来分析。 (1)平均性态(Average behavior) 所谓平均性态是指各种特定输入下的基本运算次数的加权平均值来度量算法的工作量】 A(nF∑p(x)t(x) X&Dn 其中D表示当规模为n时,算法执行的所有可能输入的集合 (②)最坏情况复杂性( 所谓最坏情况分析,是指在规模为时,算法所执行的基本运算的最大次数 2、算法的空间复杂度 算法的空间复杂度是指执行这个算法所需要的内存空间。 一个算法所占用的存储空间包括算法程序所占的空间、输入的初始数据所占的存 储空间以及算法执行中所需要的额外空间。其中额外空间包括算法程序执行过程中的工作单 元以及某种数据结构所需要的附加存储空间。如果额外空间量相对于问题规模来说是常数 则称该算法是原地(in place)工作的。在许多实际问题中,为了减少算法所占的存储空间, 通常采用压缩存储技术,以便尽量减少不必要的额外空间。 5
5 算法主要是为了方便入的阅读与交流,其次才是其执行。可读性好有助于用户对算法的 理解;晦涩难懂的程序易于隐藏较多错误,难以调试和修改。 (3)健壮性(robustness) 当输入数据非法时,算法也能适当地做出反应或进行处理,而不会产生莫名其妙的输出 结果。 (4)效率与低存储量需求 效率指的是程序执行时,对于同一个问题如果有多个算法可以解决,执行时间短的算法 效率高;存储量需求指算法执行过程中所需要的最大存储空间。 1.1.2 算法的复杂度 1、算法的时间复杂度 算法的时间复杂度,是指执行算法所需要的计算工作量。同一个算法用不同的语言实 现,或者用不同的编译程序进行编译,或者在不同的计算机上运行,效率均不同。这表明使 用绝对的时间单位衡量算法的效率是不合适的。撇开这些与计算机硬件、软件有关的因素, 可以认为一个特定算法“运行工作量”的大小,只依赖于问题的规模(通常用整数 n 表示), 它是问题的规模函数。即 算法的工作量=f(n) 例如,在 N×N 矩阵相乘的算法中,整个算法的执行时间与该基本操作(乘法)重复执行 的次数 n 3 成正比,也就是时间复杂度为 n 3,即 f(n)=O(n3 ) 在有的情况下,算法中的基本操作重复执行的次数还随问题的输入数据集不同而不同。 例如在起泡排序的算法中,当要排序的数组 a 初始序列为自小至大有序时,基本操作的执行 次数为 n(n-1)/2。对这类算法的分析,可以采用以下两种方法来分析。 (1)平均性态(Average Behavior) 所谓平均性态是指各种特定输入下的基本运算次数的加权平均值来度量算法的工作量。 设 x 是所有可能输入中的某个特定输入,p(x)是x 出现的概率(即输入为x 的概率),t(x) 是算法在输入为 x 时所执行的基本运算次数,则算法的平均性态定义为 其中 Dn 表示当规模为 n 时,算法执行的所有可能输入的集合。 (2)最坏情况复杂性(Worst-case Complexity) 所谓最坏情况分析,是指在规模为 n 时,算法所执行的基本运算的最大次数。 2、算法的空间复杂度 算法的空间复杂度是指执行这个算法所需要的内存空间。 一个算法所占用的存储空间包括算法程序所占的空间、输入的初始数据所占的存 储空间以及算法执行中所需要的额外空间。其中额外空间包括算法程序执行过程中的工作单 元以及某种数据结构所需要的附加存储空间。如果额外空间量相对于问题规模来说是常数, 则称该算法是原地(in place)工作的。在许多实际问题中,为了减少算法所占的存储空间, 通常采用压缩存储技术,以便尽量减少不必要的额外空间。 A(n)=∑p(x)t(x) X∈Dn
1.2数据结构 1.2.1数据结构的定义 数据结构(data structure))是指相互之间存在一种或多种特定关系的数据元素的集 合,即数据的组织形式。 数据结构作为计算机的一门学科,主要研究和讨论以下三个方面: (1)数据集合中个数据元素之间所固有的逻辑关系,即数据的逻辑结构: (②)在对数据元素进行处理时,各数据元素在计算机中的存储关系,即数据的存储结构: (3)对各种数据结构进行的运算。 讨论以上问题的目的是为了提高数据处理的效率,所谓提高数据处理的效率有两个方 面: (1)提高数据处理的速度: (2)尽量节省在数据处理过程中所占用的计算机存储空间。 数据(d ta/: 是对客观事物的符号表示,在计算机科学中是指所有能输入到计算机中并 被计算机程序处理的符号的总称。 数据元素(data element):是数据的基本单位,在计算机程序中通常作为一个整体进 行考虑和处理。 数据对象(data ob iect):是性质相同的数据元素的集合,是数据的一个子集 在一般情况下,在具有相同特征的数据元素集合中,各个数据元素之间存在有某种关系 (即连续),这种关系反映了该集合中的数据元素所固有的 一种结构。在数据处理领域中,通 常把数据元素之间这种固有的关系简单地用前后件关系(或直接前驱与直接后继关系)来描 述。 前后件关系是数据元素之间的一个基本关系,但前后件关系所表示的实际意义随具体对 象的不同而不同 来说,数据元素之间的任何关系都可以用前后件关系来描述。 数据 逻辑结 数据结构是指反映数据元素之间的关系的数据元素集合的表示。更通俗地说,数据结构 是指带有结构的数据元素的集合。所谓结构实际上就是指数据元素之间的前后件关系。 一个数据结构应包含以下两方面信息: (1)表示数据元素的信息: (②)表示各数据元素之间的前后件关系。 2、数据的存储结构 数据的逻辑结构在计算机存储空间中的存放形式称为数据的存储结构(也称为数据的物 理结构) 1.2.2数据结构的图形表示 数据结构除了用二元关系表示外,还可以直观地用图形表示, 在数据结构的图形表示中,对于数据集合D中的每一个数据元素用中间标有元素值的方 框表示,一般称之为数据结点,并简称为结点:为了进一步表示各数据元素之间的前后件关 系,对于关系R中的每一个二元组,用一条有向线段从前件结点指向后件结点。 在数据结构中,没有前件的结点称为根结点:没有后件的结点称为终端结点(也称为叶子 6
6 1.2 数据结构 1.2.1 数据结构的定义 数据结构(data structure)是指相互之间存在一种或多种特定关系的数据元素的集 合,即数据的组织形式。 数据结构作为计算机的一门学科,主要研究和讨论以下三个方面: (l)数据集合中个数据元素之间所固有的逻辑关系,即数据的逻辑结构; (2)在对数据元素进行处理时,各数据元素在计算机中的存储关系,即数据的存储结构; (3)对各种数据结构进行的运算。 讨论以上问题的目的是为了提高数据处理的效率,所谓提高数据处理的效率有两个方 面: (l)提高数据处理的速度; (2)尽量节省在数据处理过程中所占用的计算机存储空间。 数据(data):是对客观事物的符号表示,在计算机科学中是指所有能输入到计算机中并 被计算机程序处理的符号的总称。 数据元素(data element):是数据的基本单位,在计算机程序中通常作为一个整体进 行考虑和处理。 数据对象(data object):是性质相同的数据元素的集合,是数据的一个子集。 在一般情况下,在具有相同特征的数据元素集合中,各个数据元素之间存在有某种关系 (即连续),这种关系反映了该集合中的数据元素所固有的一种结构。在数据处理领域中,通 常把数据元素之间这种固有的关系简单地用前后件关系(或直接前驱与直接后继关系)来描 述。 前后件关系是数据元素之间的一个基本关系,但前后件关系所表示的实际意义随具体对 象的不同而不同。一般来说,数据元素之间的任何关系都可以用前后件关系来描述。 1、 数据的逻辑结构 数据结构是指反映数据元素之间的关系的数据元素集合的表示。更通俗地说,数据结构 是指带有结构的数据元素的集合。所谓结构实际上就是指数据元素之间的前后件关系。 一个数据结构应包含以下两方面信息: (1) 表示数据元素的信息; (2)表示各数据元素之间的前后件关系。 2、数据的存储结构 数据的逻辑结构在计算机存储空间中的存放形式称为数据的存储结构(也称为数据的物 理结构) 1.2.2 数据结构的图形表示 数据结构除了用二元关系表示外,还可以直观地用图形表示。 在数据结构的图形表示中,对于数据集合 D 中的每一个数据元素用中间标有元素值的方 框表示,一般称之为数据结点,并简称为结点;为了进一步表示各数据元素之间的前后件关 系,对于关系 R 中的每一个二元组,用一条有向线段从前件结点指向后件结点。 在数据结构中,没有前件的结点称为根结点;没有后件的结点称为终端结点(也称为叶子
结点)。 一个数据结构中的结点可能是在动态变化的。根据需要或在处理过程中,可以在一个数 据结构中增加 个新结点(称为插入运算 也可以 据结枸中的某个结点(称为删除 算)。插入与删除是对数据结构的两种基本运算。除此之外,对数据结构的运算还有查找 分类、合并、分解、复制和修改等。 1.2.3线性结构与非线性结构 如果在一个数据结构中一个数据元素都没有,则称该数据结构为空的数据结构。在一个 数据结构中有一个或者多个数据元素,则称该数据结构为非空数据结构。根据数据结构中各 数据元素之间前后件关系的复杂程度, 般将数据结构分为两大类型:线性结构与非线性结 构。 非空数据结构满足: (1)有且只有一个根结点: (2)每一个结点最多有一个前件,也最多有一个后件。 则称该数据结构为线性结构。线性结构又称为线性表 。一个线性表是个数据元素的有 限序列。至于 个元素的 具体 在不同的情况下各不相同 也可以是一页书,甚至其他更复杂的信息。如果一个数据结构不是线性结构,称之为非线 结构。线性结构与非线性结构都可以是空的数据结构。对于空的数据结构,如果对该数据结 构的运算是按线性结构的规则来处理的,则属于线性结构:否则属于非线性结构。 1.3线性表及顺序存储结构 13.1线性表的定义 线性表是n(n≥0)个元素构成的有限序列(a, da, .,a)。表中的每一个数据元素,除 了第一个外,有且只有一个前件,除了最后一个外,有且只有一个后件。即线性表是一个空 表,或可以表示为 其中a:(i=1,2,.,n)是属于数据对象的元素,通常也称其为线性表中的一个结点 其由 ,每个元素可以简单到是一个字母或是 一个数据 ,也可能是比较复杂的由多个数振 项组成的。在复杂的线性表中,由若干数据项组成的数据元素称为记录(r©cord),而由多 记录构成的线性表又称为文件(fil)。在非空表中的每个数据元素都有一个确定的位置,如 a是第一个元素,a,是最后一个数据元素,a是第i个数据元素,称i为数据元素在线性 表中的位序。 非空线性表有如下一些结构特征: ()有且只有一个根结点,它无前件: (2)有且只有一个终端结点a,它无后件: (3)除根结点与终端结点外,其他所有结点有且只有一个前件,也有且只有一个后件。 线性表中结点的个数n称为线性表的长度。当n=0时称为空表
7 结点)。 一个数据结构中的结点可能是在动态变化的。根据需要或在处理过程中,可以在一个数 据结构中增加一个新结点(称为插入运算),也可以删除数据结构中的某个结点(称为删除运 算)。插入与删除是对数据结构的两种基本运算。除此之外,对数据结构的运算还有查找、 分类、合并、分解、复制和修改等。 1.2.3 线性结构与非线性结构 如果在一个数据结构中一个数据元素都没有,则称该数据结构为空的数据结构。在一个 数据结构中有一个或者多个数据元素,则称该数据结构为非空数据结构。根据数据结构中各 数据元素之间前后件关系的复杂程度,一般将数据结构分为两大类型:线性结构与非线性结 构。 非空数据结构满足: (l)有且只有一个根结点; (2)每一个结点最多有一个前件,也最多有一个后件。 则称该数据结构为线性结构。线性结构又称为线性表。一个线性表是 n 个数据元素的有 限序列。至于每个元素的具体含义,在不同的情况下各不相同,它可以是一个数或一个符号, 也可以是一页书,甚至其他更复杂的信息。如果一个数据结构不是线性结构,称之为非线性 结构。线性结构与非线性结构都可以是空的数据结构。对于空的数据结构,如果对该数据结 构的运算是按线性结构的规则来处理的,则属于线性结构;否则属于非线性结构。 1.3 线性表及顺序存储结构 1.3.1 线性表的定义 线性表是 n(n≥0)个元素构成的有限序列(a1,a2,.,an)。表中的每一个数据元素,除 了第一个外,有且只有一个前件,除了最后一个外,有且只有一个后件。即线性表是一个空 表,或可以表示为 (a1,a2,.,an) 其中 ai(i=1,2,.,n)是属于数据对象的元素,通常也称其为线性表中的一个结点。 其中,每个元素可以简单到是一个字母或是一个数据,也可能是比较复杂的由多个数据 项组成的。在复杂的线性表中,由若干数据项组成的数据元素称为记录(record),而由多个 记录构成的线性表又称为文件(file)。在非空表中的每个数据元素都有一个确定的位置,如 a1 是第一个元素,an 是最后一个数据元素,ai 是第 i 个数据元素,称 i 为数据元素 ai 在线性 表中的位序。 非空线性表有如下一些结构特征: (1) 有且只有一个根结点 a1,它无前件; (2) 有且只有一个终端结点 an,它无后件; (3) 除根结点与终端结点外,其他所有结点有且只有一个前件,也有且只有一个后件。 线性表中结点的个数 n 称为线性表的长度。当 n=0 时称为空表
1.3.2线性表的顺序存储结构 线性表的顺序表指的是用一组地址连续的存储单元依次存储线性表的数据元素 线性表的顺序存储结构具备如下两个基本特征: (1)线性表中的所有元素所古的存储空间是连续的: (2)线性表中各数据元素在存储空间中是按逻辑顺序依次存放的。 假设线性表的每个元素需要占用k个存储单元,并以所占的存储位置ADR(a)和第 i个数据元素的存储位置ADR(a:)之间满足下列关系: ADR(a:.)=ADR(a.)+k 线性表第i个元素ai的存储位置为 ADR(a)=ADR(a)+(i-1)xk 式中ADR(a:)是线性表的第一个数据元素a的存储位置,通常称做线性表的起始位 置或基址」 线性表的这种表示称做线性表的顺序存储结构或顺序映像,这种存储结构的线性表 为顺序表。表中有 元素的存储位置都和线性表的起始位置相差一个和数据元素在线 性表中的位序成正比例的常数。知图1-1所示。 占K个字节 存储地址 a l 占K个字节 ADR (al) ADR (al)+k 占K个字节 ADR (al)+(i-1) an 占K个字节 ADR(a1)+(n-1) 图1-1顺序表 由此只要确定了存储线性表的起始位置,线性表中任一数据元素都可以随机存取,所以 线性表的顺序存储结构是一种随机存取的存储结构。 在程序设计语言中,通常定义一个一维数组来表示线性表的顺序存储空间。在用一维数 组存放线性表时,该一维数组的长度通常要定义得比线性表的实际长度大一些,以便对线性 表进行各种运算,特别是插入运算 1.3.3顺序表的插入运算 线性表的插入运算是指在表的第1(1≤i≤+1)个位置上,插入一个新结点x,使长度为 n的线性表 (a,a-a,.ya 变成长度为n+1的线性表
8 1.3.2 线性表的顺序存储结构 线性表的顺序表指的是用一组地址连续的存储单元依次存储线性表的数据元素。 线性表的顺序存储结构具备如下两个基本特征: (l)线性表中的所有元素所占的存储空间是连续的; (2)线性表中各数据元素在存储空间中是按逻辑顺序依次存放的。 假设线性表的每个元素需要占用 k 个存储单元,并以所占的存储位置 ADR(ai+1)和第 i 个数据元素的存储位置 ADR(ai)之间满足下列关系: ADR(ai+1)=ADR(ai)+k 线性表第 i 个元素 ai 的存储位置为 ADR(ai)=ADR(a1)+(i-1)×k 式中 ADR(ai)是线性表的第一个数据元素 a1 的存储位置,通常称做线性表的起始位 置或基址。 线性表的这种表示称做线性表的顺序存储结构或顺序映像,这种存储结构的线性表 为顺序表。表中每一个元素的存储位置都和线性表的起始位置相差一个和数据元素在线 性表中的位序成正比例的常数。如图 1-1 所示。 图 1-1 顺序表 由此只要确定了存储线性表的起始位置,线性表中任一数据元素都可以随机存取,所以 线性表的顺序存储结构是一种随机存取的存储结构。 在程序设计语言中,通常定义一个一维数组来表示线性表的顺序存储空间。在用一维数 组存放线性表时,该一维数组的长度通常要定义得比线性表的实际长度大一些,以便对线性 表进行各种运算,特别是插入运算。 1.3.3 顺序表的插入运算 线性表的插入运算是指在表的第 i(1≤i≤n+l)个位置上,插入一个新结点 x,使长度为 n 的线性表 (a1,.,ai-1,ai,.,an) 变成长度为 n+1 的线性表 存储地址 ADR(a1) ADR(a1)+k ADR(a1)+(i-1) k ADR(a1)+(n-1) k a 1 a 2 a i a n . . . . 占 K 个字节 占 K 个字节 占 K 个字节 占 K 个字节 .
a,a,。a,++,a) 现在分析算法的复杂度。这里的问题规模是表的长度,设它的值为。该算法的时间主 要花费在循环纠 点后移 句上 该语句的执行次数(即移动结点的次数)是一i+1。由此可 出,所需移动结点的次数不仅依赖于表的长度,而且还与插入位置有关 当=+1时,由于循环变量的终值大于初值,结点后移语句将不进行:这是最好情况, 其时间复杂度0(1): 当=1时,结点后移语句,将循环执行n次,需移动表中所有结点,这是最坏情况,其 时间复杂度为00 由于插入可能在表中任何位置上进行,因此需分析算法的平均复杂度 在长度为n的线性表中第i个位置上插入一个结点,令Eis(n)表示移动结点的 期望值(即移动的平均次数),则在第个位置上插入一个结点的移动次数为-i+l。故不失 般性,假设在表中任何位置(1≤i≤+1)上插入结点的机会是均等的,则 因此,在等插 pn+1=l/(a+) 的情况 就是说,在顺序表上做插入运算,平均要移动表 一半的结点。当表长n较大时,算法的效率相当低。虽然Eis(n)中n的的系数较小 但就数量级而言,它仍然是线性级的。因此算法的平均时间复杂度为O()。 1.3.4顺序表的删除运算 线性表的删除运算是指将表的第i(1≤i≤)个结点删除,使长度为n的线性表: .,a) 变成长度为n1的线性表 (ai 该算法的时间分析与插入算法相似,结点的移动次数也是由表长和位置i决定。若 =m,则由于循环变量的初值大于终值,前移语句将不执行,无需移动结点:若=1,则前 移语句将循环执行一1次,需移动表中除开始结点外的所有结点。这两种情况下算法的时 与插入算法相似。在长度为的线性表中删除一个结点,令 Ede()表示所需移动结点的平均次数,别除表中第i个结点的移动次数为m-i,故式子中, pi表示删除表中第ⅰ个结点的概率。在等概率的假设下, p1=p2=p3=+=pn=1/n 由此可得:即在顺序表上做删除运算,平均要移动表中约一半的结点,平均时间复杂度 也是0() 1.4栈和队列 1.4.1栈及其基本运算 1、什么是栈 栈实际也是线性表,只不过是一种特殊的线性表。栈(Sta©k)是只能在表的一端进行插 入和删除运算配线性表,通常称插入、删除的这一端为栈顶(TOp),另一端为栈底(Bot tom)。 当表中没有元素时称为空栈(栈顶元素总是后被插入的元素,从而也是最先被除的元素 9
9 (a1,.,ai-1,x,ai,.,an) 现在分析算法的复杂度。这里的问题规模是表的长度,设它的值为 n。该算法的时间主 要花费在循环结点后移语句上,该语句的执行次数(即移动结点的次数)是 n-i+1。由此可看 出,所需移动结点的次数不仅依赖于表的长度,而且还与插入位置有关。 当 i=n+1 时,由于循环变量的终值大于初值,结点后移语句将不进行;这是最好情况, 其时间复杂度 O(1); 当 i=1 时,结点后移语句,将循环执行 n 次,需移动表中所有结点,这是最坏情况,其 时间复杂度为 O(n)。 由于插入可能在表中任何位置上进行,因此需分析算法的平均复杂度。 在长度为 n 的线性表中第 i 个位置上插入一个结点,令 Eis ( n )表示移动结点的 期望值(即移动的平均次数),则在第 i 个位置上插入一个结点的移动次数为 n-i+1。故不失 一般性,假设在表中任何位置(1≤i≤n+1)上插入结点的机会是均等的,则 p1=p2=p3=.=pn+1=1/(n+1) 因此,在等概率插入的情况下, 也就是说,在顺序表上做插入运算,平均要移动表上 一半的结点。当表长 n 较大时,算法的效率相当低。虽然 Eis ( n )中 n 的的系数较小, 但就数量级而言,它仍然是线性级的。因此算法的平均时间复杂度为 O(n)。 1.3.4 顺序表的删除运算 线性表的删除运算是指将表的第 i(1≤i≤n)个结点删除,使长度为 n 的线性表: (a1,.,ai-1,ai,ai+1,.,an) 变成长度为 n-l 的线性表 (a1,.,ai-1,ai+1,.,an) 该算法的时间分析与插入算法相似,结点的移动次数也是由表长 n 和位置 i 决定。若 i=n,则由于循环变量的初值大于终值,前移语句将不执行,无需移动结点;若 i=1,则前 移语句将循环执行 n 一 1 次,需移动表中除开始结点外的所有结点。这两种情况下算法的时 间复杂度分别为 O(1)和 O(n)。 删除算法的平均性能分析与插入算法相似。在长度为 n 的线性表中删除一个结点,令 Ede(n)表示所需移动结点的平均次数,删除表中第 i 个结点的移动次数为 n-i,故式子中, pi 表示删除表中第 i 个结点的概率。在等概率的假设下, p1=p2=p3=.=pn=1/n 由此可得:即在顺序表上做删除运算,平均要移动表中约一半的结点,平均时间复杂度 也是 O(n)。 1.4 栈和队列 1.4.1 栈及其基本运算 1、 什么是栈 栈实际也是线性表,只不过是一种特殊的线性表。栈(Stack)是只能在表的一端进行插 入和删除运算配线性表,通常称插入、删除的这一端为栈顶(Top),另一端为栈底(Bottom)。 当表中没有元素时称为空栈(栈顶元素总是后被插入的元素,从而也是最先被删除的元素;
找底元素总是最先被插入的元素,从而也是最后才能被侧除的元素」 假设栈S=(a,a 小,则a称为栈底元素为栈顶元素。栈中元素按a a,a的次序进栈,退栈的第 一个元素应为栈顶元素。换句话说,栈的修政是按后进先 出的原则进行的。因此,栈称为先进后出表(FILO,First In Last Out),或“后进先出 表LIfO,Last In First0ut),如图1-2所示。 栈顶 top an a2 栈底bottom一 ai 图1-2先进后出表 2、栈的顺序存储及其运算 (1)入栈运算: 入栈运算是指在栈顶位置插入一个新元素。首先将栈顶指针加一(即t0 加1),然后将元素插入到栈顶指针指向的位置。当栈顶指针已经指向存储空间的最后一个 位置时,说明栈空间己满,不可能再进行入栈操作。这种情况称为栈“上溢”错误。 (2)退栈运算:退栈是指取出栈顶元素并赋给一个指定的变量。首先将栈顶元素(栈顶指 针指向的元素)赋给一个指定的变量,然后将栈顶指针减一(即to印减1)。当栈顶指针为。 时,说明栈空 ,不可进行退栈操作。这种情况称为栈的“下溢”错误 (④读栈顶元素:读栈项元素是指将栈项元素赋给一个指定的变量。这个运算不剧除栈 顶元素,只是将它赋给一个变量,因此栈顶指针不会改变。当栈顶指针为0时,说 明栈空,读不到栈顶元素。 1.4.2队列及其基本运算 1、什么是队列 队列(uu©)是只允许在一端刑除,在另一端插入的顺序表,允许除的一端叫做队头 (front),允许插入的一端叫微队尾(rear),当队列中没有元素时称为空队列。在空队列中 依次加入元素a,a2,a之后,a是队头元素,a是队尾元素。显然退出队列的次序也 只能是,a,.,a也就是说队列的修政是依先进先出的原则进行的。因此队列亦称作先 进先出(FIFO,First In First Out)的线性表,或后进后出LILO,Last In Last Out) 的线性表。往队列队尾插入一个元素称为入队运算,从队列的排头删除一个元素称为退队运 算,如图1-3所示
10 栈底元素总是最先被插入的元素,从而也是最后才能被删除的元素。 假设栈 S=(al,a2,a3,.,an),则 a1 称为栈底元素 an 为栈顶元素。栈中元素按 a1,a2, a3,.,an 的次序进栈,退栈的第一个元素应为栈顶元素。换句话说,栈的修改是按后进先 出的原则进行的。因此,栈称为先进后出表(FILO,First In Last Out),或“后进先出” 表(LIFO,Last In First Out),如图 1-2 所示。 图 1-2 先进后出表 2、 栈的顺序存储及其运算 (l)入栈运算:入栈运算是指在栈顶位置插入一个新元素。首先将栈顶指针加一(即 top 加 1),然后将元素插入到栈顶指针指向的位置。当栈顶指针已经指向存储空间的最后一个 位置时,说明栈空间已满,不可能再进行入栈操作。这种情况称为栈“上溢”错误。 (2)退栈运算:退栈是指取出栈顶元素并赋给一个指定的变量。首先将栈顶元素(栈顶指 针指向的元素)赋给一个指定的变量,然后将栈顶指针减一(即 top 减 1)。当栈顶指针为。 时,说明栈空,不可进行退栈操作。这种情况称为栈的“下溢”错误。 (4) 读栈顶元素:读栈顶元素是指将栈顶元素赋给一个指定的变量。这个运算不删除栈 顶元素,只是将它赋给一个变量,因此栈顶指针不会改变。当栈顶指针为 0 时,说 明栈空,读不到栈顶元素。 1.4.2 队列及其基本运算 1、 什么是队列 队列(queue)是只允许在一端删除,在另一端插入的顺序表,允许删除的一端叫做队头 (front),允许插入的一端叫做队尾(rear),当队列中没有元素时称为空队列。在空队列中 依次加入元素 a1,a2,.,an 之后,a1 是队头元素,an 是队尾元素。显然退出队列的次序也 只能是 a1,a2,.,an 也就是说队列的修改是依先进先出的原则进行的。因此队列亦称作先 进先出(FIFO,First In First Out)的线性表,或后进后出(LILO,Last In Last Out) 的线性表。往队列队尾插入一个元素称为入队运算,从队列的排头删除一个元素称为退队运 算,如图 1-3 所示。 栈顶 栈底 a n a 2 a i . top bottom