2019-2020-1学期 20192419 《网络空间安全专业导论》第四周学习总结 (读书笔记)

第八章抽象数据类型与子程序

8.1 抽象数据类型

抽象数据类型是属性(数据和操作)明确地与特定实现分离的容器。
应用层是特定问题中的数据的视图。逻辑层是数据值和处理它们的操作的抽象视图。实现层明确表示出了存放数据项的结构,并用程序设计语言对数据的操作进行编码。这一层涉及了数据结构,即一种抽象数据类型中的复合数据域的实现。

  • 容器:存放和操作其他对象的对象。

    8.2 栈

    栈和队列是抽象复合结构。

  • 栈:一种抽象复合结构,只能从一端访问栈中的元素。可以在第一个位置插入元素,也可以删除第一个元素。
    会计师称它为LIFO,即后进先出的缩写。另一种描述栈的访问行为的说法是删除的项总是在栈中时间最短的项目。

    8.3 队列

    队列也是种抽象结构,队列中的项目从一端入,从另一端出。会计师称为
    FIFO,即先进先出的缩写。另一种描述队列的访问行为的说法是删除的总是在队列中时间最长的项目。

    8.4 列表

    列表有三个属性特性:项目是同构的,项目是线性的,列表是变长的。
    线性:每个项目除了第一个都有一个独特的组成部分在它之前,除了最后一个也都有一个独特的组成部分在它之后。
    列表通常提供插入一个项目的操作、删除一个项目的操作、检索一个项目是否存放以及报告列表中项目数量。
    *不要把列表误认为是数组,数组是内嵌结构,列表是抽象结构。然而列表应用于数组中。
    列表也可以被形象化为链式结构,链式结构以节点的概念为基础。一个节点由两部分构成:用户的数据和指向列表的下一个节点的链接或指针。
  • 链式结构:一个将数据项和找到下一项位置的信息保存到同一容器的实现方法。

    8.5 树

    这种分层体系结构叫作数。

    8.5.1 二叉树

    二叉树是一种抽象结构,其他每个节点可以有两个后继节点,叫作子女。树的头部是一个起始节点,叫作根,它不是任何节点的子女。如果一个节点左边的子节点存在,则这个子节点叫作左子女。如果一个节点右边的子节点存在,这个子节点便叫作右子女。如果一个节点没有子女,则这个节点叫作树叶。

  • 叶节点:没有子女的树节点。

除了根节点外,每个节点都只有一个父母节点。树中的每个节点都可以被看作一个子树的根。如果一个节点是另一个节点的父母或者是另一个节点先辈的父母,那么前者是后者的先辈。

8.5.2 二叉检索树

二叉检索树还具有语义属性来刻画树中节点上的值,即任何节点的值都要大于它的左子树中的所有节点的值,并且要小于它的右子树中的所有节点的值。

在二叉检索树中搜索

如果current指向一个节点,那么info(current)指的就是这个节点中的的用户数据,left(current)指向的是current的左子树的根节点,right(current)指向的是current的右子树的根节点。null是一个特殊值,说明指针指向空值。因此,如果一个指针是null,那么这个子树就是空的。

8.6 图

  • 图:由一组节点和一组把节点相互连接起来的边构成的数据结构。
  • 顶点:图中的节点。
  • 边(弧):表示图中两个节点的连接的顶点对。
  • 无向图:其中的边没有方向的图。
  • 有向图:其中的边是从一个顶点指向另一个顶点(或同一个顶点)的图。
  • 邻顶点:通过边连接起来的两个顶点。
  • 路径:连接图中两个顶点的一系列顶点。

    8.6.1 创建图

    列表、栈、队列和树都是可容纳元素的容器。
    创建一个表格需要以上操作:

  • 在表格中添加一个顶点
  • 在表格中添加一条边
  • 在表格中添加一个权值

    8.6.2 图算法

    深度优先搜索

    当我们试图在两个顶点间寻找路径时,用栈来储存访问的顶点。用深度优先搜索来检查第一个与起点相邻的顶点。如果是它是终点,则搜索结束。否则,检查所有与第一个顶点相邻的顶点。
    我们需要存储其他和起点相邻的顶点,随后需要的时候会用到它们。因为我们想要沿着一条路径尽可能深地访问各个节点,如果没有找到终点则回溯,因此栈是一种存储顶点的合适数据结构。
    一旦我们把一个顶点的所有相邻顶点都放到栈内,就标记这个顶点为访问过。如果我们处理了一个已经访问过的顶点,将会把一个同样的顶点一次又一次地放入栈内。那么这个算法根本不能称为算法,因为它可能无法终止。所以我们不能多次处理同一个顶点。
    这种搜索叫作深度优先搜索,因为我们走向最深的分支。

    广度优先搜索

    在深度优先搜索中,当来到一个无法继续走通的位置,我们尽可能少回溯。我们尝试从距此顶点最近的路径开始,也就是那些在栈顶的路径。在广度优先搜索中,我们想要回溯到尽可以远,以找到从最初的顶点出发的路径。因此栈不再是一个适合寻找较早路径的数据结构。

    单源最短路搜索

    “最短路径”指的是将路径上的边的值(权值)加在一起得到的和最小。
    我们想要检索离当前顶点最近的顶点,也就是说,与此顶点相连的边权值最小的顶点。我们称这种抽象容器为优先队列,被检索的元素是在队列中拥有最高优先度的元素。

    8.7 子程序

    这里我们用非递归的上下文来审视它们并且讨论怎样能够来回在算法和子算法之间传递信息。因为在讨论实际的语言构造,因此我们更习惯称这样的结构为子程序而不是子算法。
    许多子程序都是高级语言或语言附带库的一部分。

    8.7.1 参数传递

  • 参数列表:程序中的两部分之间的通信机制。
  • 形参:列在子程序名后的括号中的标识符。
  • 实参:子程序调用中列在括号中的标识符。

可以把形参看作子程序中使用的临时标记符。当子程序被调用时,调用单元会把真正的标识符的名字发送给子程序。子程序的动作则是用形参定义的。当动作执行时,实参将逐个替代形参。执行替代操作的方式有几种,不过最常见的是根据位置进行替代。第一个实参替代第一个形参,第二个实参替代第二个形参。
我们可以利用一个数组和一个长度字段来实现一个列表。当向列表添加一个元素时,元素被存储在数组中的length-1位置,从该位置开始不断增加数组长度。我们将值和长度绑定在一起形成一个记录,称之为列表,并把它传递需要它的子程序。
替代机制的操作有点像使用留言板。当子程序被调用时,它将得到一个实参列表(就像把实参列表写在了子程序的留言板上)。当需要多次调用一个子程序而每次调用的实参又不同时,这一点非常有用。以这种方式传递的形参通常叫作位置形参

8.7.2 值参与引用参数

传递参数的基本方式有两种,即通过值传递和通过引用(或地址)传递。

  • 值参:由调用单元传入实参的副本(写在留言本上)的形参。
  • 引用参数:由调用单元传入实参的地址(写在留言板上)的形参。
    要访问一个引用参数,子程序必须访问留言板上列出的地址中的内容。要访问一个值参,子程序只需要访问留言板自身的内容即可。
    isThere是一个有返回值的子程序,这种类型的子程序被称作有返回值的子程序。相反,Delete和Insert则不返回特定的值。然而,它们确实通过参数返回了改变的列表。

    第九章 面向对象设计与高级程序设计语言

    9.1 面向对象方法

    自顶向下的解决方案对任务进行了分层。每个任务或指定的动作通过其参数列表操作传递给它的数据来生成想要的输出。自顶向下设计的重点就是任务。相反地,面向对象的设计方法是用叫作对象的独立实体生成解决方案的问题求解方法,对象由数据和处理数据的操作构成。

    9.1.1 面向对象

    面向对象设计(OOD)的底层概念是类(class)和对象(object)。
    对象是在问题背景中具有意义的事物或实体.对象类(或简称为类)描述了一组类似的对象。

  • 域:类中的特定项,可以是数据或子程序。
  • 方法:定义了类的一种行为的特定算法。

    9.1.2 设计方法

    分解过程有四个阶段,集体讨论(头脑风暴)是确定问题中的类的第一个阶段。在过滤这个阶段中,将回顾集体讨论阶段确定的类,看哪些类是可以合并的以及还缺少哪些类。场景阶段将确定每个类的行为。由于每个类只对自己的行为负责,所以我们称类的行为为责任。最后是责任算法阶段,这个阶段将为列出的所有类的责任编写算法。CRC卡就是用来记录这一阶段的类信息工具。
    责任的类型有两种,即类自身必须知道什么(知识)和类必须能够做什么(行为)。

  • 封装:把数据和动作集中在一起,使数据和动作的逻辑属性与它们的实现细节分离。

    9.1.3 一个计算机示例

    责任算法

    Person类 有两个责任需要分解,即初始化和输出。由于姓名是一个类,可以让这些类自己进行初始化并输出自身。在面向对象设计中,调用子程序的方法是用对象名加点号再加要调用的方法。
    Name类 这个类有两个责任,即初始化和输出,它们的算法不同。初始化责任必须提示用户输入姓名,并且算法必须读入姓名。输出责任必须输出姓和名,并给出合适的标签。

    9.2 翻译过程

    用汇编语言编写的程序要输入汇编器,由它把汇编语言指令翻译成机器码,最终执行的是汇编器输出的机器码。

    9.2.1 编译器

    翻译用高级程序设计语言编写的程序的程序叫作编译器。注意:编译器是一种程序。

    9.2.2 解释器

    解释器是一种程序,用于翻译和执行语句语句序列。与汇编器和编译器只是输出机器码且机器码再单独执行不同的是,解释器在翻译过语句之后会立即执行这个语句。
    在Java设计中,可移植性是最重要的特性。Java被编译成一种标准机器语言——字节码

    9.3 程序设计语言的范型

    范型:“用作模式或模型的实体”和“一组假设、概念、值和实践,构成了它们的聚合体观察现实的方式,尤其适用于精神学科”。
    有两种主要的范型,分别是命令的和声明的。

    9.3.1 命令式范型

    冯·诺伊曼顺序指令模型在内存中操作数值,这给了编程语言所用的绝大多数常用模型巨大的影响:命令式模型。因此,这些命令式范型具有顺序执行指令的特征,变量的使用代表了内存地址,而使用赋值语句则改变这些变量的值。

    面向过程的范型

    面向过程编程是一种命令式模型,在这里语句被分组为子程序。伪代码示例描述了这种模型。

    面向对象的范型

    面向对象视角是与对象交互的一种方式。在面向过程的范型中,数据被认为是被动并且被程序所操控的。在面向对象的范型中,数据对象是活跃的。对象和操作对象的代码绑定在一起。

    9.3.2 声明式范型

    声明式范型是一个描述结果的模型,但是完成结果的过程则不被描述。在这种范型中有两种基本模型:函数型和逻辑型。

    函数式模型

    函数式模型基于函数的数学概念。

    逻辑编程

    逻辑编程基于象征逻辑的原则。这个模型包括了一系列关于对象的事实和一系列关于对象间关系的规则。一个程序包括了向这些对象和关系询问可以通过事实和规则演变的问题。解决潜在问题的算法用逻辑的规则来推演出事实和规则的答案。

    9.4 高级程序设计语言的功能性

    两种伪代码结构————选择和重复(循环)是命令式语言的标志。
    布尔表达式是一个标识符序列,标识符之间由相容的运算符分隔,求得的值是true或false。一个布尔表达式可以是:

  • 一个布尔变量
  • 一个算术表达式加一个关系运算符,再加一个布尔表达式
  • 一个布尔表达式加一个布尔运算符,再加一个布尔表达式

布尔运算符是特殊的运算符AND、OR和NOT。如果两个表达式都是true,AND运算符就返回true,否则返回false。如果两个表达式都是false,OR运算符就返回false,否则返回true。NOT运算符将改变表达式的值。

9.4.2 数据归类

  • 强类型化:每个变量都有一个类型,只有这种类型的值才能存储到该变量中。
  • 数据类型:一组值以及能够应用于这种类型的值的基本操作集合的说明。

    数据类型

    数据是表示信息的物理符号。
    整数、实数、字符和布尔型称为简单数据类型或原子数据类型,字符串是一种具有复合数据类型的特征的数据类型,但通常被看作简单数据类型。

    整数

    整数数据类型表示的是一个整数值的范围,这个范围由表示整数值的字节数决定。
    加法和减法由标准符号+和-表示。乘法和除法通常表示为*和/。大多数语言还有一个返回整数除法的余数的运算符,称为模运算符。

    实数

    实数数据类型表示的是特定精度的数的范围。

    字符

    表示ASCII字符集中的字符需要一个字节,表示Unicode字符集中的字符则需要两个字节。

    布尔型

    布尔数据类型只有两个值——true和false。

    字符串

    字符串是一个字符序列,在某些语言中这个序列通常被看做一个数据值。

    声明

  • 声明:把变量、动作或语言中的其他实体与标识符关联起来的语句,使程序员可以通过,名字引用这些项目。
  • 保留字:一种语言中具有特殊意义的字,不能用它作为标识符。
  • 区分大小写:大写字母和小写字母被看作是不同的;两个拼写方法相同但大小写形式不同的标识符被看作是两个不同的标识符。

    9.4.3 输入/输出结构

    高级语言把输入的文本数据看做一个分为多行的字符流。字符的含义则由存放值的内存单元的数据类型决定。所有输入语句都由三部分组成,即要存放数据的变量的声明、输入语句和要读入的变量名以及数据流自身。变量出现在输入语句中的顺序必须与值出现在输入流中的顺序一样。输入的变量的类型决定了如何解释输入流中的字符。输出语句创建字符流。输出语句中列出的项目可以是文字值或变量名。文字值是直接在输出语句中写的数字或字符串。类型确定了如何解释位模式。

    9.4.4 控制结构

    伪代码提供了三种方法来改变控制算法的流程:重复、选择和子程序。这些结构叫作控制结构。

    嵌套逻辑

    被跳过或重复的语句可以包含一个控制结构。选择语句可以在循环结构中被嵌套。循环结构可以在选择语句中被嵌套。选择和循环语句可以在子程序中被嵌套,而子程序可以在循环或选择结构中被嵌套。

    异步处理

  • 异步:不与计算机中的其他操作同时发生;换句话说,与计算机的动作不同步。

异步处理也叫作事件驱动处理。

9.5 面向对象语言的功能性

9.5.1 封装

  • 封装:实施信息隐蔽的语言特性。
  • 对象类或类(问题求解阶段):属性和行为相似的一组对象的说明。
  • 对象(问题求解阶段):与问题背景相关的事物或实体。
  • 对象(实现阶段):类的一个实例。
  • 类(实现阶段):对象的模式。

    9.5.2 类

  • 实例化:创建类的对象。

    9.5.3 继承

  • 继承:类获取其他类的属性(数据域和方法)的机制。
  • 超类:被继承的类。
  • 派生类:继承的类。

在这种体系结构中,所处的层次越低,对象越专门化。

9.5.4 多态

  • 多态:一种语言的继承体系结构中具有两个同名方法且能够根据对象应用合适的方法的能力。

猜你喜欢

转载自www.cnblogs.com/wty2419/p/11768188.html