第九章——数据结构与算法

前言:
   计算机第九章节主要知识点。

1 知识点介绍

  • 数据结构与算法概念
  • 线性表
  • 数组与矩阵
  • 树与二叉树
  • 查找

2 数据结构定义

  • 数据结构
    • 数据逻辑结构:指数据元素之间的管理。
      • 线性结构:一对一关系
      • 非线性结构:一对多,多对多关系
    • 数据物理结构:数据在物理设备上具体如何存储。

3 算法概念

  算法的5个重要特征

  • 又穷性:执行有穷步之后结束,且每一步都可在有穷时间内完成。
  • 确定性:算法中每一条指令都必须由确切的含义,不能含糊不清。
  • 输入(>= 0)
  • 输出(>= 1)
  • 有效性(可行性):算法的每个步骤都能有效执行并能在执行有限此后得到确定的结果,例如a = 0,b / a就无效。

4 伪代码

  伪代码是一种算法描述语言,介于自然语言与编程语言之间,不用拘泥于具体的实现。

第九章——数据结构与算法

前言:
   计算机第九章节主要知识点。

1 知识点介绍

  • 数据结构与算法概念
  • 线性表
  • 数组与矩阵
  • 树与二叉树
  • 查找

2 数据结构定义

  • 数据结构
    • 数据逻辑结构:指数据元素之间的管理。
      • 线性结构:一对一关系
      • 非线性结构:一对多,多对多关系
    • 数据物理结构:数据在物理设备上具体如何存储。

3 算法概念

  算法的5个重要特征

  • 又穷性:执行有穷步之后结束,且每一步都可在有穷时间内完成。
  • 确定性:算法中每一条指令都必须由确切的含义,不能含糊不清。
  • 输入(>= 0)
  • 输出(>= 1)
  • 有效性(可行性):算法的每个步骤都能有效执行并能在执行有限此后得到确定的结果,例如a = 0,b / a就无效。

4 伪代码

  伪代码是一种算法描述语言,介于自然语言与编程语言之间,不用拘泥于具体的实现。

Pseudocode.png

5 线性表

5.1 线性表的概念

  常见线性表的两种存储结构。

  • 顺序存储结构(如:顺序表)
  • 链式存储结构(如:链表)

  逻辑上连续,物理上不一定连续。

  • 顺序表:随机存取。查询和修改容易,元素插入和删除麻烦,需要移动元素。
  • 链表
    • 单链表
    • 循环链表
    • 双向链表

LinearList.png

5.2 链表基本操作

  • 单链表删除结点
  • 单链表插入结点
  • 双向链表删除结点
  • 双向链表插入结点

LinkedList.png

5.3 例题

  1. 以下关于单链表存储结构特征的叙述中,不正确的是(D)。

A. 表中结点所占用存储空间的地址不必是连续的
B. 在表中任意位置进行插入和删除操作都不用移动元素
C. 所需空间与结点个数成正比
D. 可随机访问表中的任一结点

5.4 队列和栈

  元素按照a、b、c的次序进入栈,请尝试写出其所有可能的出栈序。

QueueAndStack.png

5.5 例题

  1. 令序列X、Y、Z的每个元素都按顺序进栈,且每个元素进栈和出栈仅一次,则不可能得到的出栈序列是(C)。

A. XYZ
B. XZY
C. ZXY
D. YZX

6 广义表

  广义表示n个表元素组成的有限序列,是线性表的推广,通常用递归的形式进行定义,记作: $LS = (a_0, a_1, …, a_n)$

注:其中LS是表名, $a_i$ 是表元素,它可以是表(称做子表),也可以是数据元素(称为原子)。其中n是广义表的长度(也就是最外层包含的元素个数),n = 0的广义表为空表;而递归定义的重数就是广义表的深度,直观地说,就是定义中所含括号的重数(原子的深度为0,空表的深度为1)。

例,有广义表LS1 = (a, (b, c), (d, e)),其长度为?深度为?
答案:长度为3,深度为2。

7 串

  串是仅由字符构成的有限序列,是取值范围受限的线性表,一般记为 S = ‘a1a2…an’,其中S是串名,单引号括起来的字符序列是串值。

8 数组

  二维数组分按行存储和按列存储。c/c++的多维数组是按行、连续存储逇。FORTRAN语言,Matlab中,数组按列优先顺序存储。

数组类型 存储地址计算
一维数组a[n] a[i]的存储地址为:a + i * len
二维数组a[m][n] a[i][j]的存储地址(按行存储)为:a + (i * n + j) * len
a[i][j]存储地址(按列存储)为:a + (j * m + i) * len

8.1 例题

  1. 数组a[1 … n, 1 … m](n > 1, m > 1)中的元素以行为主序存放,每个元素占用1个存储伟,则数组元素a[i, j] $(1 \leq i \leq n, 1 \leq j \leq m)$ 相对于数组空间首地址的偏移量为(A)

A. (i - 1) * m + j - 1
B. (i - 1) * n + j - 1
C. (j - 1) * m + i - 1
D. (j - 1) * n + i - 1

  1. 若二维数组arr[1 … M, 1 … N]的首地址为base,数组元素按列存储且每个元素占用K个存储单元,则元素arr[i, j]在该数组空间的地址为()。

A. base + ((i - 1) * M + j - 1) * K
B. base + ((i - 1) * N + j - 1) * K
C. base + ((j - 1) * M + i - 1) * K
D. base + ((j - 1) * N + i - 1) * K

9 树与二叉树

  • 结点的度
  • 树的高度
  • 叶子结点
  • 分支结点
  • 内部结点
  • 父结点
  • 子结点
  • 兄弟结点
  • 层次

BinaryTree.png

BinaryTree_1.png

  二叉树的重要特征。

  • 在二叉树的第i层上最多有 $2^{i - 1}$ 个结点 $(i \geq 1)$ ;
  • 深度为k的二叉树最多有 $2^k - 1$ 个结点 $(k \geq 1)$ ;
  • 对任何一颗二叉树,如果其叶子结点数为 $n_0$ ,度为2的结点数为 $n_2$ ,则 $n_0 = n_2 + 1$ 。
  • 如果对一颗有n个结点的完全二叉树的结点按层序编号(从第1层到 $log_2n + 1$ 层,每层从左到右),则对任一结点i $(i \geq i \geq n)$ ,有
    • 如果i = 1,则结点i无父结点,是二叉树的根;如果i > 1,则父结点是i / 2;
    • 如果2i > n,则结点i为叶子结点,无左子结点;否则,其左子结点是结点2i;
    • 如果2i + 1 > n,则结点i无右叶子结点,否则,其右子结点是结点2i + 1;

9.1 二叉树遍历

  • 前序遍历(根左右)
  • 中序遍历(左根右)
  • 后序遍历(左右根)
  • 层序遍历

  前序遍历:12457836,中序遍历:42785136,后序遍历:48752631,层次遍历:12345678。

TraversalOfBinaryTree.png

10 堆

  堆是计算机科学中的一类特殊的数据结构的统称。堆通常是一个可以被看做一颗完全二叉树的数组对象。
  若n个元素的序列 ${a_1, a_2 … a_n}$ 满足

Formula.png

  则分别称该序列 ${a_1, a_2, … a_n}$ 为小根堆和大根堆。
  从堆的定义可以看出,对实质是满足如下性质的完全二叉树:

  • 二叉树中任一非叶子结点均小于(大于)它的孩子结点。
  • 堆总是一颗完全二叉树。

  例如:下面序列为堆,对应的完全二叉树分别为。

1
2
98 77 35 62 55 14 35 48
14 48 35 62 55 98 35 77

Heap.png

10.1 例题

  1. 对于n个元素的关键字序列 ${k_1, k_2, … k_n}$ ,当且仅当满足关系 $k_j \leq k_{2i}$ 且 $k_i \leq k_{2i + 1}$ {i = 1.2…[n/2]}时称其为小根堆(小顶堆)。以下序列中,(D)不是小根堆。

A. 16, 25, 40, 55, 30, 50, 45
B. 16, 40, 25, 50, 45, 30, 55
C. 16, 25, 39, 41, 45, 43, 50
D. 16, 40, 25, 53, 39, 55, 45

11 图

11.1 图的存储

11.1.1 邻接矩阵表示法

  邻接矩阵表示法用一个n阶方阵R来存放图中各结点的关联信息,其矩阵元素 $R_{ij}$ 定义为。
  为无向图。表示稀疏矩阵时空间浪费大。

FigureOfTheStorage.png

11.1.2 邻接链条表示法

  首先把每个顶点的邻接顶点用链表表示出来,然后用一个一维数组来顺序存储上面每个链表的头指针。

ListFigure.png

11.2 例题

  1. 某有向图G的邻接表如下图所示,可看出该图中存在弧 $<v_2, V3>$ 而不存在从顶点 $V_1$ 出发的弧。以下关于图G的叙述中,错误的是()。

A. G中存在回路
B. G中每个顶点的入度为1
C. G的邻接矩阵是对称的
D. 不存在弧 $V_3, V_1>

ex1.png

11.3 图的遍历

GraphTraversal.png

12 查找算法

  • 五大查找
    • 顺序表查找
      • 顺序查找
      • 二分查找
      • 索引顺序查找
    • 树表查找
      • 二叉排序树
    • 散列表查找
      • 哈希查找

12.1 顺序查找

  顺序查找的过程:将待查找的关键字可key的元素从头到尾与表中元素进行比较,如果中间存在关键字为key的元素,则返回成功,否则返回失败。顺序查找主要针对少量的、无规则的数据。

1
4 7 10 18 30 2 46 24 15

12.2 二分查找

  二分法查找的基本过程是:(设R[low, …, high]是当前的查找区)

  • 确定该区间的中间位置:mid = [(low + high) / 2],向下取整。
  • 将待查的k值与R[mid].key比较,若相等,则查找成功并返回此位置,否则需确定新的查找区间,继续二分查找,具体方法如下。
    • 若R[mid].key > k,则由表的有序性可知R[mid, …, n].key均大于k,因此若表中存在关键字等于k的结点,则该结点必定是在位置mid左边的子表R[low, …, mid -1]中。因此,新的查找区间是左子表R[low, …, high],其中high = mid - 1.
    • 若R[mid].key < k,则要查找的k必在mid的右子表R[mid + 1, …, high]中,即新的查找区间是右子表R[low, …, high],其中low = mid + 1。
    • 若R[mid].key = k,则查找成功,算法结束。
  • 下次查找是针对新的查找区间进行,重复步骤(1)和(2)。
  • 在查找过程中,low逐步增加,而high逐步减少。如果high < low,则查找失败,算法结束。

12.3 二叉查找树(排序)

  二叉查找树的定义:二叉排序树或者是一颗空树,或者是具有如下特性的二叉树。

  • 若它的左子树不空,则左子树上所有节点的值均小于根节点的值。
  • 若它的有子树不空,则右子树上所有节点的值均大于根节点的值。
  • 它的左、右子树也都分别是二叉排序树。

  对二叉查找树进行中序遍历,即可得到有序的序列。

BinarySortTree.png

  查找过程:二叉查找(排序)树是先对待查找的数据进行生成树,确保数的左分支值小于右分支的值,然后再去和每个结点的父结点比较大小,查找最合适的范围。这个算法的查找效率很高,但是如果使用这种查找方法要首先创建数。
  具体步骤为。

  • 若查找的关键字等于根节点的关键字,查找成功。
  • 若查找的关键字小于根节点的关键字,递归查找左子树。
  • 若查找的关键字大于根节点的关键字,递归查找右子树。
  • 若子树为空,则查找不成功。

12.4 二叉平衡树

  定义:又称AVL树。它或者是一颗空树,或者是具有下列性质的二叉树:它的左子树或右子树都是平衡二叉树,且左子树和右子树的深度之差的绝对值不超过1。

  平衡因子。
  二叉树上任一结点的左子树深度减去右子树深度的差值,称为此结点的平衡因子。

AVL.png

12.5 例题

  1. 关于二叉排序树的说法,错误的是(C)。

A. 对于二叉排序树进行中序遍历,必定得到结点关键字的有序序列
B. 依据关键字无序的序列建立二叉排序,也可能构造出单支树
C. 若构造二叉排序树时进行平衡化处理,则根节点的左子树结点数与右子树结点数的差值一定不超过1
D. 若构造二叉排序树时进行平衡化处理,则根结点的左子树高度与右子树高度的差值一定不超过1

12.5 哈夫曼树

  定义:给定N个权值作为N个叶子节点,构造一颗二叉树,若该树的带权路径长度达到最小,称这样的二叉树为最优二叉树,也称为哈夫曼树。哈夫曼树是带权路径长度最短的数,权值较大的结点离根较近。
  一般可以按下面步骤构建。

  • 将所有左、右子树都为空的作为根节点。
  • 在森林中选取两棵根节点的权值最小的数作为一棵新树的左、右子树,且置新树的附加根节点的权值为其左、右子树上根结点的权值之和。
  • 从森林中删除这两棵树,同时把新树加入到森林中。
  • 重复2、3步骤,直到森林中只有一棵树为止,此树便是哈夫曼树。

HuffmanTree.png

HuffmanTree_.png

  应用场景:对字符集中的字符进行编码和译码。

12.6 例题

  1. 以下有关哈夫曼树的说法中,错误的是(C)。

A. 哈夫曼树又被称为最优二叉树
B. 哈夫曼树是一种带权路径长度最短的树
C. 具有n个叶子结点的权值为 $W_1, W_2, …, W_n$ 的最优二叉树是唯一的
D. 哈夫曼树可以用来进行通信电文的编码和解码

13 B树

  B树,有时又写为B-树或B_树(其中的“-”或者“_”只是连字符,并不读作“B减树”)。一颗m阶的B树是一颗平衡的多路搜索树,它或者是空树,或者是满足下列性质的树。

  1. 树中每个结点至多有m棵子树。
  2. 若根结点不是叶子结点,则至少有两棵子树。
  3. 除根之外的所有非终端结点至少有[m/2](向上取整)棵子树。
  4. 所有的非终端结点中包含下列信息数据:

   $(n, A_0, K_1, A_1, K_2, A_2, …, K_n, A_n)$ ,其中: $K_i (i = 1, 2, …, n)$ 为关键字,且 $K_i < K_{i + 1}$ (i = 1, …, n - 1)。
   $A_i (i = 0, …, n)$ 为指向子树根结点的指针,且指针 $A_{i -1}$ 所指子树中所有结点的关键字均小于 $K_i(i = 1, …, n)$ , $A_n$ 所指子树中所有结点的关键字均大于 $K_n$ , $n ([m / 2] - 1 \leq n \leq m - 1)$ 为关键字的个数(或n + 1为子树个数)。其中[m / 2]表示向上取整。

  1. 所有的叶子结点都出现在同一层次上,并且不带信息(可以看作是外部结点或查找失败的结点,实际上这些结点不存在,指向这些结点的指针为空)。

BTree.png

14 B+树

  是B-树的一种变型,一个m阶的B+树具有如下几个特征。

  • 每个叶子结点中含有n个关键字和n个指向记录的指针,并且所有叶子节点彼此相链接构成一个有序链表,其头指针指向含最小关键字的节点。
  • 每个非叶子节点中的关键字 $K_i$ 即为其相应指针 $A_i$ 所指子树中关键字的最大值。
  • 所有叶子节点都处在统一层次上,每个叶子节点中关键字的个数均介于[m / 2](向上取整)和m之间。

B+Tree.png

15 散列表

  散列表构造的基本思想是:已知关键字集合U,最大关键字为m,设计一个函数Hash,它以关键字为自变量,关键字的存储地址为因变量,将关键字映射到一个有限的、地址连续的区间T[0 .. n - 1](n << m)中,这个区间就称为散列表,散列查找中使用的转换函数称为散列函数。

  例:假设有一个大小为7的表,现在要将(13, 18, 19s, 50, 20, 27)散列到表中。

  • 选择散列函数,例如使用hash(x) = x % 7作为散列函数。
  • 计算数据散列值,并放到合适的位置。
哈希地址 0 1 2 3 4 5 6
关键码 50 18 19 13

  地址重复时出现冲突,即散列冲突。

15.1 解决散列冲突

  • 链地址法(拉链法)
  • 开放地址法

   $H_i = (Hash(key) + d_i) % m$ i = 1, 2, …, k $(k \leq m - 1)$
  其中Hash(key)为哈希函数,m为哈希表的表长,di为增量序列。常见的增量序列有三种。

  • di = 1, 2, 3, …, m - 1,称为线性他侧再散列。
  • di = $1^2, {-1}^2, 2^2, {-2}^2, 3^3, …, ±k^2$ ,称为二次探测再散列。
  • di = 伪随机数列,称为随机探测再散列,如:di = Random(key)。

15.2 例题

  1. 用哈希表存储元素时,需要进行冲突(碰撞)处理,冲突是指(B)。

A. 关键字被依次映射到地址编号连续的存储位置
B. 关键字不同的元素被映射到相同的存储位置
C. 关键字相同的元素被映射到不同的存储位置
D. 关键字被映射到哈希表之外的位置

16 总结

  考查形式主要是概念区分以及部分计算题型,主要出现在上午的选择题当中。

  • 树的遍历
  • 图的遍历
  • 典型的时间复杂度

  需要记忆。

  • 数据结构与算法的概念
  • 线性表(顺序表、链表、栈、队列)
  • 数组与矩阵
  • 树与二叉树
  • 查找(二分查找、哈希)

5 线性表

5.1 线性表的概念

  常见线性表的两种存储结构。

  • 顺序存储结构(如:顺序表)
  • 链式存储结构(如:链表)

  逻辑上连续,物理上不一定连续。

  • 顺序表:随机存取。查询和修改容易,元素插入和删除麻烦,需要移动元素。
  • 链表
    • 单链表
    • 循环链表
    • 双向链表

第九章——数据结构与算法

前言:
   计算机第九章节主要知识点。

1 知识点介绍

  • 数据结构与算法概念
  • 线性表
  • 数组与矩阵
  • 树与二叉树
  • 查找

2 数据结构定义

  • 数据结构
    • 数据逻辑结构:指数据元素之间的管理。
      • 线性结构:一对一关系
      • 非线性结构:一对多,多对多关系
    • 数据物理结构:数据在物理设备上具体如何存储。

3 算法概念

  算法的5个重要特征

  • 又穷性:执行有穷步之后结束,且每一步都可在有穷时间内完成。
  • 确定性:算法中每一条指令都必须由确切的含义,不能含糊不清。
  • 输入(>= 0)
  • 输出(>= 1)
  • 有效性(可行性):算法的每个步骤都能有效执行并能在执行有限此后得到确定的结果,例如a = 0,b / a就无效。

4 伪代码

  伪代码是一种算法描述语言,介于自然语言与编程语言之间,不用拘泥于具体的实现。

Pseudocode.png

5 线性表

5.1 线性表的概念

  常见线性表的两种存储结构。

  • 顺序存储结构(如:顺序表)
  • 链式存储结构(如:链表)

  逻辑上连续,物理上不一定连续。

  • 顺序表:随机存取。查询和修改容易,元素插入和删除麻烦,需要移动元素。
  • 链表
    • 单链表
    • 循环链表
    • 双向链表

LinearList.png

5.2 链表基本操作

  • 单链表删除结点
  • 单链表插入结点
  • 双向链表删除结点
  • 双向链表插入结点

LinkedList.png

5.3 例题

  1. 以下关于单链表存储结构特征的叙述中,不正确的是(D)。

A. 表中结点所占用存储空间的地址不必是连续的
B. 在表中任意位置进行插入和删除操作都不用移动元素
C. 所需空间与结点个数成正比
D. 可随机访问表中的任一结点

5.4 队列和栈

  元素按照a、b、c的次序进入栈,请尝试写出其所有可能的出栈序。

QueueAndStack.png

5.5 例题

  1. 令序列X、Y、Z的每个元素都按顺序进栈,且每个元素进栈和出栈仅一次,则不可能得到的出栈序列是(C)。

A. XYZ
B. XZY
C. ZXY
D. YZX

6 广义表

  广义表示n个表元素组成的有限序列,是线性表的推广,通常用递归的形式进行定义,记作: $LS = (a_0, a_1, …, a_n)$

注:其中LS是表名, $a_i$ 是表元素,它可以是表(称做子表),也可以是数据元素(称为原子)。其中n是广义表的长度(也就是最外层包含的元素个数),n = 0的广义表为空表;而递归定义的重数就是广义表的深度,直观地说,就是定义中所含括号的重数(原子的深度为0,空表的深度为1)。

例,有广义表LS1 = (a, (b, c), (d, e)),其长度为?深度为?
答案:长度为3,深度为2。

7 串

  串是仅由字符构成的有限序列,是取值范围受限的线性表,一般记为 S = ‘a1a2…an’,其中S是串名,单引号括起来的字符序列是串值。

8 数组

  二维数组分按行存储和按列存储。c/c++的多维数组是按行、连续存储逇。FORTRAN语言,Matlab中,数组按列优先顺序存储。

数组类型 存储地址计算
一维数组a[n] a[i]的存储地址为:a + i * len
二维数组a[m][n] a[i][j]的存储地址(按行存储)为:a + (i * n + j) * len
a[i][j]存储地址(按列存储)为:a + (j * m + i) * len

8.1 例题

  1. 数组a[1 … n, 1 … m](n > 1, m > 1)中的元素以行为主序存放,每个元素占用1个存储伟,则数组元素a[i, j] $(1 \leq i \leq n, 1 \leq j \leq m)$ 相对于数组空间首地址的偏移量为(A)

A. (i - 1) * m + j - 1
B. (i - 1) * n + j - 1
C. (j - 1) * m + i - 1
D. (j - 1) * n + i - 1

  1. 若二维数组arr[1 … M, 1 … N]的首地址为base,数组元素按列存储且每个元素占用K个存储单元,则元素arr[i, j]在该数组空间的地址为()。

A. base + ((i - 1) * M + j - 1) * K
B. base + ((i - 1) * N + j - 1) * K
C. base + ((j - 1) * M + i - 1) * K
D. base + ((j - 1) * N + i - 1) * K

9 树与二叉树

  • 结点的度
  • 树的高度
  • 叶子结点
  • 分支结点
  • 内部结点
  • 父结点
  • 子结点
  • 兄弟结点
  • 层次

BinaryTree.png

BinaryTree_1.png

  二叉树的重要特征。

  • 在二叉树的第i层上最多有 $2^{i - 1}$ 个结点 $(i \geq 1)$ ;
  • 深度为k的二叉树最多有 $2^k - 1$ 个结点 $(k \geq 1)$ ;
  • 对任何一颗二叉树,如果其叶子结点数为 $n_0$ ,度为2的结点数为 $n_2$ ,则 $n_0 = n_2 + 1$ 。
  • 如果对一颗有n个结点的完全二叉树的结点按层序编号(从第1层到 $log_2n + 1$ 层,每层从左到右),则对任一结点i $(i \geq i \geq n)$ ,有
    • 如果i = 1,则结点i无父结点,是二叉树的根;如果i > 1,则父结点是i / 2;
    • 如果2i > n,则结点i为叶子结点,无左子结点;否则,其左子结点是结点2i;
    • 如果2i + 1 > n,则结点i无右叶子结点,否则,其右子结点是结点2i + 1;

9.1 二叉树遍历

  • 前序遍历(根左右)
  • 中序遍历(左根右)
  • 后序遍历(左右根)
  • 层序遍历

  前序遍历:12457836,中序遍历:42785136,后序遍历:48752631,层次遍历:12345678。

TraversalOfBinaryTree.png

10 堆

  堆是计算机科学中的一类特殊的数据结构的统称。堆通常是一个可以被看做一颗完全二叉树的数组对象。
  若n个元素的序列 ${a_1, a_2 … a_n}$ 满足

Formula.png

  则分别称该序列 ${a_1, a_2, … a_n}$ 为小根堆和大根堆。
  从堆的定义可以看出,对实质是满足如下性质的完全二叉树:

  • 二叉树中任一非叶子结点均小于(大于)它的孩子结点。
  • 堆总是一颗完全二叉树。

  例如:下面序列为堆,对应的完全二叉树分别为。

1
2
98 77 35 62 55 14 35 48
14 48 35 62 55 98 35 77

Heap.png

10.1 例题

  1. 对于n个元素的关键字序列 ${k_1, k_2, … k_n}$ ,当且仅当满足关系 $k_j \leq k_{2i}$ 且 $k_i \leq k_{2i + 1}$ {i = 1.2…[n/2]}时称其为小根堆(小顶堆)。以下序列中,(D)不是小根堆。

A. 16, 25, 40, 55, 30, 50, 45
B. 16, 40, 25, 50, 45, 30, 55
C. 16, 25, 39, 41, 45, 43, 50
D. 16, 40, 25, 53, 39, 55, 45

11 图

11.1 图的存储

11.1.1 邻接矩阵表示法

  邻接矩阵表示法用一个n阶方阵R来存放图中各结点的关联信息,其矩阵元素 $R_{ij}$ 定义为。
  为无向图。表示稀疏矩阵时空间浪费大。

FigureOfTheStorage.png

11.1.2 邻接链条表示法

  首先把每个顶点的邻接顶点用链表表示出来,然后用一个一维数组来顺序存储上面每个链表的头指针。

ListFigure.png

11.2 例题

  1. 某有向图G的邻接表如下图所示,可看出该图中存在弧 $<v_2, V3>$ 而不存在从顶点 $V_1$ 出发的弧。以下关于图G的叙述中,错误的是()。

A. G中存在回路
B. G中每个顶点的入度为1
C. G的邻接矩阵是对称的
D. 不存在弧 $V_3, V_1>

ex1.png

11.3 图的遍历

GraphTraversal.png

12 查找算法

  • 五大查找
    • 顺序表查找
      • 顺序查找
      • 二分查找
      • 索引顺序查找
    • 树表查找
      • 二叉排序树
    • 散列表查找
      • 哈希查找

12.1 顺序查找

  顺序查找的过程:将待查找的关键字可key的元素从头到尾与表中元素进行比较,如果中间存在关键字为key的元素,则返回成功,否则返回失败。顺序查找主要针对少量的、无规则的数据。

1
4 7 10 18 30 2 46 24 15

12.2 二分查找

  二分法查找的基本过程是:(设R[low, …, high]是当前的查找区)

  • 确定该区间的中间位置:mid = [(low + high) / 2],向下取整。
  • 将待查的k值与R[mid].key比较,若相等,则查找成功并返回此位置,否则需确定新的查找区间,继续二分查找,具体方法如下。
    • 若R[mid].key > k,则由表的有序性可知R[mid, …, n].key均大于k,因此若表中存在关键字等于k的结点,则该结点必定是在位置mid左边的子表R[low, …, mid -1]中。因此,新的查找区间是左子表R[low, …, high],其中high = mid - 1.
    • 若R[mid].key < k,则要查找的k必在mid的右子表R[mid + 1, …, high]中,即新的查找区间是右子表R[low, …, high],其中low = mid + 1。
    • 若R[mid].key = k,则查找成功,算法结束。
  • 下次查找是针对新的查找区间进行,重复步骤(1)和(2)。
  • 在查找过程中,low逐步增加,而high逐步减少。如果high < low,则查找失败,算法结束。

12.3 二叉查找树(排序)

  二叉查找树的定义:二叉排序树或者是一颗空树,或者是具有如下特性的二叉树。

  • 若它的左子树不空,则左子树上所有节点的值均小于根节点的值。
  • 若它的有子树不空,则右子树上所有节点的值均大于根节点的值。
  • 它的左、右子树也都分别是二叉排序树。

  对二叉查找树进行中序遍历,即可得到有序的序列。

BinarySortTree.png

  查找过程:二叉查找(排序)树是先对待查找的数据进行生成树,确保数的左分支值小于右分支的值,然后再去和每个结点的父结点比较大小,查找最合适的范围。这个算法的查找效率很高,但是如果使用这种查找方法要首先创建数。
  具体步骤为。

  • 若查找的关键字等于根节点的关键字,查找成功。
  • 若查找的关键字小于根节点的关键字,递归查找左子树。
  • 若查找的关键字大于根节点的关键字,递归查找右子树。
  • 若子树为空,则查找不成功。

12.4 二叉平衡树

  定义:又称AVL树。它或者是一颗空树,或者是具有下列性质的二叉树:它的左子树或右子树都是平衡二叉树,且左子树和右子树的深度之差的绝对值不超过1。

  平衡因子。
  二叉树上任一结点的左子树深度减去右子树深度的差值,称为此结点的平衡因子。

AVL.png

12.5 例题

  1. 关于二叉排序树的说法,错误的是(C)。

A. 对于二叉排序树进行中序遍历,必定得到结点关键字的有序序列
B. 依据关键字无序的序列建立二叉排序,也可能构造出单支树
C. 若构造二叉排序树时进行平衡化处理,则根节点的左子树结点数与右子树结点数的差值一定不超过1
D. 若构造二叉排序树时进行平衡化处理,则根结点的左子树高度与右子树高度的差值一定不超过1

12.5 哈夫曼树

  定义:给定N个权值作为N个叶子节点,构造一颗二叉树,若该树的带权路径长度达到最小,称这样的二叉树为最优二叉树,也称为哈夫曼树。哈夫曼树是带权路径长度最短的数,权值较大的结点离根较近。
  一般可以按下面步骤构建。

  • 将所有左、右子树都为空的作为根节点。
  • 在森林中选取两棵根节点的权值最小的数作为一棵新树的左、右子树,且置新树的附加根节点的权值为其左、右子树上根结点的权值之和。
  • 从森林中删除这两棵树,同时把新树加入到森林中。
  • 重复2、3步骤,直到森林中只有一棵树为止,此树便是哈夫曼树。

HuffmanTree.png

HuffmanTree_.png

  应用场景:对字符集中的字符进行编码和译码。

12.6 例题

  1. 以下有关哈夫曼树的说法中,错误的是(C)。

A. 哈夫曼树又被称为最优二叉树
B. 哈夫曼树是一种带权路径长度最短的树
C. 具有n个叶子结点的权值为 $W_1, W_2, …, W_n$ 的最优二叉树是唯一的
D. 哈夫曼树可以用来进行通信电文的编码和解码

13 B树

  B树,有时又写为B-树或B_树(其中的“-”或者“_”只是连字符,并不读作“B减树”)。一颗m阶的B树是一颗平衡的多路搜索树,它或者是空树,或者是满足下列性质的树。

  1. 树中每个结点至多有m棵子树。
  2. 若根结点不是叶子结点,则至少有两棵子树。
  3. 除根之外的所有非终端结点至少有[m/2](向上取整)棵子树。
  4. 所有的非终端结点中包含下列信息数据:

   $(n, A_0, K_1, A_1, K_2, A_2, …, K_n, A_n)$ ,其中: $K_i (i = 1, 2, …, n)$ 为关键字,且 $K_i < K_{i + 1}$ (i = 1, …, n - 1)。
   $A_i (i = 0, …, n)$ 为指向子树根结点的指针,且指针 $A_{i -1}$ 所指子树中所有结点的关键字均小于 $K_i(i = 1, …, n)$ , $A_n$ 所指子树中所有结点的关键字均大于 $K_n$ , $n ([m / 2] - 1 \leq n \leq m - 1)$ 为关键字的个数(或n + 1为子树个数)。其中[m / 2]表示向上取整。

  1. 所有的叶子结点都出现在同一层次上,并且不带信息(可以看作是外部结点或查找失败的结点,实际上这些结点不存在,指向这些结点的指针为空)。

BTree.png

14 B+树

  是B-树的一种变型,一个m阶的B+树具有如下几个特征。

  • 每个叶子结点中含有n个关键字和n个指向记录的指针,并且所有叶子节点彼此相链接构成一个有序链表,其头指针指向含最小关键字的节点。
  • 每个非叶子节点中的关键字 $K_i$ 即为其相应指针 $A_i$ 所指子树中关键字的最大值。
  • 所有叶子节点都处在统一层次上,每个叶子节点中关键字的个数均介于[m / 2](向上取整)和m之间。

B+Tree.png

15 散列表

  散列表构造的基本思想是:已知关键字集合U,最大关键字为m,设计一个函数Hash,它以关键字为自变量,关键字的存储地址为因变量,将关键字映射到一个有限的、地址连续的区间T[0 .. n - 1](n << m)中,这个区间就称为散列表,散列查找中使用的转换函数称为散列函数。

  例:假设有一个大小为7的表,现在要将(13, 18, 19s, 50, 20, 27)散列到表中。

  • 选择散列函数,例如使用hash(x) = x % 7作为散列函数。
  • 计算数据散列值,并放到合适的位置。
哈希地址 0 1 2 3 4 5 6
关键码 50 18 19 13

  地址重复时出现冲突,即散列冲突。

15.1 解决散列冲突

  • 链地址法(拉链法)
  • 开放地址法

   $H_i = (Hash(key) + d_i) % m$ i = 1, 2, …, k $(k \leq m - 1)$
  其中Hash(key)为哈希函数,m为哈希表的表长,di为增量序列。常见的增量序列有三种。

  • di = 1, 2, 3, …, m - 1,称为线性他侧再散列。
  • di = $1^2, {-1}^2, 2^2, {-2}^2, 3^3, …, ±k^2$ ,称为二次探测再散列。
  • di = 伪随机数列,称为随机探测再散列,如:di = Random(key)。

15.2 例题

  1. 用哈希表存储元素时,需要进行冲突(碰撞)处理,冲突是指(B)。

A. 关键字被依次映射到地址编号连续的存储位置
B. 关键字不同的元素被映射到相同的存储位置
C. 关键字相同的元素被映射到不同的存储位置
D. 关键字被映射到哈希表之外的位置

16 总结

  考查形式主要是概念区分以及部分计算题型,主要出现在上午的选择题当中。

  • 树的遍历
  • 图的遍历
  • 典型的时间复杂度

  需要记忆。

  • 数据结构与算法的概念
  • 线性表(顺序表、链表、栈、队列)
  • 数组与矩阵
  • 树与二叉树
  • 查找(二分查找、哈希)

5.2 链表基本操作

  • 单链表删除结点
  • 单链表插入结点
  • 双向链表删除结点
  • 双向链表插入结点

第九章——数据结构与算法

前言:
   计算机第九章节主要知识点。

1 知识点介绍

  • 数据结构与算法概念
  • 线性表
  • 数组与矩阵
  • 树与二叉树
  • 查找

2 数据结构定义

  • 数据结构
    • 数据逻辑结构:指数据元素之间的管理。
      • 线性结构:一对一关系
      • 非线性结构:一对多,多对多关系
    • 数据物理结构:数据在物理设备上具体如何存储。

3 算法概念

  算法的5个重要特征

  • 又穷性:执行有穷步之后结束,且每一步都可在有穷时间内完成。
  • 确定性:算法中每一条指令都必须由确切的含义,不能含糊不清。
  • 输入(>= 0)
  • 输出(>= 1)
  • 有效性(可行性):算法的每个步骤都能有效执行并能在执行有限此后得到确定的结果,例如a = 0,b / a就无效。

4 伪代码

  伪代码是一种算法描述语言,介于自然语言与编程语言之间,不用拘泥于具体的实现。

Pseudocode.png

5 线性表

5.1 线性表的概念

  常见线性表的两种存储结构。

  • 顺序存储结构(如:顺序表)
  • 链式存储结构(如:链表)

  逻辑上连续,物理上不一定连续。

  • 顺序表:随机存取。查询和修改容易,元素插入和删除麻烦,需要移动元素。
  • 链表
    • 单链表
    • 循环链表
    • 双向链表

LinearList.png

5.2 链表基本操作

  • 单链表删除结点
  • 单链表插入结点
  • 双向链表删除结点
  • 双向链表插入结点

LinkedList.png

5.3 例题

  1. 以下关于单链表存储结构特征的叙述中,不正确的是(D)。

A. 表中结点所占用存储空间的地址不必是连续的
B. 在表中任意位置进行插入和删除操作都不用移动元素
C. 所需空间与结点个数成正比
D. 可随机访问表中的任一结点

5.4 队列和栈

  元素按照a、b、c的次序进入栈,请尝试写出其所有可能的出栈序。

QueueAndStack.png

5.5 例题

  1. 令序列X、Y、Z的每个元素都按顺序进栈,且每个元素进栈和出栈仅一次,则不可能得到的出栈序列是(C)。

A. XYZ
B. XZY
C. ZXY
D. YZX

6 广义表

  广义表示n个表元素组成的有限序列,是线性表的推广,通常用递归的形式进行定义,记作: $LS = (a_0, a_1, …, a_n)$

注:其中LS是表名, $a_i$ 是表元素,它可以是表(称做子表),也可以是数据元素(称为原子)。其中n是广义表的长度(也就是最外层包含的元素个数),n = 0的广义表为空表;而递归定义的重数就是广义表的深度,直观地说,就是定义中所含括号的重数(原子的深度为0,空表的深度为1)。

例,有广义表LS1 = (a, (b, c), (d, e)),其长度为?深度为?
答案:长度为3,深度为2。

7 串

  串是仅由字符构成的有限序列,是取值范围受限的线性表,一般记为 S = ‘a1a2…an’,其中S是串名,单引号括起来的字符序列是串值。

8 数组

  二维数组分按行存储和按列存储。c/c++的多维数组是按行、连续存储逇。FORTRAN语言,Matlab中,数组按列优先顺序存储。

数组类型 存储地址计算
一维数组a[n] a[i]的存储地址为:a + i * len
二维数组a[m][n] a[i][j]的存储地址(按行存储)为:a + (i * n + j) * len
a[i][j]存储地址(按列存储)为:a + (j * m + i) * len

8.1 例题

  1. 数组a[1 … n, 1 … m](n > 1, m > 1)中的元素以行为主序存放,每个元素占用1个存储伟,则数组元素a[i, j] $(1 \leq i \leq n, 1 \leq j \leq m)$ 相对于数组空间首地址的偏移量为(A)

A. (i - 1) * m + j - 1
B. (i - 1) * n + j - 1
C. (j - 1) * m + i - 1
D. (j - 1) * n + i - 1

  1. 若二维数组arr[1 … M, 1 … N]的首地址为base,数组元素按列存储且每个元素占用K个存储单元,则元素arr[i, j]在该数组空间的地址为()。

A. base + ((i - 1) * M + j - 1) * K
B. base + ((i - 1) * N + j - 1) * K
C. base + ((j - 1) * M + i - 1) * K
D. base + ((j - 1) * N + i - 1) * K

9 树与二叉树

  • 结点的度
  • 树的高度
  • 叶子结点
  • 分支结点
  • 内部结点
  • 父结点
  • 子结点
  • 兄弟结点
  • 层次

BinaryTree.png

BinaryTree_1.png

  二叉树的重要特征。

  • 在二叉树的第i层上最多有 $2^{i - 1}$ 个结点 $(i \geq 1)$ ;
  • 深度为k的二叉树最多有 $2^k - 1$ 个结点 $(k \geq 1)$ ;
  • 对任何一颗二叉树,如果其叶子结点数为 $n_0$ ,度为2的结点数为 $n_2$ ,则 $n_0 = n_2 + 1$ 。
  • 如果对一颗有n个结点的完全二叉树的结点按层序编号(从第1层到 $log_2n + 1$ 层,每层从左到右),则对任一结点i $(i \geq i \geq n)$ ,有
    • 如果i = 1,则结点i无父结点,是二叉树的根;如果i > 1,则父结点是i / 2;
    • 如果2i > n,则结点i为叶子结点,无左子结点;否则,其左子结点是结点2i;
    • 如果2i + 1 > n,则结点i无右叶子结点,否则,其右子结点是结点2i + 1;

9.1 二叉树遍历

  • 前序遍历(根左右)
  • 中序遍历(左根右)
  • 后序遍历(左右根)
  • 层序遍历

  前序遍历:12457836,中序遍历:42785136,后序遍历:48752631,层次遍历:12345678。

TraversalOfBinaryTree.png

10 堆

  堆是计算机科学中的一类特殊的数据结构的统称。堆通常是一个可以被看做一颗完全二叉树的数组对象。
  若n个元素的序列 ${a_1, a_2 … a_n}$ 满足

Formula.png

  则分别称该序列 ${a_1, a_2, … a_n}$ 为小根堆和大根堆。
  从堆的定义可以看出,对实质是满足如下性质的完全二叉树:

  • 二叉树中任一非叶子结点均小于(大于)它的孩子结点。
  • 堆总是一颗完全二叉树。

  例如:下面序列为堆,对应的完全二叉树分别为。

1
2
98 77 35 62 55 14 35 48
14 48 35 62 55 98 35 77

Heap.png

10.1 例题

  1. 对于n个元素的关键字序列 ${k_1, k_2, … k_n}$ ,当且仅当满足关系 $k_j \leq k_{2i}$ 且 $k_i \leq k_{2i + 1}$ {i = 1.2…[n/2]}时称其为小根堆(小顶堆)。以下序列中,(D)不是小根堆。

A. 16, 25, 40, 55, 30, 50, 45
B. 16, 40, 25, 50, 45, 30, 55
C. 16, 25, 39, 41, 45, 43, 50
D. 16, 40, 25, 53, 39, 55, 45

11 图

11.1 图的存储

11.1.1 邻接矩阵表示法

  邻接矩阵表示法用一个n阶方阵R来存放图中各结点的关联信息,其矩阵元素 $R_{ij}$ 定义为。
  为无向图。表示稀疏矩阵时空间浪费大。

FigureOfTheStorage.png

11.1.2 邻接链条表示法

  首先把每个顶点的邻接顶点用链表表示出来,然后用一个一维数组来顺序存储上面每个链表的头指针。

ListFigure.png

11.2 例题

  1. 某有向图G的邻接表如下图所示,可看出该图中存在弧 $<v_2, V3>$ 而不存在从顶点 $V_1$ 出发的弧。以下关于图G的叙述中,错误的是()。

A. G中存在回路
B. G中每个顶点的入度为1
C. G的邻接矩阵是对称的
D. 不存在弧 $V_3, V_1>

ex1.png

11.3 图的遍历

GraphTraversal.png

12 查找算法

  • 五大查找
    • 顺序表查找
      • 顺序查找
      • 二分查找
      • 索引顺序查找
    • 树表查找
      • 二叉排序树
    • 散列表查找
      • 哈希查找

12.1 顺序查找

  顺序查找的过程:将待查找的关键字可key的元素从头到尾与表中元素进行比较,如果中间存在关键字为key的元素,则返回成功,否则返回失败。顺序查找主要针对少量的、无规则的数据。

1
4 7 10 18 30 2 46 24 15

12.2 二分查找

  二分法查找的基本过程是:(设R[low, …, high]是当前的查找区)

  • 确定该区间的中间位置:mid = [(low + high) / 2],向下取整。
  • 将待查的k值与R[mid].key比较,若相等,则查找成功并返回此位置,否则需确定新的查找区间,继续二分查找,具体方法如下。
    • 若R[mid].key > k,则由表的有序性可知R[mid, …, n].key均大于k,因此若表中存在关键字等于k的结点,则该结点必定是在位置mid左边的子表R[low, …, mid -1]中。因此,新的查找区间是左子表R[low, …, high],其中high = mid - 1.
    • 若R[mid].key < k,则要查找的k必在mid的右子表R[mid + 1, …, high]中,即新的查找区间是右子表R[low, …, high],其中low = mid + 1。
    • 若R[mid].key = k,则查找成功,算法结束。
  • 下次查找是针对新的查找区间进行,重复步骤(1)和(2)。
  • 在查找过程中,low逐步增加,而high逐步减少。如果high < low,则查找失败,算法结束。

12.3 二叉查找树(排序)

  二叉查找树的定义:二叉排序树或者是一颗空树,或者是具有如下特性的二叉树。

  • 若它的左子树不空,则左子树上所有节点的值均小于根节点的值。
  • 若它的有子树不空,则右子树上所有节点的值均大于根节点的值。
  • 它的左、右子树也都分别是二叉排序树。

  对二叉查找树进行中序遍历,即可得到有序的序列。

BinarySortTree.png

  查找过程:二叉查找(排序)树是先对待查找的数据进行生成树,确保数的左分支值小于右分支的值,然后再去和每个结点的父结点比较大小,查找最合适的范围。这个算法的查找效率很高,但是如果使用这种查找方法要首先创建数。
  具体步骤为。

  • 若查找的关键字等于根节点的关键字,查找成功。
  • 若查找的关键字小于根节点的关键字,递归查找左子树。
  • 若查找的关键字大于根节点的关键字,递归查找右子树。
  • 若子树为空,则查找不成功。

12.4 二叉平衡树

  定义:又称AVL树。它或者是一颗空树,或者是具有下列性质的二叉树:它的左子树或右子树都是平衡二叉树,且左子树和右子树的深度之差的绝对值不超过1。

  平衡因子。
  二叉树上任一结点的左子树深度减去右子树深度的差值,称为此结点的平衡因子。

AVL.png

12.5 例题

  1. 关于二叉排序树的说法,错误的是(C)。

A. 对于二叉排序树进行中序遍历,必定得到结点关键字的有序序列
B. 依据关键字无序的序列建立二叉排序,也可能构造出单支树
C. 若构造二叉排序树时进行平衡化处理,则根节点的左子树结点数与右子树结点数的差值一定不超过1
D. 若构造二叉排序树时进行平衡化处理,则根结点的左子树高度与右子树高度的差值一定不超过1

12.5 哈夫曼树

  定义:给定N个权值作为N个叶子节点,构造一颗二叉树,若该树的带权路径长度达到最小,称这样的二叉树为最优二叉树,也称为哈夫曼树。哈夫曼树是带权路径长度最短的数,权值较大的结点离根较近。
  一般可以按下面步骤构建。

  • 将所有左、右子树都为空的作为根节点。
  • 在森林中选取两棵根节点的权值最小的数作为一棵新树的左、右子树,且置新树的附加根节点的权值为其左、右子树上根结点的权值之和。
  • 从森林中删除这两棵树,同时把新树加入到森林中。
  • 重复2、3步骤,直到森林中只有一棵树为止,此树便是哈夫曼树。

HuffmanTree.png

HuffmanTree_.png

  应用场景:对字符集中的字符进行编码和译码。

12.6 例题

  1. 以下有关哈夫曼树的说法中,错误的是(C)。

A. 哈夫曼树又被称为最优二叉树
B. 哈夫曼树是一种带权路径长度最短的树
C. 具有n个叶子结点的权值为 $W_1, W_2, …, W_n$ 的最优二叉树是唯一的
D. 哈夫曼树可以用来进行通信电文的编码和解码

13 B树

  B树,有时又写为B-树或B_树(其中的“-”或者“_”只是连字符,并不读作“B减树”)。一颗m阶的B树是一颗平衡的多路搜索树,它或者是空树,或者是满足下列性质的树。

  1. 树中每个结点至多有m棵子树。
  2. 若根结点不是叶子结点,则至少有两棵子树。
  3. 除根之外的所有非终端结点至少有[m/2](向上取整)棵子树。
  4. 所有的非终端结点中包含下列信息数据:

   $(n, A_0, K_1, A_1, K_2, A_2, …, K_n, A_n)$ ,其中: $K_i (i = 1, 2, …, n)$ 为关键字,且 $K_i < K_{i + 1}$ (i = 1, …, n - 1)。
   $A_i (i = 0, …, n)$ 为指向子树根结点的指针,且指针 $A_{i -1}$ 所指子树中所有结点的关键字均小于 $K_i(i = 1, …, n)$ , $A_n$ 所指子树中所有结点的关键字均大于 $K_n$ , $n ([m / 2] - 1 \leq n \leq m - 1)$ 为关键字的个数(或n + 1为子树个数)。其中[m / 2]表示向上取整。

  1. 所有的叶子结点都出现在同一层次上,并且不带信息(可以看作是外部结点或查找失败的结点,实际上这些结点不存在,指向这些结点的指针为空)。

BTree.png

14 B+树

  是B-树的一种变型,一个m阶的B+树具有如下几个特征。

  • 每个叶子结点中含有n个关键字和n个指向记录的指针,并且所有叶子节点彼此相链接构成一个有序链表,其头指针指向含最小关键字的节点。
  • 每个非叶子节点中的关键字 $K_i$ 即为其相应指针 $A_i$ 所指子树中关键字的最大值。
  • 所有叶子节点都处在统一层次上,每个叶子节点中关键字的个数均介于[m / 2](向上取整)和m之间。

B+Tree.png

15 散列表

  散列表构造的基本思想是:已知关键字集合U,最大关键字为m,设计一个函数Hash,它以关键字为自变量,关键字的存储地址为因变量,将关键字映射到一个有限的、地址连续的区间T[0 .. n - 1](n << m)中,这个区间就称为散列表,散列查找中使用的转换函数称为散列函数。

  例:假设有一个大小为7的表,现在要将(13, 18, 19s, 50, 20, 27)散列到表中。

  • 选择散列函数,例如使用hash(x) = x % 7作为散列函数。
  • 计算数据散列值,并放到合适的位置。
哈希地址 0 1 2 3 4 5 6
关键码 50 18 19 13

  地址重复时出现冲突,即散列冲突。

15.1 解决散列冲突

  • 链地址法(拉链法)
  • 开放地址法

   $H_i = (Hash(key) + d_i) % m$ i = 1, 2, …, k $(k \leq m - 1)$
  其中Hash(key)为哈希函数,m为哈希表的表长,di为增量序列。常见的增量序列有三种。

  • di = 1, 2, 3, …, m - 1,称为线性他侧再散列。
  • di = $1^2, {-1}^2, 2^2, {-2}^2, 3^3, …, ±k^2$ ,称为二次探测再散列。
  • di = 伪随机数列,称为随机探测再散列,如:di = Random(key)。

15.2 例题

  1. 用哈希表存储元素时,需要进行冲突(碰撞)处理,冲突是指(B)。

A. 关键字被依次映射到地址编号连续的存储位置
B. 关键字不同的元素被映射到相同的存储位置
C. 关键字相同的元素被映射到不同的存储位置
D. 关键字被映射到哈希表之外的位置

16 总结

  考查形式主要是概念区分以及部分计算题型,主要出现在上午的选择题当中。

  • 树的遍历
  • 图的遍历
  • 典型的时间复杂度

  需要记忆。

  • 数据结构与算法的概念
  • 线性表(顺序表、链表、栈、队列)
  • 数组与矩阵
  • 树与二叉树
  • 查找(二分查找、哈希)

5.3 例题

  1. 以下关于单链表存储结构特征的叙述中,不正确的是(D)。

A. 表中结点所占用存储空间的地址不必是连续的
B. 在表中任意位置进行插入和删除操作都不用移动元素
C. 所需空间与结点个数成正比
D. 可随机访问表中的任一结点

5.4 队列和栈

  元素按照a、b、c的次序进入栈,请尝试写出其所有可能的出栈序。

第九章——数据结构与算法

前言:
   计算机第九章节主要知识点。

1 知识点介绍

  • 数据结构与算法概念
  • 线性表
  • 数组与矩阵
  • 树与二叉树
  • 查找

2 数据结构定义

  • 数据结构
    • 数据逻辑结构:指数据元素之间的管理。
      • 线性结构:一对一关系
      • 非线性结构:一对多,多对多关系
    • 数据物理结构:数据在物理设备上具体如何存储。

3 算法概念

  算法的5个重要特征

  • 又穷性:执行有穷步之后结束,且每一步都可在有穷时间内完成。
  • 确定性:算法中每一条指令都必须由确切的含义,不能含糊不清。
  • 输入(>= 0)
  • 输出(>= 1)
  • 有效性(可行性):算法的每个步骤都能有效执行并能在执行有限此后得到确定的结果,例如a = 0,b / a就无效。

4 伪代码

  伪代码是一种算法描述语言,介于自然语言与编程语言之间,不用拘泥于具体的实现。

Pseudocode.png

5 线性表

5.1 线性表的概念

  常见线性表的两种存储结构。

  • 顺序存储结构(如:顺序表)
  • 链式存储结构(如:链表)

  逻辑上连续,物理上不一定连续。

  • 顺序表:随机存取。查询和修改容易,元素插入和删除麻烦,需要移动元素。
  • 链表
    • 单链表
    • 循环链表
    • 双向链表

LinearList.png

5.2 链表基本操作

  • 单链表删除结点
  • 单链表插入结点
  • 双向链表删除结点
  • 双向链表插入结点

LinkedList.png

5.3 例题

  1. 以下关于单链表存储结构特征的叙述中,不正确的是(D)。

A. 表中结点所占用存储空间的地址不必是连续的
B. 在表中任意位置进行插入和删除操作都不用移动元素
C. 所需空间与结点个数成正比
D. 可随机访问表中的任一结点

5.4 队列和栈

  元素按照a、b、c的次序进入栈,请尝试写出其所有可能的出栈序。

QueueAndStack.png

5.5 例题

  1. 令序列X、Y、Z的每个元素都按顺序进栈,且每个元素进栈和出栈仅一次,则不可能得到的出栈序列是(C)。

A. XYZ
B. XZY
C. ZXY
D. YZX

6 广义表

  广义表示n个表元素组成的有限序列,是线性表的推广,通常用递归的形式进行定义,记作: $LS = (a_0, a_1, …, a_n)$

注:其中LS是表名, $a_i$ 是表元素,它可以是表(称做子表),也可以是数据元素(称为原子)。其中n是广义表的长度(也就是最外层包含的元素个数),n = 0的广义表为空表;而递归定义的重数就是广义表的深度,直观地说,就是定义中所含括号的重数(原子的深度为0,空表的深度为1)。

例,有广义表LS1 = (a, (b, c), (d, e)),其长度为?深度为?
答案:长度为3,深度为2。

7 串

  串是仅由字符构成的有限序列,是取值范围受限的线性表,一般记为 S = ‘a1a2…an’,其中S是串名,单引号括起来的字符序列是串值。

8 数组

  二维数组分按行存储和按列存储。c/c++的多维数组是按行、连续存储逇。FORTRAN语言,Matlab中,数组按列优先顺序存储。

数组类型 存储地址计算
一维数组a[n] a[i]的存储地址为:a + i * len
二维数组a[m][n] a[i][j]的存储地址(按行存储)为:a + (i * n + j) * len
a[i][j]存储地址(按列存储)为:a + (j * m + i) * len

8.1 例题

  1. 数组a[1 … n, 1 … m](n > 1, m > 1)中的元素以行为主序存放,每个元素占用1个存储伟,则数组元素a[i, j] $(1 \leq i \leq n, 1 \leq j \leq m)$ 相对于数组空间首地址的偏移量为(A)

A. (i - 1) * m + j - 1
B. (i - 1) * n + j - 1
C. (j - 1) * m + i - 1
D. (j - 1) * n + i - 1

  1. 若二维数组arr[1 … M, 1 … N]的首地址为base,数组元素按列存储且每个元素占用K个存储单元,则元素arr[i, j]在该数组空间的地址为()。

A. base + ((i - 1) * M + j - 1) * K
B. base + ((i - 1) * N + j - 1) * K
C. base + ((j - 1) * M + i - 1) * K
D. base + ((j - 1) * N + i - 1) * K

9 树与二叉树

  • 结点的度
  • 树的高度
  • 叶子结点
  • 分支结点
  • 内部结点
  • 父结点
  • 子结点
  • 兄弟结点
  • 层次

BinaryTree.png

BinaryTree_1.png

  二叉树的重要特征。

  • 在二叉树的第i层上最多有 $2^{i - 1}$ 个结点 $(i \geq 1)$ ;
  • 深度为k的二叉树最多有 $2^k - 1$ 个结点 $(k \geq 1)$ ;
  • 对任何一颗二叉树,如果其叶子结点数为 $n_0$ ,度为2的结点数为 $n_2$ ,则 $n_0 = n_2 + 1$ 。
  • 如果对一颗有n个结点的完全二叉树的结点按层序编号(从第1层到 $log_2n + 1$ 层,每层从左到右),则对任一结点i $(i \geq i \geq n)$ ,有
    • 如果i = 1,则结点i无父结点,是二叉树的根;如果i > 1,则父结点是i / 2;
    • 如果2i > n,则结点i为叶子结点,无左子结点;否则,其左子结点是结点2i;
    • 如果2i + 1 > n,则结点i无右叶子结点,否则,其右子结点是结点2i + 1;

9.1 二叉树遍历

  • 前序遍历(根左右)
  • 中序遍历(左根右)
  • 后序遍历(左右根)
  • 层序遍历

  前序遍历:12457836,中序遍历:42785136,后序遍历:48752631,层次遍历:12345678。

TraversalOfBinaryTree.png

10 堆

  堆是计算机科学中的一类特殊的数据结构的统称。堆通常是一个可以被看做一颗完全二叉树的数组对象。
  若n个元素的序列 ${a_1, a_2 … a_n}$ 满足

Formula.png

  则分别称该序列 ${a_1, a_2, … a_n}$ 为小根堆和大根堆。
  从堆的定义可以看出,对实质是满足如下性质的完全二叉树:

  • 二叉树中任一非叶子结点均小于(大于)它的孩子结点。
  • 堆总是一颗完全二叉树。

  例如:下面序列为堆,对应的完全二叉树分别为。

1
2
98 77 35 62 55 14 35 48
14 48 35 62 55 98 35 77

Heap.png

10.1 例题

  1. 对于n个元素的关键字序列 ${k_1, k_2, … k_n}$ ,当且仅当满足关系 $k_j \leq k_{2i}$ 且 $k_i \leq k_{2i + 1}$ {i = 1.2…[n/2]}时称其为小根堆(小顶堆)。以下序列中,(D)不是小根堆。

A. 16, 25, 40, 55, 30, 50, 45
B. 16, 40, 25, 50, 45, 30, 55
C. 16, 25, 39, 41, 45, 43, 50
D. 16, 40, 25, 53, 39, 55, 45

11 图

11.1 图的存储

11.1.1 邻接矩阵表示法

  邻接矩阵表示法用一个n阶方阵R来存放图中各结点的关联信息,其矩阵元素 $R_{ij}$ 定义为。
  为无向图。表示稀疏矩阵时空间浪费大。

FigureOfTheStorage.png

11.1.2 邻接链条表示法

  首先把每个顶点的邻接顶点用链表表示出来,然后用一个一维数组来顺序存储上面每个链表的头指针。

ListFigure.png

11.2 例题

  1. 某有向图G的邻接表如下图所示,可看出该图中存在弧 $<v_2, V3>$ 而不存在从顶点 $V_1$ 出发的弧。以下关于图G的叙述中,错误的是()。

A. G中存在回路
B. G中每个顶点的入度为1
C. G的邻接矩阵是对称的
D. 不存在弧 $V_3, V_1>

ex1.png

11.3 图的遍历

GraphTraversal.png

12 查找算法

  • 五大查找
    • 顺序表查找
      • 顺序查找
      • 二分查找
      • 索引顺序查找
    • 树表查找
      • 二叉排序树
    • 散列表查找
      • 哈希查找

12.1 顺序查找

  顺序查找的过程:将待查找的关键字可key的元素从头到尾与表中元素进行比较,如果中间存在关键字为key的元素,则返回成功,否则返回失败。顺序查找主要针对少量的、无规则的数据。

1
4 7 10 18 30 2 46 24 15

12.2 二分查找

  二分法查找的基本过程是:(设R[low, …, high]是当前的查找区)

  • 确定该区间的中间位置:mid = [(low + high) / 2],向下取整。
  • 将待查的k值与R[mid].key比较,若相等,则查找成功并返回此位置,否则需确定新的查找区间,继续二分查找,具体方法如下。
    • 若R[mid].key > k,则由表的有序性可知R[mid, …, n].key均大于k,因此若表中存在关键字等于k的结点,则该结点必定是在位置mid左边的子表R[low, …, mid -1]中。因此,新的查找区间是左子表R[low, …, high],其中high = mid - 1.
    • 若R[mid].key < k,则要查找的k必在mid的右子表R[mid + 1, …, high]中,即新的查找区间是右子表R[low, …, high],其中low = mid + 1。
    • 若R[mid].key = k,则查找成功,算法结束。
  • 下次查找是针对新的查找区间进行,重复步骤(1)和(2)。
  • 在查找过程中,low逐步增加,而high逐步减少。如果high < low,则查找失败,算法结束。

12.3 二叉查找树(排序)

  二叉查找树的定义:二叉排序树或者是一颗空树,或者是具有如下特性的二叉树。

  • 若它的左子树不空,则左子树上所有节点的值均小于根节点的值。
  • 若它的有子树不空,则右子树上所有节点的值均大于根节点的值。
  • 它的左、右子树也都分别是二叉排序树。

  对二叉查找树进行中序遍历,即可得到有序的序列。

BinarySortTree.png

  查找过程:二叉查找(排序)树是先对待查找的数据进行生成树,确保数的左分支值小于右分支的值,然后再去和每个结点的父结点比较大小,查找最合适的范围。这个算法的查找效率很高,但是如果使用这种查找方法要首先创建数。
  具体步骤为。

  • 若查找的关键字等于根节点的关键字,查找成功。
  • 若查找的关键字小于根节点的关键字,递归查找左子树。
  • 若查找的关键字大于根节点的关键字,递归查找右子树。
  • 若子树为空,则查找不成功。

12.4 二叉平衡树

  定义:又称AVL树。它或者是一颗空树,或者是具有下列性质的二叉树:它的左子树或右子树都是平衡二叉树,且左子树和右子树的深度之差的绝对值不超过1。

  平衡因子。
  二叉树上任一结点的左子树深度减去右子树深度的差值,称为此结点的平衡因子。

AVL.png

12.5 例题

  1. 关于二叉排序树的说法,错误的是(C)。

A. 对于二叉排序树进行中序遍历,必定得到结点关键字的有序序列
B. 依据关键字无序的序列建立二叉排序,也可能构造出单支树
C. 若构造二叉排序树时进行平衡化处理,则根节点的左子树结点数与右子树结点数的差值一定不超过1
D. 若构造二叉排序树时进行平衡化处理,则根结点的左子树高度与右子树高度的差值一定不超过1

12.5 哈夫曼树

  定义:给定N个权值作为N个叶子节点,构造一颗二叉树,若该树的带权路径长度达到最小,称这样的二叉树为最优二叉树,也称为哈夫曼树。哈夫曼树是带权路径长度最短的数,权值较大的结点离根较近。
  一般可以按下面步骤构建。

  • 将所有左、右子树都为空的作为根节点。
  • 在森林中选取两棵根节点的权值最小的数作为一棵新树的左、右子树,且置新树的附加根节点的权值为其左、右子树上根结点的权值之和。
  • 从森林中删除这两棵树,同时把新树加入到森林中。
  • 重复2、3步骤,直到森林中只有一棵树为止,此树便是哈夫曼树。

HuffmanTree.png

HuffmanTree_.png

  应用场景:对字符集中的字符进行编码和译码。

12.6 例题

  1. 以下有关哈夫曼树的说法中,错误的是(C)。

A. 哈夫曼树又被称为最优二叉树
B. 哈夫曼树是一种带权路径长度最短的树
C. 具有n个叶子结点的权值为 $W_1, W_2, …, W_n$ 的最优二叉树是唯一的
D. 哈夫曼树可以用来进行通信电文的编码和解码

13 B树

  B树,有时又写为B-树或B_树(其中的“-”或者“_”只是连字符,并不读作“B减树”)。一颗m阶的B树是一颗平衡的多路搜索树,它或者是空树,或者是满足下列性质的树。

  1. 树中每个结点至多有m棵子树。
  2. 若根结点不是叶子结点,则至少有两棵子树。
  3. 除根之外的所有非终端结点至少有[m/2](向上取整)棵子树。
  4. 所有的非终端结点中包含下列信息数据:

   $(n, A_0, K_1, A_1, K_2, A_2, …, K_n, A_n)$ ,其中: $K_i (i = 1, 2, …, n)$ 为关键字,且 $K_i < K_{i + 1}$ (i = 1, …, n - 1)。
   $A_i (i = 0, …, n)$ 为指向子树根结点的指针,且指针 $A_{i -1}$ 所指子树中所有结点的关键字均小于 $K_i(i = 1, …, n)$ , $A_n$ 所指子树中所有结点的关键字均大于 $K_n$ , $n ([m / 2] - 1 \leq n \leq m - 1)$ 为关键字的个数(或n + 1为子树个数)。其中[m / 2]表示向上取整。

  1. 所有的叶子结点都出现在同一层次上,并且不带信息(可以看作是外部结点或查找失败的结点,实际上这些结点不存在,指向这些结点的指针为空)。

BTree.png

14 B+树

  是B-树的一种变型,一个m阶的B+树具有如下几个特征。

  • 每个叶子结点中含有n个关键字和n个指向记录的指针,并且所有叶子节点彼此相链接构成一个有序链表,其头指针指向含最小关键字的节点。
  • 每个非叶子节点中的关键字 $K_i$ 即为其相应指针 $A_i$ 所指子树中关键字的最大值。
  • 所有叶子节点都处在统一层次上,每个叶子节点中关键字的个数均介于[m / 2](向上取整)和m之间。

B+Tree.png

15 散列表

  散列表构造的基本思想是:已知关键字集合U,最大关键字为m,设计一个函数Hash,它以关键字为自变量,关键字的存储地址为因变量,将关键字映射到一个有限的、地址连续的区间T[0 .. n - 1](n << m)中,这个区间就称为散列表,散列查找中使用的转换函数称为散列函数。

  例:假设有一个大小为7的表,现在要将(13, 18, 19s, 50, 20, 27)散列到表中。

  • 选择散列函数,例如使用hash(x) = x % 7作为散列函数。
  • 计算数据散列值,并放到合适的位置。
哈希地址 0 1 2 3 4 5 6
关键码 50 18 19 13

  地址重复时出现冲突,即散列冲突。

15.1 解决散列冲突

  • 链地址法(拉链法)
  • 开放地址法

   $H_i = (Hash(key) + d_i) % m$ i = 1, 2, …, k $(k \leq m - 1)$
  其中Hash(key)为哈希函数,m为哈希表的表长,di为增量序列。常见的增量序列有三种。

  • di = 1, 2, 3, …, m - 1,称为线性他侧再散列。
  • di = $1^2, {-1}^2, 2^2, {-2}^2, 3^3, …, ±k^2$ ,称为二次探测再散列。
  • di = 伪随机数列,称为随机探测再散列,如:di = Random(key)。

15.2 例题

  1. 用哈希表存储元素时,需要进行冲突(碰撞)处理,冲突是指(B)。

A. 关键字被依次映射到地址编号连续的存储位置
B. 关键字不同的元素被映射到相同的存储位置
C. 关键字相同的元素被映射到不同的存储位置
D. 关键字被映射到哈希表之外的位置

16 总结

  考查形式主要是概念区分以及部分计算题型,主要出现在上午的选择题当中。

  • 树的遍历
  • 图的遍历
  • 典型的时间复杂度

  需要记忆。

  • 数据结构与算法的概念
  • 线性表(顺序表、链表、栈、队列)
  • 数组与矩阵
  • 树与二叉树
  • 查找(二分查找、哈希)

5.5 例题

  1. 令序列X、Y、Z的每个元素都按顺序进栈,且每个元素进栈和出栈仅一次,则不可能得到的出栈序列是(C)。

A. XYZ
B. XZY
C. ZXY
D. YZX

6 广义表

  广义表示n个表元素组成的有限序列,是线性表的推广,通常用递归的形式进行定义,记作: $LS = (a_0, a_1, …, a_n)$

注:其中LS是表名, $a_i$ 是表元素,它可以是表(称做子表),也可以是数据元素(称为原子)。其中n是广义表的长度(也就是最外层包含的元素个数),n = 0的广义表为空表;而递归定义的重数就是广义表的深度,直观地说,就是定义中所含括号的重数(原子的深度为0,空表的深度为1)。

例,有广义表LS1 = (a, (b, c), (d, e)),其长度为?深度为?
答案:长度为3,深度为2。

7 串

  串是仅由字符构成的有限序列,是取值范围受限的线性表,一般记为 S = ‘a1a2…an’,其中S是串名,单引号括起来的字符序列是串值。

8 数组

  二维数组分按行存储和按列存储。c/c++的多维数组是按行、连续存储逇。FORTRAN语言,Matlab中,数组按列优先顺序存储。

数组类型 存储地址计算
一维数组a[n] a[i]的存储地址为:a + i * len
二维数组a[m][n] a[i][j]的存储地址(按行存储)为:a + (i * n + j) * len
a[i][j]存储地址(按列存储)为:a + (j * m + i) * len

8.1 例题

  1. 数组a[1 … n, 1 … m](n > 1, m > 1)中的元素以行为主序存放,每个元素占用1个存储伟,则数组元素a[i, j] $(1 \leq i \leq n, 1 \leq j \leq m)$ 相对于数组空间首地址的偏移量为(A)

A. (i - 1) * m + j - 1
B. (i - 1) * n + j - 1
C. (j - 1) * m + i - 1
D. (j - 1) * n + i - 1

  1. 若二维数组arr[1 … M, 1 … N]的首地址为base,数组元素按列存储且每个元素占用K个存储单元,则元素arr[i, j]在该数组空间的地址为()。

A. base + ((i - 1) * M + j - 1) * K
B. base + ((i - 1) * N + j - 1) * K
C. base + ((j - 1) * M + i - 1) * K
D. base + ((j - 1) * N + i - 1) * K

9 树与二叉树

  • 结点的度
  • 树的高度
  • 叶子结点
  • 分支结点
  • 内部结点
  • 父结点
  • 子结点
  • 兄弟结点
  • 层次

第九章——数据结构与算法

前言:
   计算机第九章节主要知识点。

1 知识点介绍

  • 数据结构与算法概念
  • 线性表
  • 数组与矩阵
  • 树与二叉树
  • 查找

2 数据结构定义

  • 数据结构
    • 数据逻辑结构:指数据元素之间的管理。
      • 线性结构:一对一关系
      • 非线性结构:一对多,多对多关系
    • 数据物理结构:数据在物理设备上具体如何存储。

3 算法概念

  算法的5个重要特征

  • 又穷性:执行有穷步之后结束,且每一步都可在有穷时间内完成。
  • 确定性:算法中每一条指令都必须由确切的含义,不能含糊不清。
  • 输入(>= 0)
  • 输出(>= 1)
  • 有效性(可行性):算法的每个步骤都能有效执行并能在执行有限此后得到确定的结果,例如a = 0,b / a就无效。

4 伪代码

  伪代码是一种算法描述语言,介于自然语言与编程语言之间,不用拘泥于具体的实现。

Pseudocode.png

5 线性表

5.1 线性表的概念

  常见线性表的两种存储结构。

  • 顺序存储结构(如:顺序表)
  • 链式存储结构(如:链表)

  逻辑上连续,物理上不一定连续。

  • 顺序表:随机存取。查询和修改容易,元素插入和删除麻烦,需要移动元素。
  • 链表
    • 单链表
    • 循环链表
    • 双向链表

LinearList.png

5.2 链表基本操作

  • 单链表删除结点
  • 单链表插入结点
  • 双向链表删除结点
  • 双向链表插入结点

LinkedList.png

5.3 例题

  1. 以下关于单链表存储结构特征的叙述中,不正确的是(D)。

A. 表中结点所占用存储空间的地址不必是连续的
B. 在表中任意位置进行插入和删除操作都不用移动元素
C. 所需空间与结点个数成正比
D. 可随机访问表中的任一结点

5.4 队列和栈

  元素按照a、b、c的次序进入栈,请尝试写出其所有可能的出栈序。

QueueAndStack.png

5.5 例题

  1. 令序列X、Y、Z的每个元素都按顺序进栈,且每个元素进栈和出栈仅一次,则不可能得到的出栈序列是(C)。

A. XYZ
B. XZY
C. ZXY
D. YZX

6 广义表

  广义表示n个表元素组成的有限序列,是线性表的推广,通常用递归的形式进行定义,记作: $LS = (a_0, a_1, …, a_n)$

注:其中LS是表名, $a_i$ 是表元素,它可以是表(称做子表),也可以是数据元素(称为原子)。其中n是广义表的长度(也就是最外层包含的元素个数),n = 0的广义表为空表;而递归定义的重数就是广义表的深度,直观地说,就是定义中所含括号的重数(原子的深度为0,空表的深度为1)。

例,有广义表LS1 = (a, (b, c), (d, e)),其长度为?深度为?
答案:长度为3,深度为2。

7 串

  串是仅由字符构成的有限序列,是取值范围受限的线性表,一般记为 S = ‘a1a2…an’,其中S是串名,单引号括起来的字符序列是串值。

8 数组

  二维数组分按行存储和按列存储。c/c++的多维数组是按行、连续存储逇。FORTRAN语言,Matlab中,数组按列优先顺序存储。

数组类型 存储地址计算
一维数组a[n] a[i]的存储地址为:a + i * len
二维数组a[m][n] a[i][j]的存储地址(按行存储)为:a + (i * n + j) * len
a[i][j]存储地址(按列存储)为:a + (j * m + i) * len

8.1 例题

  1. 数组a[1 … n, 1 … m](n > 1, m > 1)中的元素以行为主序存放,每个元素占用1个存储伟,则数组元素a[i, j] $(1 \leq i \leq n, 1 \leq j \leq m)$ 相对于数组空间首地址的偏移量为(A)

A. (i - 1) * m + j - 1
B. (i - 1) * n + j - 1
C. (j - 1) * m + i - 1
D. (j - 1) * n + i - 1

  1. 若二维数组arr[1 … M, 1 … N]的首地址为base,数组元素按列存储且每个元素占用K个存储单元,则元素arr[i, j]在该数组空间的地址为()。

A. base + ((i - 1) * M + j - 1) * K
B. base + ((i - 1) * N + j - 1) * K
C. base + ((j - 1) * M + i - 1) * K
D. base + ((j - 1) * N + i - 1) * K

9 树与二叉树

  • 结点的度
  • 树的高度
  • 叶子结点
  • 分支结点
  • 内部结点
  • 父结点
  • 子结点
  • 兄弟结点
  • 层次

BinaryTree.png

BinaryTree_1.png

  二叉树的重要特征。

  • 在二叉树的第i层上最多有 $2^{i - 1}$ 个结点 $(i \geq 1)$ ;
  • 深度为k的二叉树最多有 $2^k - 1$ 个结点 $(k \geq 1)$ ;
  • 对任何一颗二叉树,如果其叶子结点数为 $n_0$ ,度为2的结点数为 $n_2$ ,则 $n_0 = n_2 + 1$ 。
  • 如果对一颗有n个结点的完全二叉树的结点按层序编号(从第1层到 $log_2n + 1$ 层,每层从左到右),则对任一结点i $(i \geq i \geq n)$ ,有
    • 如果i = 1,则结点i无父结点,是二叉树的根;如果i > 1,则父结点是i / 2;
    • 如果2i > n,则结点i为叶子结点,无左子结点;否则,其左子结点是结点2i;
    • 如果2i + 1 > n,则结点i无右叶子结点,否则,其右子结点是结点2i + 1;

9.1 二叉树遍历

  • 前序遍历(根左右)
  • 中序遍历(左根右)
  • 后序遍历(左右根)
  • 层序遍历

  前序遍历:12457836,中序遍历:42785136,后序遍历:48752631,层次遍历:12345678。

TraversalOfBinaryTree.png

10 堆

  堆是计算机科学中的一类特殊的数据结构的统称。堆通常是一个可以被看做一颗完全二叉树的数组对象。
  若n个元素的序列 ${a_1, a_2 … a_n}$ 满足

Formula.png

  则分别称该序列 ${a_1, a_2, … a_n}$ 为小根堆和大根堆。
  从堆的定义可以看出,对实质是满足如下性质的完全二叉树:

  • 二叉树中任一非叶子结点均小于(大于)它的孩子结点。
  • 堆总是一颗完全二叉树。

  例如:下面序列为堆,对应的完全二叉树分别为。

1
2
98 77 35 62 55 14 35 48
14 48 35 62 55 98 35 77

Heap.png

10.1 例题

  1. 对于n个元素的关键字序列 ${k_1, k_2, … k_n}$ ,当且仅当满足关系 $k_j \leq k_{2i}$ 且 $k_i \leq k_{2i + 1}$ {i = 1.2…[n/2]}时称其为小根堆(小顶堆)。以下序列中,(D)不是小根堆。

A. 16, 25, 40, 55, 30, 50, 45
B. 16, 40, 25, 50, 45, 30, 55
C. 16, 25, 39, 41, 45, 43, 50
D. 16, 40, 25, 53, 39, 55, 45

11 图

11.1 图的存储

11.1.1 邻接矩阵表示法

  邻接矩阵表示法用一个n阶方阵R来存放图中各结点的关联信息,其矩阵元素 $R_{ij}$ 定义为。
  为无向图。表示稀疏矩阵时空间浪费大。

FigureOfTheStorage.png

11.1.2 邻接链条表示法

  首先把每个顶点的邻接顶点用链表表示出来,然后用一个一维数组来顺序存储上面每个链表的头指针。

ListFigure.png

11.2 例题

  1. 某有向图G的邻接表如下图所示,可看出该图中存在弧 $<v_2, V3>$ 而不存在从顶点 $V_1$ 出发的弧。以下关于图G的叙述中,错误的是()。

A. G中存在回路
B. G中每个顶点的入度为1
C. G的邻接矩阵是对称的
D. 不存在弧 $V_3, V_1>

ex1.png

11.3 图的遍历

GraphTraversal.png

12 查找算法

  • 五大查找
    • 顺序表查找
      • 顺序查找
      • 二分查找
      • 索引顺序查找
    • 树表查找
      • 二叉排序树
    • 散列表查找
      • 哈希查找

12.1 顺序查找

  顺序查找的过程:将待查找的关键字可key的元素从头到尾与表中元素进行比较,如果中间存在关键字为key的元素,则返回成功,否则返回失败。顺序查找主要针对少量的、无规则的数据。

1
4 7 10 18 30 2 46 24 15

12.2 二分查找

  二分法查找的基本过程是:(设R[low, …, high]是当前的查找区)

  • 确定该区间的中间位置:mid = [(low + high) / 2],向下取整。
  • 将待查的k值与R[mid].key比较,若相等,则查找成功并返回此位置,否则需确定新的查找区间,继续二分查找,具体方法如下。
    • 若R[mid].key > k,则由表的有序性可知R[mid, …, n].key均大于k,因此若表中存在关键字等于k的结点,则该结点必定是在位置mid左边的子表R[low, …, mid -1]中。因此,新的查找区间是左子表R[low, …, high],其中high = mid - 1.
    • 若R[mid].key < k,则要查找的k必在mid的右子表R[mid + 1, …, high]中,即新的查找区间是右子表R[low, …, high],其中low = mid + 1。
    • 若R[mid].key = k,则查找成功,算法结束。
  • 下次查找是针对新的查找区间进行,重复步骤(1)和(2)。
  • 在查找过程中,low逐步增加,而high逐步减少。如果high < low,则查找失败,算法结束。

12.3 二叉查找树(排序)

  二叉查找树的定义:二叉排序树或者是一颗空树,或者是具有如下特性的二叉树。

  • 若它的左子树不空,则左子树上所有节点的值均小于根节点的值。
  • 若它的有子树不空,则右子树上所有节点的值均大于根节点的值。
  • 它的左、右子树也都分别是二叉排序树。

  对二叉查找树进行中序遍历,即可得到有序的序列。

BinarySortTree.png

  查找过程:二叉查找(排序)树是先对待查找的数据进行生成树,确保数的左分支值小于右分支的值,然后再去和每个结点的父结点比较大小,查找最合适的范围。这个算法的查找效率很高,但是如果使用这种查找方法要首先创建数。
  具体步骤为。

  • 若查找的关键字等于根节点的关键字,查找成功。
  • 若查找的关键字小于根节点的关键字,递归查找左子树。
  • 若查找的关键字大于根节点的关键字,递归查找右子树。
  • 若子树为空,则查找不成功。

12.4 二叉平衡树

  定义:又称AVL树。它或者是一颗空树,或者是具有下列性质的二叉树:它的左子树或右子树都是平衡二叉树,且左子树和右子树的深度之差的绝对值不超过1。

  平衡因子。
  二叉树上任一结点的左子树深度减去右子树深度的差值,称为此结点的平衡因子。

AVL.png

12.5 例题

  1. 关于二叉排序树的说法,错误的是(C)。

A. 对于二叉排序树进行中序遍历,必定得到结点关键字的有序序列
B. 依据关键字无序的序列建立二叉排序,也可能构造出单支树
C. 若构造二叉排序树时进行平衡化处理,则根节点的左子树结点数与右子树结点数的差值一定不超过1
D. 若构造二叉排序树时进行平衡化处理,则根结点的左子树高度与右子树高度的差值一定不超过1

12.5 哈夫曼树

  定义:给定N个权值作为N个叶子节点,构造一颗二叉树,若该树的带权路径长度达到最小,称这样的二叉树为最优二叉树,也称为哈夫曼树。哈夫曼树是带权路径长度最短的数,权值较大的结点离根较近。
  一般可以按下面步骤构建。

  • 将所有左、右子树都为空的作为根节点。
  • 在森林中选取两棵根节点的权值最小的数作为一棵新树的左、右子树,且置新树的附加根节点的权值为其左、右子树上根结点的权值之和。
  • 从森林中删除这两棵树,同时把新树加入到森林中。
  • 重复2、3步骤,直到森林中只有一棵树为止,此树便是哈夫曼树。

HuffmanTree.png

HuffmanTree_.png

  应用场景:对字符集中的字符进行编码和译码。

12.6 例题

  1. 以下有关哈夫曼树的说法中,错误的是(C)。

A. 哈夫曼树又被称为最优二叉树
B. 哈夫曼树是一种带权路径长度最短的树
C. 具有n个叶子结点的权值为 $W_1, W_2, …, W_n$ 的最优二叉树是唯一的
D. 哈夫曼树可以用来进行通信电文的编码和解码

13 B树

  B树,有时又写为B-树或B_树(其中的“-”或者“_”只是连字符,并不读作“B减树”)。一颗m阶的B树是一颗平衡的多路搜索树,它或者是空树,或者是满足下列性质的树。

  1. 树中每个结点至多有m棵子树。
  2. 若根结点不是叶子结点,则至少有两棵子树。
  3. 除根之外的所有非终端结点至少有[m/2](向上取整)棵子树。
  4. 所有的非终端结点中包含下列信息数据:

   $(n, A_0, K_1, A_1, K_2, A_2, …, K_n, A_n)$ ,其中: $K_i (i = 1, 2, …, n)$ 为关键字,且 $K_i < K_{i + 1}$ (i = 1, …, n - 1)。
   $A_i (i = 0, …, n)$ 为指向子树根结点的指针,且指针 $A_{i -1}$ 所指子树中所有结点的关键字均小于 $K_i(i = 1, …, n)$ , $A_n$ 所指子树中所有结点的关键字均大于 $K_n$ , $n ([m / 2] - 1 \leq n \leq m - 1)$ 为关键字的个数(或n + 1为子树个数)。其中[m / 2]表示向上取整。

  1. 所有的叶子结点都出现在同一层次上,并且不带信息(可以看作是外部结点或查找失败的结点,实际上这些结点不存在,指向这些结点的指针为空)。

BTree.png

14 B+树

  是B-树的一种变型,一个m阶的B+树具有如下几个特征。

  • 每个叶子结点中含有n个关键字和n个指向记录的指针,并且所有叶子节点彼此相链接构成一个有序链表,其头指针指向含最小关键字的节点。
  • 每个非叶子节点中的关键字 $K_i$ 即为其相应指针 $A_i$ 所指子树中关键字的最大值。
  • 所有叶子节点都处在统一层次上,每个叶子节点中关键字的个数均介于[m / 2](向上取整)和m之间。

B+Tree.png

15 散列表

  散列表构造的基本思想是:已知关键字集合U,最大关键字为m,设计一个函数Hash,它以关键字为自变量,关键字的存储地址为因变量,将关键字映射到一个有限的、地址连续的区间T[0 .. n - 1](n << m)中,这个区间就称为散列表,散列查找中使用的转换函数称为散列函数。

  例:假设有一个大小为7的表,现在要将(13, 18, 19s, 50, 20, 27)散列到表中。

  • 选择散列函数,例如使用hash(x) = x % 7作为散列函数。
  • 计算数据散列值,并放到合适的位置。
哈希地址 0 1 2 3 4 5 6
关键码 50 18 19 13

  地址重复时出现冲突,即散列冲突。

15.1 解决散列冲突

  • 链地址法(拉链法)
  • 开放地址法

   $H_i = (Hash(key) + d_i) % m$ i = 1, 2, …, k $(k \leq m - 1)$
  其中Hash(key)为哈希函数,m为哈希表的表长,di为增量序列。常见的增量序列有三种。

  • di = 1, 2, 3, …, m - 1,称为线性他侧再散列。
  • di = $1^2, {-1}^2, 2^2, {-2}^2, 3^3, …, ±k^2$ ,称为二次探测再散列。
  • di = 伪随机数列,称为随机探测再散列,如:di = Random(key)。

15.2 例题

  1. 用哈希表存储元素时,需要进行冲突(碰撞)处理,冲突是指(B)。

A. 关键字被依次映射到地址编号连续的存储位置
B. 关键字不同的元素被映射到相同的存储位置
C. 关键字相同的元素被映射到不同的存储位置
D. 关键字被映射到哈希表之外的位置

16 总结

  考查形式主要是概念区分以及部分计算题型,主要出现在上午的选择题当中。

  • 树的遍历
  • 图的遍历
  • 典型的时间复杂度

  需要记忆。

  • 数据结构与算法的概念
  • 线性表(顺序表、链表、栈、队列)
  • 数组与矩阵
  • 树与二叉树
  • 查找(二分查找、哈希)

第九章——数据结构与算法

前言:
   计算机第九章节主要知识点。

1 知识点介绍

  • 数据结构与算法概念
  • 线性表
  • 数组与矩阵
  • 树与二叉树
  • 查找

2 数据结构定义

  • 数据结构
    • 数据逻辑结构:指数据元素之间的管理。
      • 线性结构:一对一关系
      • 非线性结构:一对多,多对多关系
    • 数据物理结构:数据在物理设备上具体如何存储。

3 算法概念

  算法的5个重要特征

  • 又穷性:执行有穷步之后结束,且每一步都可在有穷时间内完成。
  • 确定性:算法中每一条指令都必须由确切的含义,不能含糊不清。
  • 输入(>= 0)
  • 输出(>= 1)
  • 有效性(可行性):算法的每个步骤都能有效执行并能在执行有限此后得到确定的结果,例如a = 0,b / a就无效。

4 伪代码

  伪代码是一种算法描述语言,介于自然语言与编程语言之间,不用拘泥于具体的实现。

Pseudocode.png

5 线性表

5.1 线性表的概念

  常见线性表的两种存储结构。

  • 顺序存储结构(如:顺序表)
  • 链式存储结构(如:链表)

  逻辑上连续,物理上不一定连续。

  • 顺序表:随机存取。查询和修改容易,元素插入和删除麻烦,需要移动元素。
  • 链表
    • 单链表
    • 循环链表
    • 双向链表

LinearList.png

5.2 链表基本操作

  • 单链表删除结点
  • 单链表插入结点
  • 双向链表删除结点
  • 双向链表插入结点

LinkedList.png

5.3 例题

  1. 以下关于单链表存储结构特征的叙述中,不正确的是(D)。

A. 表中结点所占用存储空间的地址不必是连续的
B. 在表中任意位置进行插入和删除操作都不用移动元素
C. 所需空间与结点个数成正比
D. 可随机访问表中的任一结点

5.4 队列和栈

  元素按照a、b、c的次序进入栈,请尝试写出其所有可能的出栈序。

QueueAndStack.png

5.5 例题

  1. 令序列X、Y、Z的每个元素都按顺序进栈,且每个元素进栈和出栈仅一次,则不可能得到的出栈序列是(C)。

A. XYZ
B. XZY
C. ZXY
D. YZX

6 广义表

  广义表示n个表元素组成的有限序列,是线性表的推广,通常用递归的形式进行定义,记作: $LS = (a_0, a_1, …, a_n)$

注:其中LS是表名, $a_i$ 是表元素,它可以是表(称做子表),也可以是数据元素(称为原子)。其中n是广义表的长度(也就是最外层包含的元素个数),n = 0的广义表为空表;而递归定义的重数就是广义表的深度,直观地说,就是定义中所含括号的重数(原子的深度为0,空表的深度为1)。

例,有广义表LS1 = (a, (b, c), (d, e)),其长度为?深度为?
答案:长度为3,深度为2。

7 串

  串是仅由字符构成的有限序列,是取值范围受限的线性表,一般记为 S = ‘a1a2…an’,其中S是串名,单引号括起来的字符序列是串值。

8 数组

  二维数组分按行存储和按列存储。c/c++的多维数组是按行、连续存储逇。FORTRAN语言,Matlab中,数组按列优先顺序存储。

数组类型 存储地址计算
一维数组a[n] a[i]的存储地址为:a + i * len
二维数组a[m][n] a[i][j]的存储地址(按行存储)为:a + (i * n + j) * len
a[i][j]存储地址(按列存储)为:a + (j * m + i) * len

8.1 例题

  1. 数组a[1 … n, 1 … m](n > 1, m > 1)中的元素以行为主序存放,每个元素占用1个存储伟,则数组元素a[i, j] $(1 \leq i \leq n, 1 \leq j \leq m)$ 相对于数组空间首地址的偏移量为(A)

A. (i - 1) * m + j - 1
B. (i - 1) * n + j - 1
C. (j - 1) * m + i - 1
D. (j - 1) * n + i - 1

  1. 若二维数组arr[1 … M, 1 … N]的首地址为base,数组元素按列存储且每个元素占用K个存储单元,则元素arr[i, j]在该数组空间的地址为()。

A. base + ((i - 1) * M + j - 1) * K
B. base + ((i - 1) * N + j - 1) * K
C. base + ((j - 1) * M + i - 1) * K
D. base + ((j - 1) * N + i - 1) * K

9 树与二叉树

  • 结点的度
  • 树的高度
  • 叶子结点
  • 分支结点
  • 内部结点
  • 父结点
  • 子结点
  • 兄弟结点
  • 层次

BinaryTree.png

BinaryTree_1.png

  二叉树的重要特征。

  • 在二叉树的第i层上最多有 $2^{i - 1}$ 个结点 $(i \geq 1)$ ;
  • 深度为k的二叉树最多有 $2^k - 1$ 个结点 $(k \geq 1)$ ;
  • 对任何一颗二叉树,如果其叶子结点数为 $n_0$ ,度为2的结点数为 $n_2$ ,则 $n_0 = n_2 + 1$ 。
  • 如果对一颗有n个结点的完全二叉树的结点按层序编号(从第1层到 $log_2n + 1$ 层,每层从左到右),则对任一结点i $(i \geq i \geq n)$ ,有
    • 如果i = 1,则结点i无父结点,是二叉树的根;如果i > 1,则父结点是i / 2;
    • 如果2i > n,则结点i为叶子结点,无左子结点;否则,其左子结点是结点2i;
    • 如果2i + 1 > n,则结点i无右叶子结点,否则,其右子结点是结点2i + 1;

9.1 二叉树遍历

  • 前序遍历(根左右)
  • 中序遍历(左根右)
  • 后序遍历(左右根)
  • 层序遍历

  前序遍历:12457836,中序遍历:42785136,后序遍历:48752631,层次遍历:12345678。

TraversalOfBinaryTree.png

10 堆

  堆是计算机科学中的一类特殊的数据结构的统称。堆通常是一个可以被看做一颗完全二叉树的数组对象。
  若n个元素的序列 ${a_1, a_2 … a_n}$ 满足

Formula.png

  则分别称该序列 ${a_1, a_2, … a_n}$ 为小根堆和大根堆。
  从堆的定义可以看出,对实质是满足如下性质的完全二叉树:

  • 二叉树中任一非叶子结点均小于(大于)它的孩子结点。
  • 堆总是一颗完全二叉树。

  例如:下面序列为堆,对应的完全二叉树分别为。

1
2
98 77 35 62 55 14 35 48
14 48 35 62 55 98 35 77

Heap.png

10.1 例题

  1. 对于n个元素的关键字序列 ${k_1, k_2, … k_n}$ ,当且仅当满足关系 $k_j \leq k_{2i}$ 且 $k_i \leq k_{2i + 1}$ {i = 1.2…[n/2]}时称其为小根堆(小顶堆)。以下序列中,(D)不是小根堆。

A. 16, 25, 40, 55, 30, 50, 45
B. 16, 40, 25, 50, 45, 30, 55
C. 16, 25, 39, 41, 45, 43, 50
D. 16, 40, 25, 53, 39, 55, 45

11 图

11.1 图的存储

11.1.1 邻接矩阵表示法

  邻接矩阵表示法用一个n阶方阵R来存放图中各结点的关联信息,其矩阵元素 $R_{ij}$ 定义为。
  为无向图。表示稀疏矩阵时空间浪费大。

FigureOfTheStorage.png

11.1.2 邻接链条表示法

  首先把每个顶点的邻接顶点用链表表示出来,然后用一个一维数组来顺序存储上面每个链表的头指针。

ListFigure.png

11.2 例题

  1. 某有向图G的邻接表如下图所示,可看出该图中存在弧 $<v_2, V3>$ 而不存在从顶点 $V_1$ 出发的弧。以下关于图G的叙述中,错误的是()。

A. G中存在回路
B. G中每个顶点的入度为1
C. G的邻接矩阵是对称的
D. 不存在弧 $V_3, V_1>

ex1.png

11.3 图的遍历

GraphTraversal.png

12 查找算法

  • 五大查找
    • 顺序表查找
      • 顺序查找
      • 二分查找
      • 索引顺序查找
    • 树表查找
      • 二叉排序树
    • 散列表查找
      • 哈希查找

12.1 顺序查找

  顺序查找的过程:将待查找的关键字可key的元素从头到尾与表中元素进行比较,如果中间存在关键字为key的元素,则返回成功,否则返回失败。顺序查找主要针对少量的、无规则的数据。

1
4 7 10 18 30 2 46 24 15

12.2 二分查找

  二分法查找的基本过程是:(设R[low, …, high]是当前的查找区)

  • 确定该区间的中间位置:mid = [(low + high) / 2],向下取整。
  • 将待查的k值与R[mid].key比较,若相等,则查找成功并返回此位置,否则需确定新的查找区间,继续二分查找,具体方法如下。
    • 若R[mid].key > k,则由表的有序性可知R[mid, …, n].key均大于k,因此若表中存在关键字等于k的结点,则该结点必定是在位置mid左边的子表R[low, …, mid -1]中。因此,新的查找区间是左子表R[low, …, high],其中high = mid - 1.
    • 若R[mid].key < k,则要查找的k必在mid的右子表R[mid + 1, …, high]中,即新的查找区间是右子表R[low, …, high],其中low = mid + 1。
    • 若R[mid].key = k,则查找成功,算法结束。
  • 下次查找是针对新的查找区间进行,重复步骤(1)和(2)。
  • 在查找过程中,low逐步增加,而high逐步减少。如果high < low,则查找失败,算法结束。

12.3 二叉查找树(排序)

  二叉查找树的定义:二叉排序树或者是一颗空树,或者是具有如下特性的二叉树。

  • 若它的左子树不空,则左子树上所有节点的值均小于根节点的值。
  • 若它的有子树不空,则右子树上所有节点的值均大于根节点的值。
  • 它的左、右子树也都分别是二叉排序树。

  对二叉查找树进行中序遍历,即可得到有序的序列。

BinarySortTree.png

  查找过程:二叉查找(排序)树是先对待查找的数据进行生成树,确保数的左分支值小于右分支的值,然后再去和每个结点的父结点比较大小,查找最合适的范围。这个算法的查找效率很高,但是如果使用这种查找方法要首先创建数。
  具体步骤为。

  • 若查找的关键字等于根节点的关键字,查找成功。
  • 若查找的关键字小于根节点的关键字,递归查找左子树。
  • 若查找的关键字大于根节点的关键字,递归查找右子树。
  • 若子树为空,则查找不成功。

12.4 二叉平衡树

  定义:又称AVL树。它或者是一颗空树,或者是具有下列性质的二叉树:它的左子树或右子树都是平衡二叉树,且左子树和右子树的深度之差的绝对值不超过1。

  平衡因子。
  二叉树上任一结点的左子树深度减去右子树深度的差值,称为此结点的平衡因子。

AVL.png

12.5 例题

  1. 关于二叉排序树的说法,错误的是(C)。

A. 对于二叉排序树进行中序遍历,必定得到结点关键字的有序序列
B. 依据关键字无序的序列建立二叉排序,也可能构造出单支树
C. 若构造二叉排序树时进行平衡化处理,则根节点的左子树结点数与右子树结点数的差值一定不超过1
D. 若构造二叉排序树时进行平衡化处理,则根结点的左子树高度与右子树高度的差值一定不超过1

12.5 哈夫曼树

  定义:给定N个权值作为N个叶子节点,构造一颗二叉树,若该树的带权路径长度达到最小,称这样的二叉树为最优二叉树,也称为哈夫曼树。哈夫曼树是带权路径长度最短的数,权值较大的结点离根较近。
  一般可以按下面步骤构建。

  • 将所有左、右子树都为空的作为根节点。
  • 在森林中选取两棵根节点的权值最小的数作为一棵新树的左、右子树,且置新树的附加根节点的权值为其左、右子树上根结点的权值之和。
  • 从森林中删除这两棵树,同时把新树加入到森林中。
  • 重复2、3步骤,直到森林中只有一棵树为止,此树便是哈夫曼树。

HuffmanTree.png

HuffmanTree_.png

  应用场景:对字符集中的字符进行编码和译码。

12.6 例题

  1. 以下有关哈夫曼树的说法中,错误的是(C)。

A. 哈夫曼树又被称为最优二叉树
B. 哈夫曼树是一种带权路径长度最短的树
C. 具有n个叶子结点的权值为 $W_1, W_2, …, W_n$ 的最优二叉树是唯一的
D. 哈夫曼树可以用来进行通信电文的编码和解码

13 B树

  B树,有时又写为B-树或B_树(其中的“-”或者“_”只是连字符,并不读作“B减树”)。一颗m阶的B树是一颗平衡的多路搜索树,它或者是空树,或者是满足下列性质的树。

  1. 树中每个结点至多有m棵子树。
  2. 若根结点不是叶子结点,则至少有两棵子树。
  3. 除根之外的所有非终端结点至少有[m/2](向上取整)棵子树。
  4. 所有的非终端结点中包含下列信息数据:

   $(n, A_0, K_1, A_1, K_2, A_2, …, K_n, A_n)$ ,其中: $K_i (i = 1, 2, …, n)$ 为关键字,且 $K_i < K_{i + 1}$ (i = 1, …, n - 1)。
   $A_i (i = 0, …, n)$ 为指向子树根结点的指针,且指针 $A_{i -1}$ 所指子树中所有结点的关键字均小于 $K_i(i = 1, …, n)$ , $A_n$ 所指子树中所有结点的关键字均大于 $K_n$ , $n ([m / 2] - 1 \leq n \leq m - 1)$ 为关键字的个数(或n + 1为子树个数)。其中[m / 2]表示向上取整。

  1. 所有的叶子结点都出现在同一层次上,并且不带信息(可以看作是外部结点或查找失败的结点,实际上这些结点不存在,指向这些结点的指针为空)。

BTree.png

14 B+树

  是B-树的一种变型,一个m阶的B+树具有如下几个特征。

  • 每个叶子结点中含有n个关键字和n个指向记录的指针,并且所有叶子节点彼此相链接构成一个有序链表,其头指针指向含最小关键字的节点。
  • 每个非叶子节点中的关键字 $K_i$ 即为其相应指针 $A_i$ 所指子树中关键字的最大值。
  • 所有叶子节点都处在统一层次上,每个叶子节点中关键字的个数均介于[m / 2](向上取整)和m之间。

B+Tree.png

15 散列表

  散列表构造的基本思想是:已知关键字集合U,最大关键字为m,设计一个函数Hash,它以关键字为自变量,关键字的存储地址为因变量,将关键字映射到一个有限的、地址连续的区间T[0 .. n - 1](n << m)中,这个区间就称为散列表,散列查找中使用的转换函数称为散列函数。

  例:假设有一个大小为7的表,现在要将(13, 18, 19s, 50, 20, 27)散列到表中。

  • 选择散列函数,例如使用hash(x) = x % 7作为散列函数。
  • 计算数据散列值,并放到合适的位置。
哈希地址 0 1 2 3 4 5 6
关键码 50 18 19 13

  地址重复时出现冲突,即散列冲突。

15.1 解决散列冲突

  • 链地址法(拉链法)
  • 开放地址法

   $H_i = (Hash(key) + d_i) % m$ i = 1, 2, …, k $(k \leq m - 1)$
  其中Hash(key)为哈希函数,m为哈希表的表长,di为增量序列。常见的增量序列有三种。

  • di = 1, 2, 3, …, m - 1,称为线性他侧再散列。
  • di = $1^2, {-1}^2, 2^2, {-2}^2, 3^3, …, ±k^2$ ,称为二次探测再散列。
  • di = 伪随机数列,称为随机探测再散列,如:di = Random(key)。

15.2 例题

  1. 用哈希表存储元素时,需要进行冲突(碰撞)处理,冲突是指(B)。

A. 关键字被依次映射到地址编号连续的存储位置
B. 关键字不同的元素被映射到相同的存储位置
C. 关键字相同的元素被映射到不同的存储位置
D. 关键字被映射到哈希表之外的位置

16 总结

  考查形式主要是概念区分以及部分计算题型,主要出现在上午的选择题当中。

  • 树的遍历
  • 图的遍历
  • 典型的时间复杂度

  需要记忆。

  • 数据结构与算法的概念
  • 线性表(顺序表、链表、栈、队列)
  • 数组与矩阵
  • 树与二叉树
  • 查找(二分查找、哈希)

  二叉树的重要特征。

  • 在二叉树的第i层上最多有 $2^{i - 1}$ 个结点 $(i \geq 1)$ ;
  • 深度为k的二叉树最多有 $2^k - 1$ 个结点 $(k \geq 1)$ ;
  • 对任何一颗二叉树,如果其叶子结点数为 $n_0$ ,度为2的结点数为 $n_2$ ,则 $n_0 = n_2 + 1$ 。
  • 如果对一颗有n个结点的完全二叉树的结点按层序编号(从第1层到 $log_2n + 1$ 层,每层从左到右),则对任一结点i $(i \geq i \geq n)$ ,有
    • 如果i = 1,则结点i无父结点,是二叉树的根;如果i > 1,则父结点是i / 2;
    • 如果2i > n,则结点i为叶子结点,无左子结点;否则,其左子结点是结点2i;
    • 如果2i + 1 > n,则结点i无右叶子结点,否则,其右子结点是结点2i + 1;

9.1 二叉树遍历

  • 前序遍历(根左右)
  • 中序遍历(左根右)
  • 后序遍历(左右根)
  • 层序遍历

  前序遍历:12457836,中序遍历:42785136,后序遍历:48752631,层次遍历:12345678。

第九章——数据结构与算法

前言:
   计算机第九章节主要知识点。

1 知识点介绍

  • 数据结构与算法概念
  • 线性表
  • 数组与矩阵
  • 树与二叉树
  • 查找

2 数据结构定义

  • 数据结构
    • 数据逻辑结构:指数据元素之间的管理。
      • 线性结构:一对一关系
      • 非线性结构:一对多,多对多关系
    • 数据物理结构:数据在物理设备上具体如何存储。

3 算法概念

  算法的5个重要特征

  • 又穷性:执行有穷步之后结束,且每一步都可在有穷时间内完成。
  • 确定性:算法中每一条指令都必须由确切的含义,不能含糊不清。
  • 输入(>= 0)
  • 输出(>= 1)
  • 有效性(可行性):算法的每个步骤都能有效执行并能在执行有限此后得到确定的结果,例如a = 0,b / a就无效。

4 伪代码

  伪代码是一种算法描述语言,介于自然语言与编程语言之间,不用拘泥于具体的实现。

Pseudocode.png

5 线性表

5.1 线性表的概念

  常见线性表的两种存储结构。

  • 顺序存储结构(如:顺序表)
  • 链式存储结构(如:链表)

  逻辑上连续,物理上不一定连续。

  • 顺序表:随机存取。查询和修改容易,元素插入和删除麻烦,需要移动元素。
  • 链表
    • 单链表
    • 循环链表
    • 双向链表

LinearList.png

5.2 链表基本操作

  • 单链表删除结点
  • 单链表插入结点
  • 双向链表删除结点
  • 双向链表插入结点

LinkedList.png

5.3 例题

  1. 以下关于单链表存储结构特征的叙述中,不正确的是(D)。

A. 表中结点所占用存储空间的地址不必是连续的
B. 在表中任意位置进行插入和删除操作都不用移动元素
C. 所需空间与结点个数成正比
D. 可随机访问表中的任一结点

5.4 队列和栈

  元素按照a、b、c的次序进入栈,请尝试写出其所有可能的出栈序。

QueueAndStack.png

5.5 例题

  1. 令序列X、Y、Z的每个元素都按顺序进栈,且每个元素进栈和出栈仅一次,则不可能得到的出栈序列是(C)。

A. XYZ
B. XZY
C. ZXY
D. YZX

6 广义表

  广义表示n个表元素组成的有限序列,是线性表的推广,通常用递归的形式进行定义,记作: $LS = (a_0, a_1, …, a_n)$

注:其中LS是表名, $a_i$ 是表元素,它可以是表(称做子表),也可以是数据元素(称为原子)。其中n是广义表的长度(也就是最外层包含的元素个数),n = 0的广义表为空表;而递归定义的重数就是广义表的深度,直观地说,就是定义中所含括号的重数(原子的深度为0,空表的深度为1)。

例,有广义表LS1 = (a, (b, c), (d, e)),其长度为?深度为?
答案:长度为3,深度为2。

7 串

  串是仅由字符构成的有限序列,是取值范围受限的线性表,一般记为 S = ‘a1a2…an’,其中S是串名,单引号括起来的字符序列是串值。

8 数组

  二维数组分按行存储和按列存储。c/c++的多维数组是按行、连续存储逇。FORTRAN语言,Matlab中,数组按列优先顺序存储。

数组类型 存储地址计算
一维数组a[n] a[i]的存储地址为:a + i * len
二维数组a[m][n] a[i][j]的存储地址(按行存储)为:a + (i * n + j) * len
a[i][j]存储地址(按列存储)为:a + (j * m + i) * len

8.1 例题

  1. 数组a[1 … n, 1 … m](n > 1, m > 1)中的元素以行为主序存放,每个元素占用1个存储伟,则数组元素a[i, j] $(1 \leq i \leq n, 1 \leq j \leq m)$ 相对于数组空间首地址的偏移量为(A)

A. (i - 1) * m + j - 1
B. (i - 1) * n + j - 1
C. (j - 1) * m + i - 1
D. (j - 1) * n + i - 1

  1. 若二维数组arr[1 … M, 1 … N]的首地址为base,数组元素按列存储且每个元素占用K个存储单元,则元素arr[i, j]在该数组空间的地址为()。

A. base + ((i - 1) * M + j - 1) * K
B. base + ((i - 1) * N + j - 1) * K
C. base + ((j - 1) * M + i - 1) * K
D. base + ((j - 1) * N + i - 1) * K

9 树与二叉树

  • 结点的度
  • 树的高度
  • 叶子结点
  • 分支结点
  • 内部结点
  • 父结点
  • 子结点
  • 兄弟结点
  • 层次

BinaryTree.png

BinaryTree_1.png

  二叉树的重要特征。

  • 在二叉树的第i层上最多有 $2^{i - 1}$ 个结点 $(i \geq 1)$ ;
  • 深度为k的二叉树最多有 $2^k - 1$ 个结点 $(k \geq 1)$ ;
  • 对任何一颗二叉树,如果其叶子结点数为 $n_0$ ,度为2的结点数为 $n_2$ ,则 $n_0 = n_2 + 1$ 。
  • 如果对一颗有n个结点的完全二叉树的结点按层序编号(从第1层到 $log_2n + 1$ 层,每层从左到右),则对任一结点i $(i \geq i \geq n)$ ,有
    • 如果i = 1,则结点i无父结点,是二叉树的根;如果i > 1,则父结点是i / 2;
    • 如果2i > n,则结点i为叶子结点,无左子结点;否则,其左子结点是结点2i;
    • 如果2i + 1 > n,则结点i无右叶子结点,否则,其右子结点是结点2i + 1;

9.1 二叉树遍历

  • 前序遍历(根左右)
  • 中序遍历(左根右)
  • 后序遍历(左右根)
  • 层序遍历

  前序遍历:12457836,中序遍历:42785136,后序遍历:48752631,层次遍历:12345678。

TraversalOfBinaryTree.png

10 堆

  堆是计算机科学中的一类特殊的数据结构的统称。堆通常是一个可以被看做一颗完全二叉树的数组对象。
  若n个元素的序列 ${a_1, a_2 … a_n}$ 满足

Formula.png

  则分别称该序列 ${a_1, a_2, … a_n}$ 为小根堆和大根堆。
  从堆的定义可以看出,对实质是满足如下性质的完全二叉树:

  • 二叉树中任一非叶子结点均小于(大于)它的孩子结点。
  • 堆总是一颗完全二叉树。

  例如:下面序列为堆,对应的完全二叉树分别为。

1
2
98 77 35 62 55 14 35 48
14 48 35 62 55 98 35 77

Heap.png

10.1 例题

  1. 对于n个元素的关键字序列 ${k_1, k_2, … k_n}$ ,当且仅当满足关系 $k_j \leq k_{2i}$ 且 $k_i \leq k_{2i + 1}$ {i = 1.2…[n/2]}时称其为小根堆(小顶堆)。以下序列中,(D)不是小根堆。

A. 16, 25, 40, 55, 30, 50, 45
B. 16, 40, 25, 50, 45, 30, 55
C. 16, 25, 39, 41, 45, 43, 50
D. 16, 40, 25, 53, 39, 55, 45

11 图

11.1 图的存储

11.1.1 邻接矩阵表示法

  邻接矩阵表示法用一个n阶方阵R来存放图中各结点的关联信息,其矩阵元素 $R_{ij}$ 定义为。
  为无向图。表示稀疏矩阵时空间浪费大。

FigureOfTheStorage.png

11.1.2 邻接链条表示法

  首先把每个顶点的邻接顶点用链表表示出来,然后用一个一维数组来顺序存储上面每个链表的头指针。

ListFigure.png

11.2 例题

  1. 某有向图G的邻接表如下图所示,可看出该图中存在弧 $<v_2, V3>$ 而不存在从顶点 $V_1$ 出发的弧。以下关于图G的叙述中,错误的是()。

A. G中存在回路
B. G中每个顶点的入度为1
C. G的邻接矩阵是对称的
D. 不存在弧 $V_3, V_1>

ex1.png

11.3 图的遍历

GraphTraversal.png

12 查找算法

  • 五大查找
    • 顺序表查找
      • 顺序查找
      • 二分查找
      • 索引顺序查找
    • 树表查找
      • 二叉排序树
    • 散列表查找
      • 哈希查找

12.1 顺序查找

  顺序查找的过程:将待查找的关键字可key的元素从头到尾与表中元素进行比较,如果中间存在关键字为key的元素,则返回成功,否则返回失败。顺序查找主要针对少量的、无规则的数据。

1
4 7 10 18 30 2 46 24 15

12.2 二分查找

  二分法查找的基本过程是:(设R[low, …, high]是当前的查找区)

  • 确定该区间的中间位置:mid = [(low + high) / 2],向下取整。
  • 将待查的k值与R[mid].key比较,若相等,则查找成功并返回此位置,否则需确定新的查找区间,继续二分查找,具体方法如下。
    • 若R[mid].key > k,则由表的有序性可知R[mid, …, n].key均大于k,因此若表中存在关键字等于k的结点,则该结点必定是在位置mid左边的子表R[low, …, mid -1]中。因此,新的查找区间是左子表R[low, …, high],其中high = mid - 1.
    • 若R[mid].key < k,则要查找的k必在mid的右子表R[mid + 1, …, high]中,即新的查找区间是右子表R[low, …, high],其中low = mid + 1。
    • 若R[mid].key = k,则查找成功,算法结束。
  • 下次查找是针对新的查找区间进行,重复步骤(1)和(2)。
  • 在查找过程中,low逐步增加,而high逐步减少。如果high < low,则查找失败,算法结束。

12.3 二叉查找树(排序)

  二叉查找树的定义:二叉排序树或者是一颗空树,或者是具有如下特性的二叉树。

  • 若它的左子树不空,则左子树上所有节点的值均小于根节点的值。
  • 若它的有子树不空,则右子树上所有节点的值均大于根节点的值。
  • 它的左、右子树也都分别是二叉排序树。

  对二叉查找树进行中序遍历,即可得到有序的序列。

BinarySortTree.png

  查找过程:二叉查找(排序)树是先对待查找的数据进行生成树,确保数的左分支值小于右分支的值,然后再去和每个结点的父结点比较大小,查找最合适的范围。这个算法的查找效率很高,但是如果使用这种查找方法要首先创建数。
  具体步骤为。

  • 若查找的关键字等于根节点的关键字,查找成功。
  • 若查找的关键字小于根节点的关键字,递归查找左子树。
  • 若查找的关键字大于根节点的关键字,递归查找右子树。
  • 若子树为空,则查找不成功。

12.4 二叉平衡树

  定义:又称AVL树。它或者是一颗空树,或者是具有下列性质的二叉树:它的左子树或右子树都是平衡二叉树,且左子树和右子树的深度之差的绝对值不超过1。

  平衡因子。
  二叉树上任一结点的左子树深度减去右子树深度的差值,称为此结点的平衡因子。

AVL.png

12.5 例题

  1. 关于二叉排序树的说法,错误的是(C)。

A. 对于二叉排序树进行中序遍历,必定得到结点关键字的有序序列
B. 依据关键字无序的序列建立二叉排序,也可能构造出单支树
C. 若构造二叉排序树时进行平衡化处理,则根节点的左子树结点数与右子树结点数的差值一定不超过1
D. 若构造二叉排序树时进行平衡化处理,则根结点的左子树高度与右子树高度的差值一定不超过1

12.5 哈夫曼树

  定义:给定N个权值作为N个叶子节点,构造一颗二叉树,若该树的带权路径长度达到最小,称这样的二叉树为最优二叉树,也称为哈夫曼树。哈夫曼树是带权路径长度最短的数,权值较大的结点离根较近。
  一般可以按下面步骤构建。

  • 将所有左、右子树都为空的作为根节点。
  • 在森林中选取两棵根节点的权值最小的数作为一棵新树的左、右子树,且置新树的附加根节点的权值为其左、右子树上根结点的权值之和。
  • 从森林中删除这两棵树,同时把新树加入到森林中。
  • 重复2、3步骤,直到森林中只有一棵树为止,此树便是哈夫曼树。

HuffmanTree.png

HuffmanTree_.png

  应用场景:对字符集中的字符进行编码和译码。

12.6 例题

  1. 以下有关哈夫曼树的说法中,错误的是(C)。

A. 哈夫曼树又被称为最优二叉树
B. 哈夫曼树是一种带权路径长度最短的树
C. 具有n个叶子结点的权值为 $W_1, W_2, …, W_n$ 的最优二叉树是唯一的
D. 哈夫曼树可以用来进行通信电文的编码和解码

13 B树

  B树,有时又写为B-树或B_树(其中的“-”或者“_”只是连字符,并不读作“B减树”)。一颗m阶的B树是一颗平衡的多路搜索树,它或者是空树,或者是满足下列性质的树。

  1. 树中每个结点至多有m棵子树。
  2. 若根结点不是叶子结点,则至少有两棵子树。
  3. 除根之外的所有非终端结点至少有[m/2](向上取整)棵子树。
  4. 所有的非终端结点中包含下列信息数据:

   $(n, A_0, K_1, A_1, K_2, A_2, …, K_n, A_n)$ ,其中: $K_i (i = 1, 2, …, n)$ 为关键字,且 $K_i < K_{i + 1}$ (i = 1, …, n - 1)。
   $A_i (i = 0, …, n)$ 为指向子树根结点的指针,且指针 $A_{i -1}$ 所指子树中所有结点的关键字均小于 $K_i(i = 1, …, n)$ , $A_n$ 所指子树中所有结点的关键字均大于 $K_n$ , $n ([m / 2] - 1 \leq n \leq m - 1)$ 为关键字的个数(或n + 1为子树个数)。其中[m / 2]表示向上取整。

  1. 所有的叶子结点都出现在同一层次上,并且不带信息(可以看作是外部结点或查找失败的结点,实际上这些结点不存在,指向这些结点的指针为空)。

BTree.png

14 B+树

  是B-树的一种变型,一个m阶的B+树具有如下几个特征。

  • 每个叶子结点中含有n个关键字和n个指向记录的指针,并且所有叶子节点彼此相链接构成一个有序链表,其头指针指向含最小关键字的节点。
  • 每个非叶子节点中的关键字 $K_i$ 即为其相应指针 $A_i$ 所指子树中关键字的最大值。
  • 所有叶子节点都处在统一层次上,每个叶子节点中关键字的个数均介于[m / 2](向上取整)和m之间。

B+Tree.png

15 散列表

  散列表构造的基本思想是:已知关键字集合U,最大关键字为m,设计一个函数Hash,它以关键字为自变量,关键字的存储地址为因变量,将关键字映射到一个有限的、地址连续的区间T[0 .. n - 1](n << m)中,这个区间就称为散列表,散列查找中使用的转换函数称为散列函数。

  例:假设有一个大小为7的表,现在要将(13, 18, 19s, 50, 20, 27)散列到表中。

  • 选择散列函数,例如使用hash(x) = x % 7作为散列函数。
  • 计算数据散列值,并放到合适的位置。
哈希地址 0 1 2 3 4 5 6
关键码 50 18 19 13

  地址重复时出现冲突,即散列冲突。

15.1 解决散列冲突

  • 链地址法(拉链法)
  • 开放地址法

   $H_i = (Hash(key) + d_i) % m$ i = 1, 2, …, k $(k \leq m - 1)$
  其中Hash(key)为哈希函数,m为哈希表的表长,di为增量序列。常见的增量序列有三种。

  • di = 1, 2, 3, …, m - 1,称为线性他侧再散列。
  • di = $1^2, {-1}^2, 2^2, {-2}^2, 3^3, …, ±k^2$ ,称为二次探测再散列。
  • di = 伪随机数列,称为随机探测再散列,如:di = Random(key)。

15.2 例题

  1. 用哈希表存储元素时,需要进行冲突(碰撞)处理,冲突是指(B)。

A. 关键字被依次映射到地址编号连续的存储位置
B. 关键字不同的元素被映射到相同的存储位置
C. 关键字相同的元素被映射到不同的存储位置
D. 关键字被映射到哈希表之外的位置

16 总结

  考查形式主要是概念区分以及部分计算题型,主要出现在上午的选择题当中。

  • 树的遍历
  • 图的遍历
  • 典型的时间复杂度

  需要记忆。

  • 数据结构与算法的概念
  • 线性表(顺序表、链表、栈、队列)
  • 数组与矩阵
  • 树与二叉树
  • 查找(二分查找、哈希)

10 堆

  堆是计算机科学中的一类特殊的数据结构的统称。堆通常是一个可以被看做一颗完全二叉树的数组对象。
  若n个元素的序列 ${a_1, a_2 … a_n}$ 满足

第九章——数据结构与算法

前言:
   计算机第九章节主要知识点。

1 知识点介绍

  • 数据结构与算法概念
  • 线性表
  • 数组与矩阵
  • 树与二叉树
  • 查找

2 数据结构定义

  • 数据结构
    • 数据逻辑结构:指数据元素之间的管理。
      • 线性结构:一对一关系
      • 非线性结构:一对多,多对多关系
    • 数据物理结构:数据在物理设备上具体如何存储。

3 算法概念

  算法的5个重要特征

  • 又穷性:执行有穷步之后结束,且每一步都可在有穷时间内完成。
  • 确定性:算法中每一条指令都必须由确切的含义,不能含糊不清。
  • 输入(>= 0)
  • 输出(>= 1)
  • 有效性(可行性):算法的每个步骤都能有效执行并能在执行有限此后得到确定的结果,例如a = 0,b / a就无效。

4 伪代码

  伪代码是一种算法描述语言,介于自然语言与编程语言之间,不用拘泥于具体的实现。

Pseudocode.png

5 线性表

5.1 线性表的概念

  常见线性表的两种存储结构。

  • 顺序存储结构(如:顺序表)
  • 链式存储结构(如:链表)

  逻辑上连续,物理上不一定连续。

  • 顺序表:随机存取。查询和修改容易,元素插入和删除麻烦,需要移动元素。
  • 链表
    • 单链表
    • 循环链表
    • 双向链表

LinearList.png

5.2 链表基本操作

  • 单链表删除结点
  • 单链表插入结点
  • 双向链表删除结点
  • 双向链表插入结点

LinkedList.png

5.3 例题

  1. 以下关于单链表存储结构特征的叙述中,不正确的是(D)。

A. 表中结点所占用存储空间的地址不必是连续的
B. 在表中任意位置进行插入和删除操作都不用移动元素
C. 所需空间与结点个数成正比
D. 可随机访问表中的任一结点

5.4 队列和栈

  元素按照a、b、c的次序进入栈,请尝试写出其所有可能的出栈序。

QueueAndStack.png

5.5 例题

  1. 令序列X、Y、Z的每个元素都按顺序进栈,且每个元素进栈和出栈仅一次,则不可能得到的出栈序列是(C)。

A. XYZ
B. XZY
C. ZXY
D. YZX

6 广义表

  广义表示n个表元素组成的有限序列,是线性表的推广,通常用递归的形式进行定义,记作: $LS = (a_0, a_1, …, a_n)$

注:其中LS是表名, $a_i$ 是表元素,它可以是表(称做子表),也可以是数据元素(称为原子)。其中n是广义表的长度(也就是最外层包含的元素个数),n = 0的广义表为空表;而递归定义的重数就是广义表的深度,直观地说,就是定义中所含括号的重数(原子的深度为0,空表的深度为1)。

例,有广义表LS1 = (a, (b, c), (d, e)),其长度为?深度为?
答案:长度为3,深度为2。

7 串

  串是仅由字符构成的有限序列,是取值范围受限的线性表,一般记为 S = ‘a1a2…an’,其中S是串名,单引号括起来的字符序列是串值。

8 数组

  二维数组分按行存储和按列存储。c/c++的多维数组是按行、连续存储逇。FORTRAN语言,Matlab中,数组按列优先顺序存储。

数组类型 存储地址计算
一维数组a[n] a[i]的存储地址为:a + i * len
二维数组a[m][n] a[i][j]的存储地址(按行存储)为:a + (i * n + j) * len
a[i][j]存储地址(按列存储)为:a + (j * m + i) * len

8.1 例题

  1. 数组a[1 … n, 1 … m](n > 1, m > 1)中的元素以行为主序存放,每个元素占用1个存储伟,则数组元素a[i, j] $(1 \leq i \leq n, 1 \leq j \leq m)$ 相对于数组空间首地址的偏移量为(A)

A. (i - 1) * m + j - 1
B. (i - 1) * n + j - 1
C. (j - 1) * m + i - 1
D. (j - 1) * n + i - 1

  1. 若二维数组arr[1 … M, 1 … N]的首地址为base,数组元素按列存储且每个元素占用K个存储单元,则元素arr[i, j]在该数组空间的地址为()。

A. base + ((i - 1) * M + j - 1) * K
B. base + ((i - 1) * N + j - 1) * K
C. base + ((j - 1) * M + i - 1) * K
D. base + ((j - 1) * N + i - 1) * K

9 树与二叉树

  • 结点的度
  • 树的高度
  • 叶子结点
  • 分支结点
  • 内部结点
  • 父结点
  • 子结点
  • 兄弟结点
  • 层次

BinaryTree.png

BinaryTree_1.png

  二叉树的重要特征。

  • 在二叉树的第i层上最多有 $2^{i - 1}$ 个结点 $(i \geq 1)$ ;
  • 深度为k的二叉树最多有 $2^k - 1$ 个结点 $(k \geq 1)$ ;
  • 对任何一颗二叉树,如果其叶子结点数为 $n_0$ ,度为2的结点数为 $n_2$ ,则 $n_0 = n_2 + 1$ 。
  • 如果对一颗有n个结点的完全二叉树的结点按层序编号(从第1层到 $log_2n + 1$ 层,每层从左到右),则对任一结点i $(i \geq i \geq n)$ ,有
    • 如果i = 1,则结点i无父结点,是二叉树的根;如果i > 1,则父结点是i / 2;
    • 如果2i > n,则结点i为叶子结点,无左子结点;否则,其左子结点是结点2i;
    • 如果2i + 1 > n,则结点i无右叶子结点,否则,其右子结点是结点2i + 1;

9.1 二叉树遍历

  • 前序遍历(根左右)
  • 中序遍历(左根右)
  • 后序遍历(左右根)
  • 层序遍历

  前序遍历:12457836,中序遍历:42785136,后序遍历:48752631,层次遍历:12345678。

TraversalOfBinaryTree.png

10 堆

  堆是计算机科学中的一类特殊的数据结构的统称。堆通常是一个可以被看做一颗完全二叉树的数组对象。
  若n个元素的序列 ${a_1, a_2 … a_n}$ 满足

Formula.png

  则分别称该序列 ${a_1, a_2, … a_n}$ 为小根堆和大根堆。
  从堆的定义可以看出,对实质是满足如下性质的完全二叉树:

  • 二叉树中任一非叶子结点均小于(大于)它的孩子结点。
  • 堆总是一颗完全二叉树。

  例如:下面序列为堆,对应的完全二叉树分别为。

1
2
98 77 35 62 55 14 35 48
14 48 35 62 55 98 35 77

Heap.png

10.1 例题

  1. 对于n个元素的关键字序列 ${k_1, k_2, … k_n}$ ,当且仅当满足关系 $k_j \leq k_{2i}$ 且 $k_i \leq k_{2i + 1}$ {i = 1.2…[n/2]}时称其为小根堆(小顶堆)。以下序列中,(D)不是小根堆。

A. 16, 25, 40, 55, 30, 50, 45
B. 16, 40, 25, 50, 45, 30, 55
C. 16, 25, 39, 41, 45, 43, 50
D. 16, 40, 25, 53, 39, 55, 45

11 图

11.1 图的存储

11.1.1 邻接矩阵表示法

  邻接矩阵表示法用一个n阶方阵R来存放图中各结点的关联信息,其矩阵元素 $R_{ij}$ 定义为。
  为无向图。表示稀疏矩阵时空间浪费大。

FigureOfTheStorage.png

11.1.2 邻接链条表示法

  首先把每个顶点的邻接顶点用链表表示出来,然后用一个一维数组来顺序存储上面每个链表的头指针。

ListFigure.png

11.2 例题

  1. 某有向图G的邻接表如下图所示,可看出该图中存在弧 $<v_2, V3>$ 而不存在从顶点 $V_1$ 出发的弧。以下关于图G的叙述中,错误的是()。

A. G中存在回路
B. G中每个顶点的入度为1
C. G的邻接矩阵是对称的
D. 不存在弧 $V_3, V_1>

ex1.png

11.3 图的遍历

GraphTraversal.png

12 查找算法

  • 五大查找
    • 顺序表查找
      • 顺序查找
      • 二分查找
      • 索引顺序查找
    • 树表查找
      • 二叉排序树
    • 散列表查找
      • 哈希查找

12.1 顺序查找

  顺序查找的过程:将待查找的关键字可key的元素从头到尾与表中元素进行比较,如果中间存在关键字为key的元素,则返回成功,否则返回失败。顺序查找主要针对少量的、无规则的数据。

1
4 7 10 18 30 2 46 24 15

12.2 二分查找

  二分法查找的基本过程是:(设R[low, …, high]是当前的查找区)

  • 确定该区间的中间位置:mid = [(low + high) / 2],向下取整。
  • 将待查的k值与R[mid].key比较,若相等,则查找成功并返回此位置,否则需确定新的查找区间,继续二分查找,具体方法如下。
    • 若R[mid].key > k,则由表的有序性可知R[mid, …, n].key均大于k,因此若表中存在关键字等于k的结点,则该结点必定是在位置mid左边的子表R[low, …, mid -1]中。因此,新的查找区间是左子表R[low, …, high],其中high = mid - 1.
    • 若R[mid].key < k,则要查找的k必在mid的右子表R[mid + 1, …, high]中,即新的查找区间是右子表R[low, …, high],其中low = mid + 1。
    • 若R[mid].key = k,则查找成功,算法结束。
  • 下次查找是针对新的查找区间进行,重复步骤(1)和(2)。
  • 在查找过程中,low逐步增加,而high逐步减少。如果high < low,则查找失败,算法结束。

12.3 二叉查找树(排序)

  二叉查找树的定义:二叉排序树或者是一颗空树,或者是具有如下特性的二叉树。

  • 若它的左子树不空,则左子树上所有节点的值均小于根节点的值。
  • 若它的有子树不空,则右子树上所有节点的值均大于根节点的值。
  • 它的左、右子树也都分别是二叉排序树。

  对二叉查找树进行中序遍历,即可得到有序的序列。

BinarySortTree.png

  查找过程:二叉查找(排序)树是先对待查找的数据进行生成树,确保数的左分支值小于右分支的值,然后再去和每个结点的父结点比较大小,查找最合适的范围。这个算法的查找效率很高,但是如果使用这种查找方法要首先创建数。
  具体步骤为。

  • 若查找的关键字等于根节点的关键字,查找成功。
  • 若查找的关键字小于根节点的关键字,递归查找左子树。
  • 若查找的关键字大于根节点的关键字,递归查找右子树。
  • 若子树为空,则查找不成功。

12.4 二叉平衡树

  定义:又称AVL树。它或者是一颗空树,或者是具有下列性质的二叉树:它的左子树或右子树都是平衡二叉树,且左子树和右子树的深度之差的绝对值不超过1。

  平衡因子。
  二叉树上任一结点的左子树深度减去右子树深度的差值,称为此结点的平衡因子。

AVL.png

12.5 例题

  1. 关于二叉排序树的说法,错误的是(C)。

A. 对于二叉排序树进行中序遍历,必定得到结点关键字的有序序列
B. 依据关键字无序的序列建立二叉排序,也可能构造出单支树
C. 若构造二叉排序树时进行平衡化处理,则根节点的左子树结点数与右子树结点数的差值一定不超过1
D. 若构造二叉排序树时进行平衡化处理,则根结点的左子树高度与右子树高度的差值一定不超过1

12.5 哈夫曼树

  定义:给定N个权值作为N个叶子节点,构造一颗二叉树,若该树的带权路径长度达到最小,称这样的二叉树为最优二叉树,也称为哈夫曼树。哈夫曼树是带权路径长度最短的数,权值较大的结点离根较近。
  一般可以按下面步骤构建。

  • 将所有左、右子树都为空的作为根节点。
  • 在森林中选取两棵根节点的权值最小的数作为一棵新树的左、右子树,且置新树的附加根节点的权值为其左、右子树上根结点的权值之和。
  • 从森林中删除这两棵树,同时把新树加入到森林中。
  • 重复2、3步骤,直到森林中只有一棵树为止,此树便是哈夫曼树。

HuffmanTree.png

HuffmanTree_.png

  应用场景:对字符集中的字符进行编码和译码。

12.6 例题

  1. 以下有关哈夫曼树的说法中,错误的是(C)。

A. 哈夫曼树又被称为最优二叉树
B. 哈夫曼树是一种带权路径长度最短的树
C. 具有n个叶子结点的权值为 $W_1, W_2, …, W_n$ 的最优二叉树是唯一的
D. 哈夫曼树可以用来进行通信电文的编码和解码

13 B树

  B树,有时又写为B-树或B_树(其中的“-”或者“_”只是连字符,并不读作“B减树”)。一颗m阶的B树是一颗平衡的多路搜索树,它或者是空树,或者是满足下列性质的树。

  1. 树中每个结点至多有m棵子树。
  2. 若根结点不是叶子结点,则至少有两棵子树。
  3. 除根之外的所有非终端结点至少有[m/2](向上取整)棵子树。
  4. 所有的非终端结点中包含下列信息数据:

   $(n, A_0, K_1, A_1, K_2, A_2, …, K_n, A_n)$ ,其中: $K_i (i = 1, 2, …, n)$ 为关键字,且 $K_i < K_{i + 1}$ (i = 1, …, n - 1)。
   $A_i (i = 0, …, n)$ 为指向子树根结点的指针,且指针 $A_{i -1}$ 所指子树中所有结点的关键字均小于 $K_i(i = 1, …, n)$ , $A_n$ 所指子树中所有结点的关键字均大于 $K_n$ , $n ([m / 2] - 1 \leq n \leq m - 1)$ 为关键字的个数(或n + 1为子树个数)。其中[m / 2]表示向上取整。

  1. 所有的叶子结点都出现在同一层次上,并且不带信息(可以看作是外部结点或查找失败的结点,实际上这些结点不存在,指向这些结点的指针为空)。

BTree.png

14 B+树

  是B-树的一种变型,一个m阶的B+树具有如下几个特征。

  • 每个叶子结点中含有n个关键字和n个指向记录的指针,并且所有叶子节点彼此相链接构成一个有序链表,其头指针指向含最小关键字的节点。
  • 每个非叶子节点中的关键字 $K_i$ 即为其相应指针 $A_i$ 所指子树中关键字的最大值。
  • 所有叶子节点都处在统一层次上,每个叶子节点中关键字的个数均介于[m / 2](向上取整)和m之间。

B+Tree.png

15 散列表

  散列表构造的基本思想是:已知关键字集合U,最大关键字为m,设计一个函数Hash,它以关键字为自变量,关键字的存储地址为因变量,将关键字映射到一个有限的、地址连续的区间T[0 .. n - 1](n << m)中,这个区间就称为散列表,散列查找中使用的转换函数称为散列函数。

  例:假设有一个大小为7的表,现在要将(13, 18, 19s, 50, 20, 27)散列到表中。

  • 选择散列函数,例如使用hash(x) = x % 7作为散列函数。
  • 计算数据散列值,并放到合适的位置。
哈希地址 0 1 2 3 4 5 6
关键码 50 18 19 13

  地址重复时出现冲突,即散列冲突。

15.1 解决散列冲突

  • 链地址法(拉链法)
  • 开放地址法

   $H_i = (Hash(key) + d_i) % m$ i = 1, 2, …, k $(k \leq m - 1)$
  其中Hash(key)为哈希函数,m为哈希表的表长,di为增量序列。常见的增量序列有三种。

  • di = 1, 2, 3, …, m - 1,称为线性他侧再散列。
  • di = $1^2, {-1}^2, 2^2, {-2}^2, 3^3, …, ±k^2$ ,称为二次探测再散列。
  • di = 伪随机数列,称为随机探测再散列,如:di = Random(key)。

15.2 例题

  1. 用哈希表存储元素时,需要进行冲突(碰撞)处理,冲突是指(B)。

A. 关键字被依次映射到地址编号连续的存储位置
B. 关键字不同的元素被映射到相同的存储位置
C. 关键字相同的元素被映射到不同的存储位置
D. 关键字被映射到哈希表之外的位置

16 总结

  考查形式主要是概念区分以及部分计算题型,主要出现在上午的选择题当中。

  • 树的遍历
  • 图的遍历
  • 典型的时间复杂度

  需要记忆。

  • 数据结构与算法的概念
  • 线性表(顺序表、链表、栈、队列)
  • 数组与矩阵
  • 树与二叉树
  • 查找(二分查找、哈希)

  则分别称该序列 ${a_1, a_2, … a_n}$ 为小根堆和大根堆。
  从堆的定义可以看出,对实质是满足如下性质的完全二叉树:

  • 二叉树中任一非叶子结点均小于(大于)它的孩子结点。
  • 堆总是一颗完全二叉树。

  例如:下面序列为堆,对应的完全二叉树分别为。

1
2
98 77 35 62 55 14 35 48
14 48 35 62 55 98 35 77

第九章——数据结构与算法

前言:
   计算机第九章节主要知识点。

1 知识点介绍

  • 数据结构与算法概念
  • 线性表
  • 数组与矩阵
  • 树与二叉树
  • 查找

2 数据结构定义

  • 数据结构
    • 数据逻辑结构:指数据元素之间的管理。
      • 线性结构:一对一关系
      • 非线性结构:一对多,多对多关系
    • 数据物理结构:数据在物理设备上具体如何存储。

3 算法概念

  算法的5个重要特征

  • 又穷性:执行有穷步之后结束,且每一步都可在有穷时间内完成。
  • 确定性:算法中每一条指令都必须由确切的含义,不能含糊不清。
  • 输入(>= 0)
  • 输出(>= 1)
  • 有效性(可行性):算法的每个步骤都能有效执行并能在执行有限此后得到确定的结果,例如a = 0,b / a就无效。

4 伪代码

  伪代码是一种算法描述语言,介于自然语言与编程语言之间,不用拘泥于具体的实现。

Pseudocode.png

5 线性表

5.1 线性表的概念

  常见线性表的两种存储结构。

  • 顺序存储结构(如:顺序表)
  • 链式存储结构(如:链表)

  逻辑上连续,物理上不一定连续。

  • 顺序表:随机存取。查询和修改容易,元素插入和删除麻烦,需要移动元素。
  • 链表
    • 单链表
    • 循环链表
    • 双向链表

LinearList.png

5.2 链表基本操作

  • 单链表删除结点
  • 单链表插入结点
  • 双向链表删除结点
  • 双向链表插入结点

LinkedList.png

5.3 例题

  1. 以下关于单链表存储结构特征的叙述中,不正确的是(D)。

A. 表中结点所占用存储空间的地址不必是连续的
B. 在表中任意位置进行插入和删除操作都不用移动元素
C. 所需空间与结点个数成正比
D. 可随机访问表中的任一结点

5.4 队列和栈

  元素按照a、b、c的次序进入栈,请尝试写出其所有可能的出栈序。

QueueAndStack.png

5.5 例题

  1. 令序列X、Y、Z的每个元素都按顺序进栈,且每个元素进栈和出栈仅一次,则不可能得到的出栈序列是(C)。

A. XYZ
B. XZY
C. ZXY
D. YZX

6 广义表

  广义表示n个表元素组成的有限序列,是线性表的推广,通常用递归的形式进行定义,记作: $LS = (a_0, a_1, …, a_n)$

注:其中LS是表名, $a_i$ 是表元素,它可以是表(称做子表),也可以是数据元素(称为原子)。其中n是广义表的长度(也就是最外层包含的元素个数),n = 0的广义表为空表;而递归定义的重数就是广义表的深度,直观地说,就是定义中所含括号的重数(原子的深度为0,空表的深度为1)。

例,有广义表LS1 = (a, (b, c), (d, e)),其长度为?深度为?
答案:长度为3,深度为2。

7 串

  串是仅由字符构成的有限序列,是取值范围受限的线性表,一般记为 S = ‘a1a2…an’,其中S是串名,单引号括起来的字符序列是串值。

8 数组

  二维数组分按行存储和按列存储。c/c++的多维数组是按行、连续存储逇。FORTRAN语言,Matlab中,数组按列优先顺序存储。

数组类型 存储地址计算
一维数组a[n] a[i]的存储地址为:a + i * len
二维数组a[m][n] a[i][j]的存储地址(按行存储)为:a + (i * n + j) * len
a[i][j]存储地址(按列存储)为:a + (j * m + i) * len

8.1 例题

  1. 数组a[1 … n, 1 … m](n > 1, m > 1)中的元素以行为主序存放,每个元素占用1个存储伟,则数组元素a[i, j] $(1 \leq i \leq n, 1 \leq j \leq m)$ 相对于数组空间首地址的偏移量为(A)

A. (i - 1) * m + j - 1
B. (i - 1) * n + j - 1
C. (j - 1) * m + i - 1
D. (j - 1) * n + i - 1

  1. 若二维数组arr[1 … M, 1 … N]的首地址为base,数组元素按列存储且每个元素占用K个存储单元,则元素arr[i, j]在该数组空间的地址为()。

A. base + ((i - 1) * M + j - 1) * K
B. base + ((i - 1) * N + j - 1) * K
C. base + ((j - 1) * M + i - 1) * K
D. base + ((j - 1) * N + i - 1) * K

9 树与二叉树

  • 结点的度
  • 树的高度
  • 叶子结点
  • 分支结点
  • 内部结点
  • 父结点
  • 子结点
  • 兄弟结点
  • 层次

BinaryTree.png

BinaryTree_1.png

  二叉树的重要特征。

  • 在二叉树的第i层上最多有 $2^{i - 1}$ 个结点 $(i \geq 1)$ ;
  • 深度为k的二叉树最多有 $2^k - 1$ 个结点 $(k \geq 1)$ ;
  • 对任何一颗二叉树,如果其叶子结点数为 $n_0$ ,度为2的结点数为 $n_2$ ,则 $n_0 = n_2 + 1$ 。
  • 如果对一颗有n个结点的完全二叉树的结点按层序编号(从第1层到 $log_2n + 1$ 层,每层从左到右),则对任一结点i $(i \geq i \geq n)$ ,有
    • 如果i = 1,则结点i无父结点,是二叉树的根;如果i > 1,则父结点是i / 2;
    • 如果2i > n,则结点i为叶子结点,无左子结点;否则,其左子结点是结点2i;
    • 如果2i + 1 > n,则结点i无右叶子结点,否则,其右子结点是结点2i + 1;

9.1 二叉树遍历

  • 前序遍历(根左右)
  • 中序遍历(左根右)
  • 后序遍历(左右根)
  • 层序遍历

  前序遍历:12457836,中序遍历:42785136,后序遍历:48752631,层次遍历:12345678。

TraversalOfBinaryTree.png

10 堆

  堆是计算机科学中的一类特殊的数据结构的统称。堆通常是一个可以被看做一颗完全二叉树的数组对象。
  若n个元素的序列 ${a_1, a_2 … a_n}$ 满足

Formula.png

  则分别称该序列 ${a_1, a_2, … a_n}$ 为小根堆和大根堆。
  从堆的定义可以看出,对实质是满足如下性质的完全二叉树:

  • 二叉树中任一非叶子结点均小于(大于)它的孩子结点。
  • 堆总是一颗完全二叉树。

  例如:下面序列为堆,对应的完全二叉树分别为。

1
2
98 77 35 62 55 14 35 48
14 48 35 62 55 98 35 77

Heap.png

10.1 例题

  1. 对于n个元素的关键字序列 ${k_1, k_2, … k_n}$ ,当且仅当满足关系 $k_j \leq k_{2i}$ 且 $k_i \leq k_{2i + 1}$ {i = 1.2…[n/2]}时称其为小根堆(小顶堆)。以下序列中,(D)不是小根堆。

A. 16, 25, 40, 55, 30, 50, 45
B. 16, 40, 25, 50, 45, 30, 55
C. 16, 25, 39, 41, 45, 43, 50
D. 16, 40, 25, 53, 39, 55, 45

11 图

11.1 图的存储

11.1.1 邻接矩阵表示法

  邻接矩阵表示法用一个n阶方阵R来存放图中各结点的关联信息,其矩阵元素 $R_{ij}$ 定义为。
  为无向图。表示稀疏矩阵时空间浪费大。

FigureOfTheStorage.png

11.1.2 邻接链条表示法

  首先把每个顶点的邻接顶点用链表表示出来,然后用一个一维数组来顺序存储上面每个链表的头指针。

ListFigure.png

11.2 例题

  1. 某有向图G的邻接表如下图所示,可看出该图中存在弧 $<v_2, V3>$ 而不存在从顶点 $V_1$ 出发的弧。以下关于图G的叙述中,错误的是()。

A. G中存在回路
B. G中每个顶点的入度为1
C. G的邻接矩阵是对称的
D. 不存在弧 $V_3, V_1>

ex1.png

11.3 图的遍历

GraphTraversal.png

12 查找算法

  • 五大查找
    • 顺序表查找
      • 顺序查找
      • 二分查找
      • 索引顺序查找
    • 树表查找
      • 二叉排序树
    • 散列表查找
      • 哈希查找

12.1 顺序查找

  顺序查找的过程:将待查找的关键字可key的元素从头到尾与表中元素进行比较,如果中间存在关键字为key的元素,则返回成功,否则返回失败。顺序查找主要针对少量的、无规则的数据。

1
4 7 10 18 30 2 46 24 15

12.2 二分查找

  二分法查找的基本过程是:(设R[low, …, high]是当前的查找区)

  • 确定该区间的中间位置:mid = [(low + high) / 2],向下取整。
  • 将待查的k值与R[mid].key比较,若相等,则查找成功并返回此位置,否则需确定新的查找区间,继续二分查找,具体方法如下。
    • 若R[mid].key > k,则由表的有序性可知R[mid, …, n].key均大于k,因此若表中存在关键字等于k的结点,则该结点必定是在位置mid左边的子表R[low, …, mid -1]中。因此,新的查找区间是左子表R[low, …, high],其中high = mid - 1.
    • 若R[mid].key < k,则要查找的k必在mid的右子表R[mid + 1, …, high]中,即新的查找区间是右子表R[low, …, high],其中low = mid + 1。
    • 若R[mid].key = k,则查找成功,算法结束。
  • 下次查找是针对新的查找区间进行,重复步骤(1)和(2)。
  • 在查找过程中,low逐步增加,而high逐步减少。如果high < low,则查找失败,算法结束。

12.3 二叉查找树(排序)

  二叉查找树的定义:二叉排序树或者是一颗空树,或者是具有如下特性的二叉树。

  • 若它的左子树不空,则左子树上所有节点的值均小于根节点的值。
  • 若它的有子树不空,则右子树上所有节点的值均大于根节点的值。
  • 它的左、右子树也都分别是二叉排序树。

  对二叉查找树进行中序遍历,即可得到有序的序列。

BinarySortTree.png

  查找过程:二叉查找(排序)树是先对待查找的数据进行生成树,确保数的左分支值小于右分支的值,然后再去和每个结点的父结点比较大小,查找最合适的范围。这个算法的查找效率很高,但是如果使用这种查找方法要首先创建数。
  具体步骤为。

  • 若查找的关键字等于根节点的关键字,查找成功。
  • 若查找的关键字小于根节点的关键字,递归查找左子树。
  • 若查找的关键字大于根节点的关键字,递归查找右子树。
  • 若子树为空,则查找不成功。

12.4 二叉平衡树

  定义:又称AVL树。它或者是一颗空树,或者是具有下列性质的二叉树:它的左子树或右子树都是平衡二叉树,且左子树和右子树的深度之差的绝对值不超过1。

  平衡因子。
  二叉树上任一结点的左子树深度减去右子树深度的差值,称为此结点的平衡因子。

AVL.png

12.5 例题

  1. 关于二叉排序树的说法,错误的是(C)。

A. 对于二叉排序树进行中序遍历,必定得到结点关键字的有序序列
B. 依据关键字无序的序列建立二叉排序,也可能构造出单支树
C. 若构造二叉排序树时进行平衡化处理,则根节点的左子树结点数与右子树结点数的差值一定不超过1
D. 若构造二叉排序树时进行平衡化处理,则根结点的左子树高度与右子树高度的差值一定不超过1

12.5 哈夫曼树

  定义:给定N个权值作为N个叶子节点,构造一颗二叉树,若该树的带权路径长度达到最小,称这样的二叉树为最优二叉树,也称为哈夫曼树。哈夫曼树是带权路径长度最短的数,权值较大的结点离根较近。
  一般可以按下面步骤构建。

  • 将所有左、右子树都为空的作为根节点。
  • 在森林中选取两棵根节点的权值最小的数作为一棵新树的左、右子树,且置新树的附加根节点的权值为其左、右子树上根结点的权值之和。
  • 从森林中删除这两棵树,同时把新树加入到森林中。
  • 重复2、3步骤,直到森林中只有一棵树为止,此树便是哈夫曼树。

HuffmanTree.png

HuffmanTree_.png

  应用场景:对字符集中的字符进行编码和译码。

12.6 例题

  1. 以下有关哈夫曼树的说法中,错误的是(C)。

A. 哈夫曼树又被称为最优二叉树
B. 哈夫曼树是一种带权路径长度最短的树
C. 具有n个叶子结点的权值为 $W_1, W_2, …, W_n$ 的最优二叉树是唯一的
D. 哈夫曼树可以用来进行通信电文的编码和解码

13 B树

  B树,有时又写为B-树或B_树(其中的“-”或者“_”只是连字符,并不读作“B减树”)。一颗m阶的B树是一颗平衡的多路搜索树,它或者是空树,或者是满足下列性质的树。

  1. 树中每个结点至多有m棵子树。
  2. 若根结点不是叶子结点,则至少有两棵子树。
  3. 除根之外的所有非终端结点至少有[m/2](向上取整)棵子树。
  4. 所有的非终端结点中包含下列信息数据:

   $(n, A_0, K_1, A_1, K_2, A_2, …, K_n, A_n)$ ,其中: $K_i (i = 1, 2, …, n)$ 为关键字,且 $K_i < K_{i + 1}$ (i = 1, …, n - 1)。
   $A_i (i = 0, …, n)$ 为指向子树根结点的指针,且指针 $A_{i -1}$ 所指子树中所有结点的关键字均小于 $K_i(i = 1, …, n)$ , $A_n$ 所指子树中所有结点的关键字均大于 $K_n$ , $n ([m / 2] - 1 \leq n \leq m - 1)$ 为关键字的个数(或n + 1为子树个数)。其中[m / 2]表示向上取整。

  1. 所有的叶子结点都出现在同一层次上,并且不带信息(可以看作是外部结点或查找失败的结点,实际上这些结点不存在,指向这些结点的指针为空)。

BTree.png

14 B+树

  是B-树的一种变型,一个m阶的B+树具有如下几个特征。

  • 每个叶子结点中含有n个关键字和n个指向记录的指针,并且所有叶子节点彼此相链接构成一个有序链表,其头指针指向含最小关键字的节点。
  • 每个非叶子节点中的关键字 $K_i$ 即为其相应指针 $A_i$ 所指子树中关键字的最大值。
  • 所有叶子节点都处在统一层次上,每个叶子节点中关键字的个数均介于[m / 2](向上取整)和m之间。

B+Tree.png

15 散列表

  散列表构造的基本思想是:已知关键字集合U,最大关键字为m,设计一个函数Hash,它以关键字为自变量,关键字的存储地址为因变量,将关键字映射到一个有限的、地址连续的区间T[0 .. n - 1](n << m)中,这个区间就称为散列表,散列查找中使用的转换函数称为散列函数。

  例:假设有一个大小为7的表,现在要将(13, 18, 19s, 50, 20, 27)散列到表中。

  • 选择散列函数,例如使用hash(x) = x % 7作为散列函数。
  • 计算数据散列值,并放到合适的位置。
哈希地址 0 1 2 3 4 5 6
关键码 50 18 19 13

  地址重复时出现冲突,即散列冲突。

15.1 解决散列冲突

  • 链地址法(拉链法)
  • 开放地址法

   $H_i = (Hash(key) + d_i) % m$ i = 1, 2, …, k $(k \leq m - 1)$
  其中Hash(key)为哈希函数,m为哈希表的表长,di为增量序列。常见的增量序列有三种。

  • di = 1, 2, 3, …, m - 1,称为线性他侧再散列。
  • di = $1^2, {-1}^2, 2^2, {-2}^2, 3^3, …, ±k^2$ ,称为二次探测再散列。
  • di = 伪随机数列,称为随机探测再散列,如:di = Random(key)。

15.2 例题

  1. 用哈希表存储元素时,需要进行冲突(碰撞)处理,冲突是指(B)。

A. 关键字被依次映射到地址编号连续的存储位置
B. 关键字不同的元素被映射到相同的存储位置
C. 关键字相同的元素被映射到不同的存储位置
D. 关键字被映射到哈希表之外的位置

16 总结

  考查形式主要是概念区分以及部分计算题型,主要出现在上午的选择题当中。

  • 树的遍历
  • 图的遍历
  • 典型的时间复杂度

  需要记忆。

  • 数据结构与算法的概念
  • 线性表(顺序表、链表、栈、队列)
  • 数组与矩阵
  • 树与二叉树
  • 查找(二分查找、哈希)

10.1 例题

  1. 对于n个元素的关键字序列 ${k_1, k_2, … k_n}$ ,当且仅当满足关系 $k_j \leq k_{2i}$ 且 $k_i \leq k_{2i + 1}$ {i = 1.2…[n/2]}时称其为小根堆(小顶堆)。以下序列中,(D)不是小根堆。

A. 16, 25, 40, 55, 30, 50, 45
B. 16, 40, 25, 50, 45, 30, 55
C. 16, 25, 39, 41, 45, 43, 50
D. 16, 40, 25, 53, 39, 55, 45

11 图

11.1 图的存储

11.1.1 邻接矩阵表示法

  邻接矩阵表示法用一个n阶方阵R来存放图中各结点的关联信息,其矩阵元素 $R_{ij}$ 定义为。
  为无向图。表示稀疏矩阵时空间浪费大。

第九章——数据结构与算法

前言:
   计算机第九章节主要知识点。

1 知识点介绍

  • 数据结构与算法概念
  • 线性表
  • 数组与矩阵
  • 树与二叉树
  • 查找

2 数据结构定义

  • 数据结构
    • 数据逻辑结构:指数据元素之间的管理。
      • 线性结构:一对一关系
      • 非线性结构:一对多,多对多关系
    • 数据物理结构:数据在物理设备上具体如何存储。

3 算法概念

  算法的5个重要特征

  • 又穷性:执行有穷步之后结束,且每一步都可在有穷时间内完成。
  • 确定性:算法中每一条指令都必须由确切的含义,不能含糊不清。
  • 输入(>= 0)
  • 输出(>= 1)
  • 有效性(可行性):算法的每个步骤都能有效执行并能在执行有限此后得到确定的结果,例如a = 0,b / a就无效。

4 伪代码

  伪代码是一种算法描述语言,介于自然语言与编程语言之间,不用拘泥于具体的实现。

Pseudocode.png

5 线性表

5.1 线性表的概念

  常见线性表的两种存储结构。

  • 顺序存储结构(如:顺序表)
  • 链式存储结构(如:链表)

  逻辑上连续,物理上不一定连续。

  • 顺序表:随机存取。查询和修改容易,元素插入和删除麻烦,需要移动元素。
  • 链表
    • 单链表
    • 循环链表
    • 双向链表

LinearList.png

5.2 链表基本操作

  • 单链表删除结点
  • 单链表插入结点
  • 双向链表删除结点
  • 双向链表插入结点

LinkedList.png

5.3 例题

  1. 以下关于单链表存储结构特征的叙述中,不正确的是(D)。

A. 表中结点所占用存储空间的地址不必是连续的
B. 在表中任意位置进行插入和删除操作都不用移动元素
C. 所需空间与结点个数成正比
D. 可随机访问表中的任一结点

5.4 队列和栈

  元素按照a、b、c的次序进入栈,请尝试写出其所有可能的出栈序。

QueueAndStack.png

5.5 例题

  1. 令序列X、Y、Z的每个元素都按顺序进栈,且每个元素进栈和出栈仅一次,则不可能得到的出栈序列是(C)。

A. XYZ
B. XZY
C. ZXY
D. YZX

6 广义表

  广义表示n个表元素组成的有限序列,是线性表的推广,通常用递归的形式进行定义,记作: $LS = (a_0, a_1, …, a_n)$

注:其中LS是表名, $a_i$ 是表元素,它可以是表(称做子表),也可以是数据元素(称为原子)。其中n是广义表的长度(也就是最外层包含的元素个数),n = 0的广义表为空表;而递归定义的重数就是广义表的深度,直观地说,就是定义中所含括号的重数(原子的深度为0,空表的深度为1)。

例,有广义表LS1 = (a, (b, c), (d, e)),其长度为?深度为?
答案:长度为3,深度为2。

7 串

  串是仅由字符构成的有限序列,是取值范围受限的线性表,一般记为 S = ‘a1a2…an’,其中S是串名,单引号括起来的字符序列是串值。

8 数组

  二维数组分按行存储和按列存储。c/c++的多维数组是按行、连续存储逇。FORTRAN语言,Matlab中,数组按列优先顺序存储。

数组类型 存储地址计算
一维数组a[n] a[i]的存储地址为:a + i * len
二维数组a[m][n] a[i][j]的存储地址(按行存储)为:a + (i * n + j) * len
a[i][j]存储地址(按列存储)为:a + (j * m + i) * len

8.1 例题

  1. 数组a[1 … n, 1 … m](n > 1, m > 1)中的元素以行为主序存放,每个元素占用1个存储伟,则数组元素a[i, j] $(1 \leq i \leq n, 1 \leq j \leq m)$ 相对于数组空间首地址的偏移量为(A)

A. (i - 1) * m + j - 1
B. (i - 1) * n + j - 1
C. (j - 1) * m + i - 1
D. (j - 1) * n + i - 1

  1. 若二维数组arr[1 … M, 1 … N]的首地址为base,数组元素按列存储且每个元素占用K个存储单元,则元素arr[i, j]在该数组空间的地址为()。

A. base + ((i - 1) * M + j - 1) * K
B. base + ((i - 1) * N + j - 1) * K
C. base + ((j - 1) * M + i - 1) * K
D. base + ((j - 1) * N + i - 1) * K

9 树与二叉树

  • 结点的度
  • 树的高度
  • 叶子结点
  • 分支结点
  • 内部结点
  • 父结点
  • 子结点
  • 兄弟结点
  • 层次

BinaryTree.png

BinaryTree_1.png

  二叉树的重要特征。

  • 在二叉树的第i层上最多有 $2^{i - 1}$ 个结点 $(i \geq 1)$ ;
  • 深度为k的二叉树最多有 $2^k - 1$ 个结点 $(k \geq 1)$ ;
  • 对任何一颗二叉树,如果其叶子结点数为 $n_0$ ,度为2的结点数为 $n_2$ ,则 $n_0 = n_2 + 1$ 。
  • 如果对一颗有n个结点的完全二叉树的结点按层序编号(从第1层到 $log_2n + 1$ 层,每层从左到右),则对任一结点i $(i \geq i \geq n)$ ,有
    • 如果i = 1,则结点i无父结点,是二叉树的根;如果i > 1,则父结点是i / 2;
    • 如果2i > n,则结点i为叶子结点,无左子结点;否则,其左子结点是结点2i;
    • 如果2i + 1 > n,则结点i无右叶子结点,否则,其右子结点是结点2i + 1;

9.1 二叉树遍历

  • 前序遍历(根左右)
  • 中序遍历(左根右)
  • 后序遍历(左右根)
  • 层序遍历

  前序遍历:12457836,中序遍历:42785136,后序遍历:48752631,层次遍历:12345678。

TraversalOfBinaryTree.png

10 堆

  堆是计算机科学中的一类特殊的数据结构的统称。堆通常是一个可以被看做一颗完全二叉树的数组对象。
  若n个元素的序列 ${a_1, a_2 … a_n}$ 满足

Formula.png

  则分别称该序列 ${a_1, a_2, … a_n}$ 为小根堆和大根堆。
  从堆的定义可以看出,对实质是满足如下性质的完全二叉树:

  • 二叉树中任一非叶子结点均小于(大于)它的孩子结点。
  • 堆总是一颗完全二叉树。

  例如:下面序列为堆,对应的完全二叉树分别为。

1
2
98 77 35 62 55 14 35 48
14 48 35 62 55 98 35 77

Heap.png

10.1 例题

  1. 对于n个元素的关键字序列 ${k_1, k_2, … k_n}$ ,当且仅当满足关系 $k_j \leq k_{2i}$ 且 $k_i \leq k_{2i + 1}$ {i = 1.2…[n/2]}时称其为小根堆(小顶堆)。以下序列中,(D)不是小根堆。

A. 16, 25, 40, 55, 30, 50, 45
B. 16, 40, 25, 50, 45, 30, 55
C. 16, 25, 39, 41, 45, 43, 50
D. 16, 40, 25, 53, 39, 55, 45

11 图

11.1 图的存储

11.1.1 邻接矩阵表示法

  邻接矩阵表示法用一个n阶方阵R来存放图中各结点的关联信息,其矩阵元素 $R_{ij}$ 定义为。
  为无向图。表示稀疏矩阵时空间浪费大。

FigureOfTheStorage.png

11.1.2 邻接链条表示法

  首先把每个顶点的邻接顶点用链表表示出来,然后用一个一维数组来顺序存储上面每个链表的头指针。

ListFigure.png

11.2 例题

  1. 某有向图G的邻接表如下图所示,可看出该图中存在弧 $<v_2, V3>$ 而不存在从顶点 $V_1$ 出发的弧。以下关于图G的叙述中,错误的是()。

A. G中存在回路
B. G中每个顶点的入度为1
C. G的邻接矩阵是对称的
D. 不存在弧 $V_3, V_1>

ex1.png

11.3 图的遍历

GraphTraversal.png

12 查找算法

  • 五大查找
    • 顺序表查找
      • 顺序查找
      • 二分查找
      • 索引顺序查找
    • 树表查找
      • 二叉排序树
    • 散列表查找
      • 哈希查找

12.1 顺序查找

  顺序查找的过程:将待查找的关键字可key的元素从头到尾与表中元素进行比较,如果中间存在关键字为key的元素,则返回成功,否则返回失败。顺序查找主要针对少量的、无规则的数据。

1
4 7 10 18 30 2 46 24 15

12.2 二分查找

  二分法查找的基本过程是:(设R[low, …, high]是当前的查找区)

  • 确定该区间的中间位置:mid = [(low + high) / 2],向下取整。
  • 将待查的k值与R[mid].key比较,若相等,则查找成功并返回此位置,否则需确定新的查找区间,继续二分查找,具体方法如下。
    • 若R[mid].key > k,则由表的有序性可知R[mid, …, n].key均大于k,因此若表中存在关键字等于k的结点,则该结点必定是在位置mid左边的子表R[low, …, mid -1]中。因此,新的查找区间是左子表R[low, …, high],其中high = mid - 1.
    • 若R[mid].key < k,则要查找的k必在mid的右子表R[mid + 1, …, high]中,即新的查找区间是右子表R[low, …, high],其中low = mid + 1。
    • 若R[mid].key = k,则查找成功,算法结束。
  • 下次查找是针对新的查找区间进行,重复步骤(1)和(2)。
  • 在查找过程中,low逐步增加,而high逐步减少。如果high < low,则查找失败,算法结束。

12.3 二叉查找树(排序)

  二叉查找树的定义:二叉排序树或者是一颗空树,或者是具有如下特性的二叉树。

  • 若它的左子树不空,则左子树上所有节点的值均小于根节点的值。
  • 若它的有子树不空,则右子树上所有节点的值均大于根节点的值。
  • 它的左、右子树也都分别是二叉排序树。

  对二叉查找树进行中序遍历,即可得到有序的序列。

BinarySortTree.png

  查找过程:二叉查找(排序)树是先对待查找的数据进行生成树,确保数的左分支值小于右分支的值,然后再去和每个结点的父结点比较大小,查找最合适的范围。这个算法的查找效率很高,但是如果使用这种查找方法要首先创建数。
  具体步骤为。

  • 若查找的关键字等于根节点的关键字,查找成功。
  • 若查找的关键字小于根节点的关键字,递归查找左子树。
  • 若查找的关键字大于根节点的关键字,递归查找右子树。
  • 若子树为空,则查找不成功。

12.4 二叉平衡树

  定义:又称AVL树。它或者是一颗空树,或者是具有下列性质的二叉树:它的左子树或右子树都是平衡二叉树,且左子树和右子树的深度之差的绝对值不超过1。

  平衡因子。
  二叉树上任一结点的左子树深度减去右子树深度的差值,称为此结点的平衡因子。

AVL.png

12.5 例题

  1. 关于二叉排序树的说法,错误的是(C)。

A. 对于二叉排序树进行中序遍历,必定得到结点关键字的有序序列
B. 依据关键字无序的序列建立二叉排序,也可能构造出单支树
C. 若构造二叉排序树时进行平衡化处理,则根节点的左子树结点数与右子树结点数的差值一定不超过1
D. 若构造二叉排序树时进行平衡化处理,则根结点的左子树高度与右子树高度的差值一定不超过1

12.5 哈夫曼树

  定义:给定N个权值作为N个叶子节点,构造一颗二叉树,若该树的带权路径长度达到最小,称这样的二叉树为最优二叉树,也称为哈夫曼树。哈夫曼树是带权路径长度最短的数,权值较大的结点离根较近。
  一般可以按下面步骤构建。

  • 将所有左、右子树都为空的作为根节点。
  • 在森林中选取两棵根节点的权值最小的数作为一棵新树的左、右子树,且置新树的附加根节点的权值为其左、右子树上根结点的权值之和。
  • 从森林中删除这两棵树,同时把新树加入到森林中。
  • 重复2、3步骤,直到森林中只有一棵树为止,此树便是哈夫曼树。

HuffmanTree.png

HuffmanTree_.png

  应用场景:对字符集中的字符进行编码和译码。

12.6 例题

  1. 以下有关哈夫曼树的说法中,错误的是(C)。

A. 哈夫曼树又被称为最优二叉树
B. 哈夫曼树是一种带权路径长度最短的树
C. 具有n个叶子结点的权值为 $W_1, W_2, …, W_n$ 的最优二叉树是唯一的
D. 哈夫曼树可以用来进行通信电文的编码和解码

13 B树

  B树,有时又写为B-树或B_树(其中的“-”或者“_”只是连字符,并不读作“B减树”)。一颗m阶的B树是一颗平衡的多路搜索树,它或者是空树,或者是满足下列性质的树。

  1. 树中每个结点至多有m棵子树。
  2. 若根结点不是叶子结点,则至少有两棵子树。
  3. 除根之外的所有非终端结点至少有[m/2](向上取整)棵子树。
  4. 所有的非终端结点中包含下列信息数据:

   $(n, A_0, K_1, A_1, K_2, A_2, …, K_n, A_n)$ ,其中: $K_i (i = 1, 2, …, n)$ 为关键字,且 $K_i < K_{i + 1}$ (i = 1, …, n - 1)。
   $A_i (i = 0, …, n)$ 为指向子树根结点的指针,且指针 $A_{i -1}$ 所指子树中所有结点的关键字均小于 $K_i(i = 1, …, n)$ , $A_n$ 所指子树中所有结点的关键字均大于 $K_n$ , $n ([m / 2] - 1 \leq n \leq m - 1)$ 为关键字的个数(或n + 1为子树个数)。其中[m / 2]表示向上取整。

  1. 所有的叶子结点都出现在同一层次上,并且不带信息(可以看作是外部结点或查找失败的结点,实际上这些结点不存在,指向这些结点的指针为空)。

BTree.png

14 B+树

  是B-树的一种变型,一个m阶的B+树具有如下几个特征。

  • 每个叶子结点中含有n个关键字和n个指向记录的指针,并且所有叶子节点彼此相链接构成一个有序链表,其头指针指向含最小关键字的节点。
  • 每个非叶子节点中的关键字 $K_i$ 即为其相应指针 $A_i$ 所指子树中关键字的最大值。
  • 所有叶子节点都处在统一层次上,每个叶子节点中关键字的个数均介于[m / 2](向上取整)和m之间。

B+Tree.png

15 散列表

  散列表构造的基本思想是:已知关键字集合U,最大关键字为m,设计一个函数Hash,它以关键字为自变量,关键字的存储地址为因变量,将关键字映射到一个有限的、地址连续的区间T[0 .. n - 1](n << m)中,这个区间就称为散列表,散列查找中使用的转换函数称为散列函数。

  例:假设有一个大小为7的表,现在要将(13, 18, 19s, 50, 20, 27)散列到表中。

  • 选择散列函数,例如使用hash(x) = x % 7作为散列函数。
  • 计算数据散列值,并放到合适的位置。
哈希地址 0 1 2 3 4 5 6
关键码 50 18 19 13

  地址重复时出现冲突,即散列冲突。

15.1 解决散列冲突

  • 链地址法(拉链法)
  • 开放地址法

   $H_i = (Hash(key) + d_i) % m$ i = 1, 2, …, k $(k \leq m - 1)$
  其中Hash(key)为哈希函数,m为哈希表的表长,di为增量序列。常见的增量序列有三种。

  • di = 1, 2, 3, …, m - 1,称为线性他侧再散列。
  • di = $1^2, {-1}^2, 2^2, {-2}^2, 3^3, …, ±k^2$ ,称为二次探测再散列。
  • di = 伪随机数列,称为随机探测再散列,如:di = Random(key)。

15.2 例题

  1. 用哈希表存储元素时,需要进行冲突(碰撞)处理,冲突是指(B)。

A. 关键字被依次映射到地址编号连续的存储位置
B. 关键字不同的元素被映射到相同的存储位置
C. 关键字相同的元素被映射到不同的存储位置
D. 关键字被映射到哈希表之外的位置

16 总结

  考查形式主要是概念区分以及部分计算题型,主要出现在上午的选择题当中。

  • 树的遍历
  • 图的遍历
  • 典型的时间复杂度

  需要记忆。

  • 数据结构与算法的概念
  • 线性表(顺序表、链表、栈、队列)
  • 数组与矩阵
  • 树与二叉树
  • 查找(二分查找、哈希)

11.1.2 邻接链条表示法

  首先把每个顶点的邻接顶点用链表表示出来,然后用一个一维数组来顺序存储上面每个链表的头指针。

第九章——数据结构与算法

前言:
   计算机第九章节主要知识点。

1 知识点介绍

  • 数据结构与算法概念
  • 线性表
  • 数组与矩阵
  • 树与二叉树
  • 查找

2 数据结构定义

  • 数据结构
    • 数据逻辑结构:指数据元素之间的管理。
      • 线性结构:一对一关系
      • 非线性结构:一对多,多对多关系
    • 数据物理结构:数据在物理设备上具体如何存储。

3 算法概念

  算法的5个重要特征

  • 又穷性:执行有穷步之后结束,且每一步都可在有穷时间内完成。
  • 确定性:算法中每一条指令都必须由确切的含义,不能含糊不清。
  • 输入(>= 0)
  • 输出(>= 1)
  • 有效性(可行性):算法的每个步骤都能有效执行并能在执行有限此后得到确定的结果,例如a = 0,b / a就无效。

4 伪代码

  伪代码是一种算法描述语言,介于自然语言与编程语言之间,不用拘泥于具体的实现。

Pseudocode.png

5 线性表

5.1 线性表的概念

  常见线性表的两种存储结构。

  • 顺序存储结构(如:顺序表)
  • 链式存储结构(如:链表)

  逻辑上连续,物理上不一定连续。

  • 顺序表:随机存取。查询和修改容易,元素插入和删除麻烦,需要移动元素。
  • 链表
    • 单链表
    • 循环链表
    • 双向链表

LinearList.png

5.2 链表基本操作

  • 单链表删除结点
  • 单链表插入结点
  • 双向链表删除结点
  • 双向链表插入结点

LinkedList.png

5.3 例题

  1. 以下关于单链表存储结构特征的叙述中,不正确的是(D)。

A. 表中结点所占用存储空间的地址不必是连续的
B. 在表中任意位置进行插入和删除操作都不用移动元素
C. 所需空间与结点个数成正比
D. 可随机访问表中的任一结点

5.4 队列和栈

  元素按照a、b、c的次序进入栈,请尝试写出其所有可能的出栈序。

QueueAndStack.png

5.5 例题

  1. 令序列X、Y、Z的每个元素都按顺序进栈,且每个元素进栈和出栈仅一次,则不可能得到的出栈序列是(C)。

A. XYZ
B. XZY
C. ZXY
D. YZX

6 广义表

  广义表示n个表元素组成的有限序列,是线性表的推广,通常用递归的形式进行定义,记作: $LS = (a_0, a_1, …, a_n)$

注:其中LS是表名, $a_i$ 是表元素,它可以是表(称做子表),也可以是数据元素(称为原子)。其中n是广义表的长度(也就是最外层包含的元素个数),n = 0的广义表为空表;而递归定义的重数就是广义表的深度,直观地说,就是定义中所含括号的重数(原子的深度为0,空表的深度为1)。

例,有广义表LS1 = (a, (b, c), (d, e)),其长度为?深度为?
答案:长度为3,深度为2。

7 串

  串是仅由字符构成的有限序列,是取值范围受限的线性表,一般记为 S = ‘a1a2…an’,其中S是串名,单引号括起来的字符序列是串值。

8 数组

  二维数组分按行存储和按列存储。c/c++的多维数组是按行、连续存储逇。FORTRAN语言,Matlab中,数组按列优先顺序存储。

数组类型 存储地址计算
一维数组a[n] a[i]的存储地址为:a + i * len
二维数组a[m][n] a[i][j]的存储地址(按行存储)为:a + (i * n + j) * len
a[i][j]存储地址(按列存储)为:a + (j * m + i) * len

8.1 例题

  1. 数组a[1 … n, 1 … m](n > 1, m > 1)中的元素以行为主序存放,每个元素占用1个存储伟,则数组元素a[i, j] $(1 \leq i \leq n, 1 \leq j \leq m)$ 相对于数组空间首地址的偏移量为(A)

A. (i - 1) * m + j - 1
B. (i - 1) * n + j - 1
C. (j - 1) * m + i - 1
D. (j - 1) * n + i - 1

  1. 若二维数组arr[1 … M, 1 … N]的首地址为base,数组元素按列存储且每个元素占用K个存储单元,则元素arr[i, j]在该数组空间的地址为()。

A. base + ((i - 1) * M + j - 1) * K
B. base + ((i - 1) * N + j - 1) * K
C. base + ((j - 1) * M + i - 1) * K
D. base + ((j - 1) * N + i - 1) * K

9 树与二叉树

  • 结点的度
  • 树的高度
  • 叶子结点
  • 分支结点
  • 内部结点
  • 父结点
  • 子结点
  • 兄弟结点
  • 层次

BinaryTree.png

BinaryTree_1.png

  二叉树的重要特征。

  • 在二叉树的第i层上最多有 $2^{i - 1}$ 个结点 $(i \geq 1)$ ;
  • 深度为k的二叉树最多有 $2^k - 1$ 个结点 $(k \geq 1)$ ;
  • 对任何一颗二叉树,如果其叶子结点数为 $n_0$ ,度为2的结点数为 $n_2$ ,则 $n_0 = n_2 + 1$ 。
  • 如果对一颗有n个结点的完全二叉树的结点按层序编号(从第1层到 $log_2n + 1$ 层,每层从左到右),则对任一结点i $(i \geq i \geq n)$ ,有
    • 如果i = 1,则结点i无父结点,是二叉树的根;如果i > 1,则父结点是i / 2;
    • 如果2i > n,则结点i为叶子结点,无左子结点;否则,其左子结点是结点2i;
    • 如果2i + 1 > n,则结点i无右叶子结点,否则,其右子结点是结点2i + 1;

9.1 二叉树遍历

  • 前序遍历(根左右)
  • 中序遍历(左根右)
  • 后序遍历(左右根)
  • 层序遍历

  前序遍历:12457836,中序遍历:42785136,后序遍历:48752631,层次遍历:12345678。

TraversalOfBinaryTree.png

10 堆

  堆是计算机科学中的一类特殊的数据结构的统称。堆通常是一个可以被看做一颗完全二叉树的数组对象。
  若n个元素的序列 ${a_1, a_2 … a_n}$ 满足

Formula.png

  则分别称该序列 ${a_1, a_2, … a_n}$ 为小根堆和大根堆。
  从堆的定义可以看出,对实质是满足如下性质的完全二叉树:

  • 二叉树中任一非叶子结点均小于(大于)它的孩子结点。
  • 堆总是一颗完全二叉树。

  例如:下面序列为堆,对应的完全二叉树分别为。

1
2
98 77 35 62 55 14 35 48
14 48 35 62 55 98 35 77

Heap.png

10.1 例题

  1. 对于n个元素的关键字序列 ${k_1, k_2, … k_n}$ ,当且仅当满足关系 $k_j \leq k_{2i}$ 且 $k_i \leq k_{2i + 1}$ {i = 1.2…[n/2]}时称其为小根堆(小顶堆)。以下序列中,(D)不是小根堆。

A. 16, 25, 40, 55, 30, 50, 45
B. 16, 40, 25, 50, 45, 30, 55
C. 16, 25, 39, 41, 45, 43, 50
D. 16, 40, 25, 53, 39, 55, 45

11 图

11.1 图的存储

11.1.1 邻接矩阵表示法

  邻接矩阵表示法用一个n阶方阵R来存放图中各结点的关联信息,其矩阵元素 $R_{ij}$ 定义为。
  为无向图。表示稀疏矩阵时空间浪费大。

FigureOfTheStorage.png

11.1.2 邻接链条表示法

  首先把每个顶点的邻接顶点用链表表示出来,然后用一个一维数组来顺序存储上面每个链表的头指针。

ListFigure.png

11.2 例题

  1. 某有向图G的邻接表如下图所示,可看出该图中存在弧 $<v_2, V3>$ 而不存在从顶点 $V_1$ 出发的弧。以下关于图G的叙述中,错误的是()。

A. G中存在回路
B. G中每个顶点的入度为1
C. G的邻接矩阵是对称的
D. 不存在弧 $V_3, V_1>

ex1.png

11.3 图的遍历

GraphTraversal.png

12 查找算法

  • 五大查找
    • 顺序表查找
      • 顺序查找
      • 二分查找
      • 索引顺序查找
    • 树表查找
      • 二叉排序树
    • 散列表查找
      • 哈希查找

12.1 顺序查找

  顺序查找的过程:将待查找的关键字可key的元素从头到尾与表中元素进行比较,如果中间存在关键字为key的元素,则返回成功,否则返回失败。顺序查找主要针对少量的、无规则的数据。

1
4 7 10 18 30 2 46 24 15

12.2 二分查找

  二分法查找的基本过程是:(设R[low, …, high]是当前的查找区)

  • 确定该区间的中间位置:mid = [(low + high) / 2],向下取整。
  • 将待查的k值与R[mid].key比较,若相等,则查找成功并返回此位置,否则需确定新的查找区间,继续二分查找,具体方法如下。
    • 若R[mid].key > k,则由表的有序性可知R[mid, …, n].key均大于k,因此若表中存在关键字等于k的结点,则该结点必定是在位置mid左边的子表R[low, …, mid -1]中。因此,新的查找区间是左子表R[low, …, high],其中high = mid - 1.
    • 若R[mid].key < k,则要查找的k必在mid的右子表R[mid + 1, …, high]中,即新的查找区间是右子表R[low, …, high],其中low = mid + 1。
    • 若R[mid].key = k,则查找成功,算法结束。
  • 下次查找是针对新的查找区间进行,重复步骤(1)和(2)。
  • 在查找过程中,low逐步增加,而high逐步减少。如果high < low,则查找失败,算法结束。

12.3 二叉查找树(排序)

  二叉查找树的定义:二叉排序树或者是一颗空树,或者是具有如下特性的二叉树。

  • 若它的左子树不空,则左子树上所有节点的值均小于根节点的值。
  • 若它的有子树不空,则右子树上所有节点的值均大于根节点的值。
  • 它的左、右子树也都分别是二叉排序树。

  对二叉查找树进行中序遍历,即可得到有序的序列。

BinarySortTree.png

  查找过程:二叉查找(排序)树是先对待查找的数据进行生成树,确保数的左分支值小于右分支的值,然后再去和每个结点的父结点比较大小,查找最合适的范围。这个算法的查找效率很高,但是如果使用这种查找方法要首先创建数。
  具体步骤为。

  • 若查找的关键字等于根节点的关键字,查找成功。
  • 若查找的关键字小于根节点的关键字,递归查找左子树。
  • 若查找的关键字大于根节点的关键字,递归查找右子树。
  • 若子树为空,则查找不成功。

12.4 二叉平衡树

  定义:又称AVL树。它或者是一颗空树,或者是具有下列性质的二叉树:它的左子树或右子树都是平衡二叉树,且左子树和右子树的深度之差的绝对值不超过1。

  平衡因子。
  二叉树上任一结点的左子树深度减去右子树深度的差值,称为此结点的平衡因子。

AVL.png

12.5 例题

  1. 关于二叉排序树的说法,错误的是(C)。

A. 对于二叉排序树进行中序遍历,必定得到结点关键字的有序序列
B. 依据关键字无序的序列建立二叉排序,也可能构造出单支树
C. 若构造二叉排序树时进行平衡化处理,则根节点的左子树结点数与右子树结点数的差值一定不超过1
D. 若构造二叉排序树时进行平衡化处理,则根结点的左子树高度与右子树高度的差值一定不超过1

12.5 哈夫曼树

  定义:给定N个权值作为N个叶子节点,构造一颗二叉树,若该树的带权路径长度达到最小,称这样的二叉树为最优二叉树,也称为哈夫曼树。哈夫曼树是带权路径长度最短的数,权值较大的结点离根较近。
  一般可以按下面步骤构建。

  • 将所有左、右子树都为空的作为根节点。
  • 在森林中选取两棵根节点的权值最小的数作为一棵新树的左、右子树,且置新树的附加根节点的权值为其左、右子树上根结点的权值之和。
  • 从森林中删除这两棵树,同时把新树加入到森林中。
  • 重复2、3步骤,直到森林中只有一棵树为止,此树便是哈夫曼树。

HuffmanTree.png

HuffmanTree_.png

  应用场景:对字符集中的字符进行编码和译码。

12.6 例题

  1. 以下有关哈夫曼树的说法中,错误的是(C)。

A. 哈夫曼树又被称为最优二叉树
B. 哈夫曼树是一种带权路径长度最短的树
C. 具有n个叶子结点的权值为 $W_1, W_2, …, W_n$ 的最优二叉树是唯一的
D. 哈夫曼树可以用来进行通信电文的编码和解码

13 B树

  B树,有时又写为B-树或B_树(其中的“-”或者“_”只是连字符,并不读作“B减树”)。一颗m阶的B树是一颗平衡的多路搜索树,它或者是空树,或者是满足下列性质的树。

  1. 树中每个结点至多有m棵子树。
  2. 若根结点不是叶子结点,则至少有两棵子树。
  3. 除根之外的所有非终端结点至少有[m/2](向上取整)棵子树。
  4. 所有的非终端结点中包含下列信息数据:

   $(n, A_0, K_1, A_1, K_2, A_2, …, K_n, A_n)$ ,其中: $K_i (i = 1, 2, …, n)$ 为关键字,且 $K_i < K_{i + 1}$ (i = 1, …, n - 1)。
   $A_i (i = 0, …, n)$ 为指向子树根结点的指针,且指针 $A_{i -1}$ 所指子树中所有结点的关键字均小于 $K_i(i = 1, …, n)$ , $A_n$ 所指子树中所有结点的关键字均大于 $K_n$ , $n ([m / 2] - 1 \leq n \leq m - 1)$ 为关键字的个数(或n + 1为子树个数)。其中[m / 2]表示向上取整。

  1. 所有的叶子结点都出现在同一层次上,并且不带信息(可以看作是外部结点或查找失败的结点,实际上这些结点不存在,指向这些结点的指针为空)。

BTree.png

14 B+树

  是B-树的一种变型,一个m阶的B+树具有如下几个特征。

  • 每个叶子结点中含有n个关键字和n个指向记录的指针,并且所有叶子节点彼此相链接构成一个有序链表,其头指针指向含最小关键字的节点。
  • 每个非叶子节点中的关键字 $K_i$ 即为其相应指针 $A_i$ 所指子树中关键字的最大值。
  • 所有叶子节点都处在统一层次上,每个叶子节点中关键字的个数均介于[m / 2](向上取整)和m之间。

B+Tree.png

15 散列表

  散列表构造的基本思想是:已知关键字集合U,最大关键字为m,设计一个函数Hash,它以关键字为自变量,关键字的存储地址为因变量,将关键字映射到一个有限的、地址连续的区间T[0 .. n - 1](n << m)中,这个区间就称为散列表,散列查找中使用的转换函数称为散列函数。

  例:假设有一个大小为7的表,现在要将(13, 18, 19s, 50, 20, 27)散列到表中。

  • 选择散列函数,例如使用hash(x) = x % 7作为散列函数。
  • 计算数据散列值,并放到合适的位置。
哈希地址 0 1 2 3 4 5 6
关键码 50 18 19 13

  地址重复时出现冲突,即散列冲突。

15.1 解决散列冲突

  • 链地址法(拉链法)
  • 开放地址法

   $H_i = (Hash(key) + d_i) % m$ i = 1, 2, …, k $(k \leq m - 1)$
  其中Hash(key)为哈希函数,m为哈希表的表长,di为增量序列。常见的增量序列有三种。

  • di = 1, 2, 3, …, m - 1,称为线性他侧再散列。
  • di = $1^2, {-1}^2, 2^2, {-2}^2, 3^3, …, ±k^2$ ,称为二次探测再散列。
  • di = 伪随机数列,称为随机探测再散列,如:di = Random(key)。

15.2 例题

  1. 用哈希表存储元素时,需要进行冲突(碰撞)处理,冲突是指(B)。

A. 关键字被依次映射到地址编号连续的存储位置
B. 关键字不同的元素被映射到相同的存储位置
C. 关键字相同的元素被映射到不同的存储位置
D. 关键字被映射到哈希表之外的位置

16 总结

  考查形式主要是概念区分以及部分计算题型,主要出现在上午的选择题当中。

  • 树的遍历
  • 图的遍历
  • 典型的时间复杂度

  需要记忆。

  • 数据结构与算法的概念
  • 线性表(顺序表、链表、栈、队列)
  • 数组与矩阵
  • 树与二叉树
  • 查找(二分查找、哈希)

11.2 例题

  1. 某有向图G的邻接表如下图所示,可看出该图中存在弧 $<v_2, V3>$ 而不存在从顶点 $V_1$ 出发的弧。以下关于图G的叙述中,错误的是()。

A. G中存在回路
B. G中每个顶点的入度为1
C. G的邻接矩阵是对称的
D. 不存在弧 $V_3, V_1>

第九章——数据结构与算法

前言:
   计算机第九章节主要知识点。

1 知识点介绍

  • 数据结构与算法概念
  • 线性表
  • 数组与矩阵
  • 树与二叉树
  • 查找

2 数据结构定义

  • 数据结构
    • 数据逻辑结构:指数据元素之间的管理。
      • 线性结构:一对一关系
      • 非线性结构:一对多,多对多关系
    • 数据物理结构:数据在物理设备上具体如何存储。

3 算法概念

  算法的5个重要特征

  • 又穷性:执行有穷步之后结束,且每一步都可在有穷时间内完成。
  • 确定性:算法中每一条指令都必须由确切的含义,不能含糊不清。
  • 输入(>= 0)
  • 输出(>= 1)
  • 有效性(可行性):算法的每个步骤都能有效执行并能在执行有限此后得到确定的结果,例如a = 0,b / a就无效。

4 伪代码

  伪代码是一种算法描述语言,介于自然语言与编程语言之间,不用拘泥于具体的实现。

Pseudocode.png

5 线性表

5.1 线性表的概念

  常见线性表的两种存储结构。

  • 顺序存储结构(如:顺序表)
  • 链式存储结构(如:链表)

  逻辑上连续,物理上不一定连续。

  • 顺序表:随机存取。查询和修改容易,元素插入和删除麻烦,需要移动元素。
  • 链表
    • 单链表
    • 循环链表
    • 双向链表

LinearList.png

5.2 链表基本操作

  • 单链表删除结点
  • 单链表插入结点
  • 双向链表删除结点
  • 双向链表插入结点

LinkedList.png

5.3 例题

  1. 以下关于单链表存储结构特征的叙述中,不正确的是(D)。

A. 表中结点所占用存储空间的地址不必是连续的
B. 在表中任意位置进行插入和删除操作都不用移动元素
C. 所需空间与结点个数成正比
D. 可随机访问表中的任一结点

5.4 队列和栈

  元素按照a、b、c的次序进入栈,请尝试写出其所有可能的出栈序。

QueueAndStack.png

5.5 例题

  1. 令序列X、Y、Z的每个元素都按顺序进栈,且每个元素进栈和出栈仅一次,则不可能得到的出栈序列是(C)。

A. XYZ
B. XZY
C. ZXY
D. YZX

6 广义表

  广义表示n个表元素组成的有限序列,是线性表的推广,通常用递归的形式进行定义,记作: $LS = (a_0, a_1, …, a_n)$

注:其中LS是表名, $a_i$ 是表元素,它可以是表(称做子表),也可以是数据元素(称为原子)。其中n是广义表的长度(也就是最外层包含的元素个数),n = 0的广义表为空表;而递归定义的重数就是广义表的深度,直观地说,就是定义中所含括号的重数(原子的深度为0,空表的深度为1)。

例,有广义表LS1 = (a, (b, c), (d, e)),其长度为?深度为?
答案:长度为3,深度为2。

7 串

  串是仅由字符构成的有限序列,是取值范围受限的线性表,一般记为 S = ‘a1a2…an’,其中S是串名,单引号括起来的字符序列是串值。

8 数组

  二维数组分按行存储和按列存储。c/c++的多维数组是按行、连续存储逇。FORTRAN语言,Matlab中,数组按列优先顺序存储。

数组类型 存储地址计算
一维数组a[n] a[i]的存储地址为:a + i * len
二维数组a[m][n] a[i][j]的存储地址(按行存储)为:a + (i * n + j) * len
a[i][j]存储地址(按列存储)为:a + (j * m + i) * len

8.1 例题

  1. 数组a[1 … n, 1 … m](n > 1, m > 1)中的元素以行为主序存放,每个元素占用1个存储伟,则数组元素a[i, j] $(1 \leq i \leq n, 1 \leq j \leq m)$ 相对于数组空间首地址的偏移量为(A)

A. (i - 1) * m + j - 1
B. (i - 1) * n + j - 1
C. (j - 1) * m + i - 1
D. (j - 1) * n + i - 1

  1. 若二维数组arr[1 … M, 1 … N]的首地址为base,数组元素按列存储且每个元素占用K个存储单元,则元素arr[i, j]在该数组空间的地址为()。

A. base + ((i - 1) * M + j - 1) * K
B. base + ((i - 1) * N + j - 1) * K
C. base + ((j - 1) * M + i - 1) * K
D. base + ((j - 1) * N + i - 1) * K

9 树与二叉树

  • 结点的度
  • 树的高度
  • 叶子结点
  • 分支结点
  • 内部结点
  • 父结点
  • 子结点
  • 兄弟结点
  • 层次

BinaryTree.png

BinaryTree_1.png

  二叉树的重要特征。

  • 在二叉树的第i层上最多有 $2^{i - 1}$ 个结点 $(i \geq 1)$ ;
  • 深度为k的二叉树最多有 $2^k - 1$ 个结点 $(k \geq 1)$ ;
  • 对任何一颗二叉树,如果其叶子结点数为 $n_0$ ,度为2的结点数为 $n_2$ ,则 $n_0 = n_2 + 1$ 。
  • 如果对一颗有n个结点的完全二叉树的结点按层序编号(从第1层到 $log_2n + 1$ 层,每层从左到右),则对任一结点i $(i \geq i \geq n)$ ,有
    • 如果i = 1,则结点i无父结点,是二叉树的根;如果i > 1,则父结点是i / 2;
    • 如果2i > n,则结点i为叶子结点,无左子结点;否则,其左子结点是结点2i;
    • 如果2i + 1 > n,则结点i无右叶子结点,否则,其右子结点是结点2i + 1;

9.1 二叉树遍历

  • 前序遍历(根左右)
  • 中序遍历(左根右)
  • 后序遍历(左右根)
  • 层序遍历

  前序遍历:12457836,中序遍历:42785136,后序遍历:48752631,层次遍历:12345678。

TraversalOfBinaryTree.png

10 堆

  堆是计算机科学中的一类特殊的数据结构的统称。堆通常是一个可以被看做一颗完全二叉树的数组对象。
  若n个元素的序列 ${a_1, a_2 … a_n}$ 满足

Formula.png

  则分别称该序列 ${a_1, a_2, … a_n}$ 为小根堆和大根堆。
  从堆的定义可以看出,对实质是满足如下性质的完全二叉树:

  • 二叉树中任一非叶子结点均小于(大于)它的孩子结点。
  • 堆总是一颗完全二叉树。

  例如:下面序列为堆,对应的完全二叉树分别为。

1
2
98 77 35 62 55 14 35 48
14 48 35 62 55 98 35 77

Heap.png

10.1 例题

  1. 对于n个元素的关键字序列 ${k_1, k_2, … k_n}$ ,当且仅当满足关系 $k_j \leq k_{2i}$ 且 $k_i \leq k_{2i + 1}$ {i = 1.2…[n/2]}时称其为小根堆(小顶堆)。以下序列中,(D)不是小根堆。

A. 16, 25, 40, 55, 30, 50, 45
B. 16, 40, 25, 50, 45, 30, 55
C. 16, 25, 39, 41, 45, 43, 50
D. 16, 40, 25, 53, 39, 55, 45

11 图

11.1 图的存储

11.1.1 邻接矩阵表示法

  邻接矩阵表示法用一个n阶方阵R来存放图中各结点的关联信息,其矩阵元素 $R_{ij}$ 定义为。
  为无向图。表示稀疏矩阵时空间浪费大。

FigureOfTheStorage.png

11.1.2 邻接链条表示法

  首先把每个顶点的邻接顶点用链表表示出来,然后用一个一维数组来顺序存储上面每个链表的头指针。

ListFigure.png

11.2 例题

  1. 某有向图G的邻接表如下图所示,可看出该图中存在弧 $<v_2, V3>$ 而不存在从顶点 $V_1$ 出发的弧。以下关于图G的叙述中,错误的是()。

A. G中存在回路
B. G中每个顶点的入度为1
C. G的邻接矩阵是对称的
D. 不存在弧 $V_3, V_1>

ex1.png

11.3 图的遍历

GraphTraversal.png

12 查找算法

  • 五大查找
    • 顺序表查找
      • 顺序查找
      • 二分查找
      • 索引顺序查找
    • 树表查找
      • 二叉排序树
    • 散列表查找
      • 哈希查找

12.1 顺序查找

  顺序查找的过程:将待查找的关键字可key的元素从头到尾与表中元素进行比较,如果中间存在关键字为key的元素,则返回成功,否则返回失败。顺序查找主要针对少量的、无规则的数据。

1
4 7 10 18 30 2 46 24 15

12.2 二分查找

  二分法查找的基本过程是:(设R[low, …, high]是当前的查找区)

  • 确定该区间的中间位置:mid = [(low + high) / 2],向下取整。
  • 将待查的k值与R[mid].key比较,若相等,则查找成功并返回此位置,否则需确定新的查找区间,继续二分查找,具体方法如下。
    • 若R[mid].key > k,则由表的有序性可知R[mid, …, n].key均大于k,因此若表中存在关键字等于k的结点,则该结点必定是在位置mid左边的子表R[low, …, mid -1]中。因此,新的查找区间是左子表R[low, …, high],其中high = mid - 1.
    • 若R[mid].key < k,则要查找的k必在mid的右子表R[mid + 1, …, high]中,即新的查找区间是右子表R[low, …, high],其中low = mid + 1。
    • 若R[mid].key = k,则查找成功,算法结束。
  • 下次查找是针对新的查找区间进行,重复步骤(1)和(2)。
  • 在查找过程中,low逐步增加,而high逐步减少。如果high < low,则查找失败,算法结束。

12.3 二叉查找树(排序)

  二叉查找树的定义:二叉排序树或者是一颗空树,或者是具有如下特性的二叉树。

  • 若它的左子树不空,则左子树上所有节点的值均小于根节点的值。
  • 若它的有子树不空,则右子树上所有节点的值均大于根节点的值。
  • 它的左、右子树也都分别是二叉排序树。

  对二叉查找树进行中序遍历,即可得到有序的序列。

BinarySortTree.png

  查找过程:二叉查找(排序)树是先对待查找的数据进行生成树,确保数的左分支值小于右分支的值,然后再去和每个结点的父结点比较大小,查找最合适的范围。这个算法的查找效率很高,但是如果使用这种查找方法要首先创建数。
  具体步骤为。

  • 若查找的关键字等于根节点的关键字,查找成功。
  • 若查找的关键字小于根节点的关键字,递归查找左子树。
  • 若查找的关键字大于根节点的关键字,递归查找右子树。
  • 若子树为空,则查找不成功。

12.4 二叉平衡树

  定义:又称AVL树。它或者是一颗空树,或者是具有下列性质的二叉树:它的左子树或右子树都是平衡二叉树,且左子树和右子树的深度之差的绝对值不超过1。

  平衡因子。
  二叉树上任一结点的左子树深度减去右子树深度的差值,称为此结点的平衡因子。

AVL.png

12.5 例题

  1. 关于二叉排序树的说法,错误的是(C)。

A. 对于二叉排序树进行中序遍历,必定得到结点关键字的有序序列
B. 依据关键字无序的序列建立二叉排序,也可能构造出单支树
C. 若构造二叉排序树时进行平衡化处理,则根节点的左子树结点数与右子树结点数的差值一定不超过1
D. 若构造二叉排序树时进行平衡化处理,则根结点的左子树高度与右子树高度的差值一定不超过1

12.5 哈夫曼树

  定义:给定N个权值作为N个叶子节点,构造一颗二叉树,若该树的带权路径长度达到最小,称这样的二叉树为最优二叉树,也称为哈夫曼树。哈夫曼树是带权路径长度最短的数,权值较大的结点离根较近。
  一般可以按下面步骤构建。

  • 将所有左、右子树都为空的作为根节点。
  • 在森林中选取两棵根节点的权值最小的数作为一棵新树的左、右子树,且置新树的附加根节点的权值为其左、右子树上根结点的权值之和。
  • 从森林中删除这两棵树,同时把新树加入到森林中。
  • 重复2、3步骤,直到森林中只有一棵树为止,此树便是哈夫曼树。

HuffmanTree.png

HuffmanTree_.png

  应用场景:对字符集中的字符进行编码和译码。

12.6 例题

  1. 以下有关哈夫曼树的说法中,错误的是(C)。

A. 哈夫曼树又被称为最优二叉树
B. 哈夫曼树是一种带权路径长度最短的树
C. 具有n个叶子结点的权值为 $W_1, W_2, …, W_n$ 的最优二叉树是唯一的
D. 哈夫曼树可以用来进行通信电文的编码和解码

13 B树

  B树,有时又写为B-树或B_树(其中的“-”或者“_”只是连字符,并不读作“B减树”)。一颗m阶的B树是一颗平衡的多路搜索树,它或者是空树,或者是满足下列性质的树。

  1. 树中每个结点至多有m棵子树。
  2. 若根结点不是叶子结点,则至少有两棵子树。
  3. 除根之外的所有非终端结点至少有[m/2](向上取整)棵子树。
  4. 所有的非终端结点中包含下列信息数据:

   $(n, A_0, K_1, A_1, K_2, A_2, …, K_n, A_n)$ ,其中: $K_i (i = 1, 2, …, n)$ 为关键字,且 $K_i < K_{i + 1}$ (i = 1, …, n - 1)。
   $A_i (i = 0, …, n)$ 为指向子树根结点的指针,且指针 $A_{i -1}$ 所指子树中所有结点的关键字均小于 $K_i(i = 1, …, n)$ , $A_n$ 所指子树中所有结点的关键字均大于 $K_n$ , $n ([m / 2] - 1 \leq n \leq m - 1)$ 为关键字的个数(或n + 1为子树个数)。其中[m / 2]表示向上取整。

  1. 所有的叶子结点都出现在同一层次上,并且不带信息(可以看作是外部结点或查找失败的结点,实际上这些结点不存在,指向这些结点的指针为空)。

BTree.png

14 B+树

  是B-树的一种变型,一个m阶的B+树具有如下几个特征。

  • 每个叶子结点中含有n个关键字和n个指向记录的指针,并且所有叶子节点彼此相链接构成一个有序链表,其头指针指向含最小关键字的节点。
  • 每个非叶子节点中的关键字 $K_i$ 即为其相应指针 $A_i$ 所指子树中关键字的最大值。
  • 所有叶子节点都处在统一层次上,每个叶子节点中关键字的个数均介于[m / 2](向上取整)和m之间。

B+Tree.png

15 散列表

  散列表构造的基本思想是:已知关键字集合U,最大关键字为m,设计一个函数Hash,它以关键字为自变量,关键字的存储地址为因变量,将关键字映射到一个有限的、地址连续的区间T[0 .. n - 1](n << m)中,这个区间就称为散列表,散列查找中使用的转换函数称为散列函数。

  例:假设有一个大小为7的表,现在要将(13, 18, 19s, 50, 20, 27)散列到表中。

  • 选择散列函数,例如使用hash(x) = x % 7作为散列函数。
  • 计算数据散列值,并放到合适的位置。
哈希地址 0 1 2 3 4 5 6
关键码 50 18 19 13

  地址重复时出现冲突,即散列冲突。

15.1 解决散列冲突

  • 链地址法(拉链法)
  • 开放地址法

   $H_i = (Hash(key) + d_i) % m$ i = 1, 2, …, k $(k \leq m - 1)$
  其中Hash(key)为哈希函数,m为哈希表的表长,di为增量序列。常见的增量序列有三种。

  • di = 1, 2, 3, …, m - 1,称为线性他侧再散列。
  • di = $1^2, {-1}^2, 2^2, {-2}^2, 3^3, …, ±k^2$ ,称为二次探测再散列。
  • di = 伪随机数列,称为随机探测再散列,如:di = Random(key)。

15.2 例题

  1. 用哈希表存储元素时,需要进行冲突(碰撞)处理,冲突是指(B)。

A. 关键字被依次映射到地址编号连续的存储位置
B. 关键字不同的元素被映射到相同的存储位置
C. 关键字相同的元素被映射到不同的存储位置
D. 关键字被映射到哈希表之外的位置

16 总结

  考查形式主要是概念区分以及部分计算题型,主要出现在上午的选择题当中。

  • 树的遍历
  • 图的遍历
  • 典型的时间复杂度

  需要记忆。

  • 数据结构与算法的概念
  • 线性表(顺序表、链表、栈、队列)
  • 数组与矩阵
  • 树与二叉树
  • 查找(二分查找、哈希)

11.3 图的遍历

第九章——数据结构与算法

前言:
   计算机第九章节主要知识点。

1 知识点介绍

  • 数据结构与算法概念
  • 线性表
  • 数组与矩阵
  • 树与二叉树
  • 查找

2 数据结构定义

  • 数据结构
    • 数据逻辑结构:指数据元素之间的管理。
      • 线性结构:一对一关系
      • 非线性结构:一对多,多对多关系
    • 数据物理结构:数据在物理设备上具体如何存储。

3 算法概念

  算法的5个重要特征

  • 又穷性:执行有穷步之后结束,且每一步都可在有穷时间内完成。
  • 确定性:算法中每一条指令都必须由确切的含义,不能含糊不清。
  • 输入(>= 0)
  • 输出(>= 1)
  • 有效性(可行性):算法的每个步骤都能有效执行并能在执行有限此后得到确定的结果,例如a = 0,b / a就无效。

4 伪代码

  伪代码是一种算法描述语言,介于自然语言与编程语言之间,不用拘泥于具体的实现。

Pseudocode.png

5 线性表

5.1 线性表的概念

  常见线性表的两种存储结构。

  • 顺序存储结构(如:顺序表)
  • 链式存储结构(如:链表)

  逻辑上连续,物理上不一定连续。

  • 顺序表:随机存取。查询和修改容易,元素插入和删除麻烦,需要移动元素。
  • 链表
    • 单链表
    • 循环链表
    • 双向链表

LinearList.png

5.2 链表基本操作

  • 单链表删除结点
  • 单链表插入结点
  • 双向链表删除结点
  • 双向链表插入结点

LinkedList.png

5.3 例题

  1. 以下关于单链表存储结构特征的叙述中,不正确的是(D)。

A. 表中结点所占用存储空间的地址不必是连续的
B. 在表中任意位置进行插入和删除操作都不用移动元素
C. 所需空间与结点个数成正比
D. 可随机访问表中的任一结点

5.4 队列和栈

  元素按照a、b、c的次序进入栈,请尝试写出其所有可能的出栈序。

QueueAndStack.png

5.5 例题

  1. 令序列X、Y、Z的每个元素都按顺序进栈,且每个元素进栈和出栈仅一次,则不可能得到的出栈序列是(C)。

A. XYZ
B. XZY
C. ZXY
D. YZX

6 广义表

  广义表示n个表元素组成的有限序列,是线性表的推广,通常用递归的形式进行定义,记作: $LS = (a_0, a_1, …, a_n)$

注:其中LS是表名, $a_i$ 是表元素,它可以是表(称做子表),也可以是数据元素(称为原子)。其中n是广义表的长度(也就是最外层包含的元素个数),n = 0的广义表为空表;而递归定义的重数就是广义表的深度,直观地说,就是定义中所含括号的重数(原子的深度为0,空表的深度为1)。

例,有广义表LS1 = (a, (b, c), (d, e)),其长度为?深度为?
答案:长度为3,深度为2。

7 串

  串是仅由字符构成的有限序列,是取值范围受限的线性表,一般记为 S = ‘a1a2…an’,其中S是串名,单引号括起来的字符序列是串值。

8 数组

  二维数组分按行存储和按列存储。c/c++的多维数组是按行、连续存储逇。FORTRAN语言,Matlab中,数组按列优先顺序存储。

数组类型 存储地址计算
一维数组a[n] a[i]的存储地址为:a + i * len
二维数组a[m][n] a[i][j]的存储地址(按行存储)为:a + (i * n + j) * len
a[i][j]存储地址(按列存储)为:a + (j * m + i) * len

8.1 例题

  1. 数组a[1 … n, 1 … m](n > 1, m > 1)中的元素以行为主序存放,每个元素占用1个存储伟,则数组元素a[i, j] $(1 \leq i \leq n, 1 \leq j \leq m)$ 相对于数组空间首地址的偏移量为(A)

A. (i - 1) * m + j - 1
B. (i - 1) * n + j - 1
C. (j - 1) * m + i - 1
D. (j - 1) * n + i - 1

  1. 若二维数组arr[1 … M, 1 … N]的首地址为base,数组元素按列存储且每个元素占用K个存储单元,则元素arr[i, j]在该数组空间的地址为()。

A. base + ((i - 1) * M + j - 1) * K
B. base + ((i - 1) * N + j - 1) * K
C. base + ((j - 1) * M + i - 1) * K
D. base + ((j - 1) * N + i - 1) * K

9 树与二叉树

  • 结点的度
  • 树的高度
  • 叶子结点
  • 分支结点
  • 内部结点
  • 父结点
  • 子结点
  • 兄弟结点
  • 层次

BinaryTree.png

BinaryTree_1.png

  二叉树的重要特征。

  • 在二叉树的第i层上最多有 $2^{i - 1}$ 个结点 $(i \geq 1)$ ;
  • 深度为k的二叉树最多有 $2^k - 1$ 个结点 $(k \geq 1)$ ;
  • 对任何一颗二叉树,如果其叶子结点数为 $n_0$ ,度为2的结点数为 $n_2$ ,则 $n_0 = n_2 + 1$ 。
  • 如果对一颗有n个结点的完全二叉树的结点按层序编号(从第1层到 $log_2n + 1$ 层,每层从左到右),则对任一结点i $(i \geq i \geq n)$ ,有
    • 如果i = 1,则结点i无父结点,是二叉树的根;如果i > 1,则父结点是i / 2;
    • 如果2i > n,则结点i为叶子结点,无左子结点;否则,其左子结点是结点2i;
    • 如果2i + 1 > n,则结点i无右叶子结点,否则,其右子结点是结点2i + 1;

9.1 二叉树遍历

  • 前序遍历(根左右)
  • 中序遍历(左根右)
  • 后序遍历(左右根)
  • 层序遍历

  前序遍历:12457836,中序遍历:42785136,后序遍历:48752631,层次遍历:12345678。

TraversalOfBinaryTree.png

10 堆

  堆是计算机科学中的一类特殊的数据结构的统称。堆通常是一个可以被看做一颗完全二叉树的数组对象。
  若n个元素的序列 ${a_1, a_2 … a_n}$ 满足

Formula.png

  则分别称该序列 ${a_1, a_2, … a_n}$ 为小根堆和大根堆。
  从堆的定义可以看出,对实质是满足如下性质的完全二叉树:

  • 二叉树中任一非叶子结点均小于(大于)它的孩子结点。
  • 堆总是一颗完全二叉树。

  例如:下面序列为堆,对应的完全二叉树分别为。

1
2
98 77 35 62 55 14 35 48
14 48 35 62 55 98 35 77

Heap.png

10.1 例题

  1. 对于n个元素的关键字序列 ${k_1, k_2, … k_n}$ ,当且仅当满足关系 $k_j \leq k_{2i}$ 且 $k_i \leq k_{2i + 1}$ {i = 1.2…[n/2]}时称其为小根堆(小顶堆)。以下序列中,(D)不是小根堆。

A. 16, 25, 40, 55, 30, 50, 45
B. 16, 40, 25, 50, 45, 30, 55
C. 16, 25, 39, 41, 45, 43, 50
D. 16, 40, 25, 53, 39, 55, 45

11 图

11.1 图的存储

11.1.1 邻接矩阵表示法

  邻接矩阵表示法用一个n阶方阵R来存放图中各结点的关联信息,其矩阵元素 $R_{ij}$ 定义为。
  为无向图。表示稀疏矩阵时空间浪费大。

FigureOfTheStorage.png

11.1.2 邻接链条表示法

  首先把每个顶点的邻接顶点用链表表示出来,然后用一个一维数组来顺序存储上面每个链表的头指针。

ListFigure.png

11.2 例题

  1. 某有向图G的邻接表如下图所示,可看出该图中存在弧 $<v_2, V3>$ 而不存在从顶点 $V_1$ 出发的弧。以下关于图G的叙述中,错误的是()。

A. G中存在回路
B. G中每个顶点的入度为1
C. G的邻接矩阵是对称的
D. 不存在弧 $V_3, V_1>

ex1.png

11.3 图的遍历

GraphTraversal.png

12 查找算法

  • 五大查找
    • 顺序表查找
      • 顺序查找
      • 二分查找
      • 索引顺序查找
    • 树表查找
      • 二叉排序树
    • 散列表查找
      • 哈希查找

12.1 顺序查找

  顺序查找的过程:将待查找的关键字可key的元素从头到尾与表中元素进行比较,如果中间存在关键字为key的元素,则返回成功,否则返回失败。顺序查找主要针对少量的、无规则的数据。

1
4 7 10 18 30 2 46 24 15

12.2 二分查找

  二分法查找的基本过程是:(设R[low, …, high]是当前的查找区)

  • 确定该区间的中间位置:mid = [(low + high) / 2],向下取整。
  • 将待查的k值与R[mid].key比较,若相等,则查找成功并返回此位置,否则需确定新的查找区间,继续二分查找,具体方法如下。
    • 若R[mid].key > k,则由表的有序性可知R[mid, …, n].key均大于k,因此若表中存在关键字等于k的结点,则该结点必定是在位置mid左边的子表R[low, …, mid -1]中。因此,新的查找区间是左子表R[low, …, high],其中high = mid - 1.
    • 若R[mid].key < k,则要查找的k必在mid的右子表R[mid + 1, …, high]中,即新的查找区间是右子表R[low, …, high],其中low = mid + 1。
    • 若R[mid].key = k,则查找成功,算法结束。
  • 下次查找是针对新的查找区间进行,重复步骤(1)和(2)。
  • 在查找过程中,low逐步增加,而high逐步减少。如果high < low,则查找失败,算法结束。

12.3 二叉查找树(排序)

  二叉查找树的定义:二叉排序树或者是一颗空树,或者是具有如下特性的二叉树。

  • 若它的左子树不空,则左子树上所有节点的值均小于根节点的值。
  • 若它的有子树不空,则右子树上所有节点的值均大于根节点的值。
  • 它的左、右子树也都分别是二叉排序树。

  对二叉查找树进行中序遍历,即可得到有序的序列。

BinarySortTree.png

  查找过程:二叉查找(排序)树是先对待查找的数据进行生成树,确保数的左分支值小于右分支的值,然后再去和每个结点的父结点比较大小,查找最合适的范围。这个算法的查找效率很高,但是如果使用这种查找方法要首先创建数。
  具体步骤为。

  • 若查找的关键字等于根节点的关键字,查找成功。
  • 若查找的关键字小于根节点的关键字,递归查找左子树。
  • 若查找的关键字大于根节点的关键字,递归查找右子树。
  • 若子树为空,则查找不成功。

12.4 二叉平衡树

  定义:又称AVL树。它或者是一颗空树,或者是具有下列性质的二叉树:它的左子树或右子树都是平衡二叉树,且左子树和右子树的深度之差的绝对值不超过1。

  平衡因子。
  二叉树上任一结点的左子树深度减去右子树深度的差值,称为此结点的平衡因子。

AVL.png

12.5 例题

  1. 关于二叉排序树的说法,错误的是(C)。

A. 对于二叉排序树进行中序遍历,必定得到结点关键字的有序序列
B. 依据关键字无序的序列建立二叉排序,也可能构造出单支树
C. 若构造二叉排序树时进行平衡化处理,则根节点的左子树结点数与右子树结点数的差值一定不超过1
D. 若构造二叉排序树时进行平衡化处理,则根结点的左子树高度与右子树高度的差值一定不超过1

12.5 哈夫曼树

  定义:给定N个权值作为N个叶子节点,构造一颗二叉树,若该树的带权路径长度达到最小,称这样的二叉树为最优二叉树,也称为哈夫曼树。哈夫曼树是带权路径长度最短的数,权值较大的结点离根较近。
  一般可以按下面步骤构建。

  • 将所有左、右子树都为空的作为根节点。
  • 在森林中选取两棵根节点的权值最小的数作为一棵新树的左、右子树,且置新树的附加根节点的权值为其左、右子树上根结点的权值之和。
  • 从森林中删除这两棵树,同时把新树加入到森林中。
  • 重复2、3步骤,直到森林中只有一棵树为止,此树便是哈夫曼树。

HuffmanTree.png

HuffmanTree_.png

  应用场景:对字符集中的字符进行编码和译码。

12.6 例题

  1. 以下有关哈夫曼树的说法中,错误的是(C)。

A. 哈夫曼树又被称为最优二叉树
B. 哈夫曼树是一种带权路径长度最短的树
C. 具有n个叶子结点的权值为 $W_1, W_2, …, W_n$ 的最优二叉树是唯一的
D. 哈夫曼树可以用来进行通信电文的编码和解码

13 B树

  B树,有时又写为B-树或B_树(其中的“-”或者“_”只是连字符,并不读作“B减树”)。一颗m阶的B树是一颗平衡的多路搜索树,它或者是空树,或者是满足下列性质的树。

  1. 树中每个结点至多有m棵子树。
  2. 若根结点不是叶子结点,则至少有两棵子树。
  3. 除根之外的所有非终端结点至少有[m/2](向上取整)棵子树。
  4. 所有的非终端结点中包含下列信息数据:

   $(n, A_0, K_1, A_1, K_2, A_2, …, K_n, A_n)$ ,其中: $K_i (i = 1, 2, …, n)$ 为关键字,且 $K_i < K_{i + 1}$ (i = 1, …, n - 1)。
   $A_i (i = 0, …, n)$ 为指向子树根结点的指针,且指针 $A_{i -1}$ 所指子树中所有结点的关键字均小于 $K_i(i = 1, …, n)$ , $A_n$ 所指子树中所有结点的关键字均大于 $K_n$ , $n ([m / 2] - 1 \leq n \leq m - 1)$ 为关键字的个数(或n + 1为子树个数)。其中[m / 2]表示向上取整。

  1. 所有的叶子结点都出现在同一层次上,并且不带信息(可以看作是外部结点或查找失败的结点,实际上这些结点不存在,指向这些结点的指针为空)。

BTree.png

14 B+树

  是B-树的一种变型,一个m阶的B+树具有如下几个特征。

  • 每个叶子结点中含有n个关键字和n个指向记录的指针,并且所有叶子节点彼此相链接构成一个有序链表,其头指针指向含最小关键字的节点。
  • 每个非叶子节点中的关键字 $K_i$ 即为其相应指针 $A_i$ 所指子树中关键字的最大值。
  • 所有叶子节点都处在统一层次上,每个叶子节点中关键字的个数均介于[m / 2](向上取整)和m之间。

B+Tree.png

15 散列表

  散列表构造的基本思想是:已知关键字集合U,最大关键字为m,设计一个函数Hash,它以关键字为自变量,关键字的存储地址为因变量,将关键字映射到一个有限的、地址连续的区间T[0 .. n - 1](n << m)中,这个区间就称为散列表,散列查找中使用的转换函数称为散列函数。

  例:假设有一个大小为7的表,现在要将(13, 18, 19s, 50, 20, 27)散列到表中。

  • 选择散列函数,例如使用hash(x) = x % 7作为散列函数。
  • 计算数据散列值,并放到合适的位置。
哈希地址 0 1 2 3 4 5 6
关键码 50 18 19 13

  地址重复时出现冲突,即散列冲突。

15.1 解决散列冲突

  • 链地址法(拉链法)
  • 开放地址法

   $H_i = (Hash(key) + d_i) % m$ i = 1, 2, …, k $(k \leq m - 1)$
  其中Hash(key)为哈希函数,m为哈希表的表长,di为增量序列。常见的增量序列有三种。

  • di = 1, 2, 3, …, m - 1,称为线性他侧再散列。
  • di = $1^2, {-1}^2, 2^2, {-2}^2, 3^3, …, ±k^2$ ,称为二次探测再散列。
  • di = 伪随机数列,称为随机探测再散列,如:di = Random(key)。

15.2 例题

  1. 用哈希表存储元素时,需要进行冲突(碰撞)处理,冲突是指(B)。

A. 关键字被依次映射到地址编号连续的存储位置
B. 关键字不同的元素被映射到相同的存储位置
C. 关键字相同的元素被映射到不同的存储位置
D. 关键字被映射到哈希表之外的位置

16 总结

  考查形式主要是概念区分以及部分计算题型,主要出现在上午的选择题当中。

  • 树的遍历
  • 图的遍历
  • 典型的时间复杂度

  需要记忆。

  • 数据结构与算法的概念
  • 线性表(顺序表、链表、栈、队列)
  • 数组与矩阵
  • 树与二叉树
  • 查找(二分查找、哈希)

12 查找算法

  • 五大查找
    • 顺序表查找
      • 顺序查找
      • 二分查找
      • 索引顺序查找
    • 树表查找
      • 二叉排序树
    • 散列表查找
      • 哈希查找

12.1 顺序查找

  顺序查找的过程:将待查找的关键字可key的元素从头到尾与表中元素进行比较,如果中间存在关键字为key的元素,则返回成功,否则返回失败。顺序查找主要针对少量的、无规则的数据。

1
4 7 10 18 30 2 46 24 15

12.2 二分查找

  二分法查找的基本过程是:(设R[low, …, high]是当前的查找区)

  • 确定该区间的中间位置:mid = [(low + high) / 2],向下取整。
  • 将待查的k值与R[mid].key比较,若相等,则查找成功并返回此位置,否则需确定新的查找区间,继续二分查找,具体方法如下。
    • 若R[mid].key > k,则由表的有序性可知R[mid, …, n].key均大于k,因此若表中存在关键字等于k的结点,则该结点必定是在位置mid左边的子表R[low, …, mid -1]中。因此,新的查找区间是左子表R[low, …, high],其中high = mid - 1.
    • 若R[mid].key < k,则要查找的k必在mid的右子表R[mid + 1, …, high]中,即新的查找区间是右子表R[low, …, high],其中low = mid + 1。
    • 若R[mid].key = k,则查找成功,算法结束。
  • 下次查找是针对新的查找区间进行,重复步骤(1)和(2)。
  • 在查找过程中,low逐步增加,而high逐步减少。如果high < low,则查找失败,算法结束。

12.3 二叉查找树(排序)

  二叉查找树的定义:二叉排序树或者是一颗空树,或者是具有如下特性的二叉树。

  • 若它的左子树不空,则左子树上所有节点的值均小于根节点的值。
  • 若它的有子树不空,则右子树上所有节点的值均大于根节点的值。
  • 它的左、右子树也都分别是二叉排序树。

  对二叉查找树进行中序遍历,即可得到有序的序列。

第九章——数据结构与算法

前言:
   计算机第九章节主要知识点。

1 知识点介绍

  • 数据结构与算法概念
  • 线性表
  • 数组与矩阵
  • 树与二叉树
  • 查找

2 数据结构定义

  • 数据结构
    • 数据逻辑结构:指数据元素之间的管理。
      • 线性结构:一对一关系
      • 非线性结构:一对多,多对多关系
    • 数据物理结构:数据在物理设备上具体如何存储。

3 算法概念

  算法的5个重要特征

  • 又穷性:执行有穷步之后结束,且每一步都可在有穷时间内完成。
  • 确定性:算法中每一条指令都必须由确切的含义,不能含糊不清。
  • 输入(>= 0)
  • 输出(>= 1)
  • 有效性(可行性):算法的每个步骤都能有效执行并能在执行有限此后得到确定的结果,例如a = 0,b / a就无效。

4 伪代码

  伪代码是一种算法描述语言,介于自然语言与编程语言之间,不用拘泥于具体的实现。

Pseudocode.png

5 线性表

5.1 线性表的概念

  常见线性表的两种存储结构。

  • 顺序存储结构(如:顺序表)
  • 链式存储结构(如:链表)

  逻辑上连续,物理上不一定连续。

  • 顺序表:随机存取。查询和修改容易,元素插入和删除麻烦,需要移动元素。
  • 链表
    • 单链表
    • 循环链表
    • 双向链表

LinearList.png

5.2 链表基本操作

  • 单链表删除结点
  • 单链表插入结点
  • 双向链表删除结点
  • 双向链表插入结点

LinkedList.png

5.3 例题

  1. 以下关于单链表存储结构特征的叙述中,不正确的是(D)。

A. 表中结点所占用存储空间的地址不必是连续的
B. 在表中任意位置进行插入和删除操作都不用移动元素
C. 所需空间与结点个数成正比
D. 可随机访问表中的任一结点

5.4 队列和栈

  元素按照a、b、c的次序进入栈,请尝试写出其所有可能的出栈序。

QueueAndStack.png

5.5 例题

  1. 令序列X、Y、Z的每个元素都按顺序进栈,且每个元素进栈和出栈仅一次,则不可能得到的出栈序列是(C)。

A. XYZ
B. XZY
C. ZXY
D. YZX

6 广义表

  广义表示n个表元素组成的有限序列,是线性表的推广,通常用递归的形式进行定义,记作: $LS = (a_0, a_1, …, a_n)$

注:其中LS是表名, $a_i$ 是表元素,它可以是表(称做子表),也可以是数据元素(称为原子)。其中n是广义表的长度(也就是最外层包含的元素个数),n = 0的广义表为空表;而递归定义的重数就是广义表的深度,直观地说,就是定义中所含括号的重数(原子的深度为0,空表的深度为1)。

例,有广义表LS1 = (a, (b, c), (d, e)),其长度为?深度为?
答案:长度为3,深度为2。

7 串

  串是仅由字符构成的有限序列,是取值范围受限的线性表,一般记为 S = ‘a1a2…an’,其中S是串名,单引号括起来的字符序列是串值。

8 数组

  二维数组分按行存储和按列存储。c/c++的多维数组是按行、连续存储逇。FORTRAN语言,Matlab中,数组按列优先顺序存储。

数组类型 存储地址计算
一维数组a[n] a[i]的存储地址为:a + i * len
二维数组a[m][n] a[i][j]的存储地址(按行存储)为:a + (i * n + j) * len
a[i][j]存储地址(按列存储)为:a + (j * m + i) * len

8.1 例题

  1. 数组a[1 … n, 1 … m](n > 1, m > 1)中的元素以行为主序存放,每个元素占用1个存储伟,则数组元素a[i, j] $(1 \leq i \leq n, 1 \leq j \leq m)$ 相对于数组空间首地址的偏移量为(A)

A. (i - 1) * m + j - 1
B. (i - 1) * n + j - 1
C. (j - 1) * m + i - 1
D. (j - 1) * n + i - 1

  1. 若二维数组arr[1 … M, 1 … N]的首地址为base,数组元素按列存储且每个元素占用K个存储单元,则元素arr[i, j]在该数组空间的地址为()。

A. base + ((i - 1) * M + j - 1) * K
B. base + ((i - 1) * N + j - 1) * K
C. base + ((j - 1) * M + i - 1) * K
D. base + ((j - 1) * N + i - 1) * K

9 树与二叉树

  • 结点的度
  • 树的高度
  • 叶子结点
  • 分支结点
  • 内部结点
  • 父结点
  • 子结点
  • 兄弟结点
  • 层次

BinaryTree.png

BinaryTree_1.png

  二叉树的重要特征。

  • 在二叉树的第i层上最多有 $2^{i - 1}$ 个结点 $(i \geq 1)$ ;
  • 深度为k的二叉树最多有 $2^k - 1$ 个结点 $(k \geq 1)$ ;
  • 对任何一颗二叉树,如果其叶子结点数为 $n_0$ ,度为2的结点数为 $n_2$ ,则 $n_0 = n_2 + 1$ 。
  • 如果对一颗有n个结点的完全二叉树的结点按层序编号(从第1层到 $log_2n + 1$ 层,每层从左到右),则对任一结点i $(i \geq i \geq n)$ ,有
    • 如果i = 1,则结点i无父结点,是二叉树的根;如果i > 1,则父结点是i / 2;
    • 如果2i > n,则结点i为叶子结点,无左子结点;否则,其左子结点是结点2i;
    • 如果2i + 1 > n,则结点i无右叶子结点,否则,其右子结点是结点2i + 1;

9.1 二叉树遍历

  • 前序遍历(根左右)
  • 中序遍历(左根右)
  • 后序遍历(左右根)
  • 层序遍历

  前序遍历:12457836,中序遍历:42785136,后序遍历:48752631,层次遍历:12345678。

TraversalOfBinaryTree.png

10 堆

  堆是计算机科学中的一类特殊的数据结构的统称。堆通常是一个可以被看做一颗完全二叉树的数组对象。
  若n个元素的序列 ${a_1, a_2 … a_n}$ 满足

Formula.png

  则分别称该序列 ${a_1, a_2, … a_n}$ 为小根堆和大根堆。
  从堆的定义可以看出,对实质是满足如下性质的完全二叉树:

  • 二叉树中任一非叶子结点均小于(大于)它的孩子结点。
  • 堆总是一颗完全二叉树。

  例如:下面序列为堆,对应的完全二叉树分别为。

1
2
98 77 35 62 55 14 35 48
14 48 35 62 55 98 35 77

Heap.png

10.1 例题

  1. 对于n个元素的关键字序列 ${k_1, k_2, … k_n}$ ,当且仅当满足关系 $k_j \leq k_{2i}$ 且 $k_i \leq k_{2i + 1}$ {i = 1.2…[n/2]}时称其为小根堆(小顶堆)。以下序列中,(D)不是小根堆。

A. 16, 25, 40, 55, 30, 50, 45
B. 16, 40, 25, 50, 45, 30, 55
C. 16, 25, 39, 41, 45, 43, 50
D. 16, 40, 25, 53, 39, 55, 45

11 图

11.1 图的存储

11.1.1 邻接矩阵表示法

  邻接矩阵表示法用一个n阶方阵R来存放图中各结点的关联信息,其矩阵元素 $R_{ij}$ 定义为。
  为无向图。表示稀疏矩阵时空间浪费大。

FigureOfTheStorage.png

11.1.2 邻接链条表示法

  首先把每个顶点的邻接顶点用链表表示出来,然后用一个一维数组来顺序存储上面每个链表的头指针。

ListFigure.png

11.2 例题

  1. 某有向图G的邻接表如下图所示,可看出该图中存在弧 $<v_2, V3>$ 而不存在从顶点 $V_1$ 出发的弧。以下关于图G的叙述中,错误的是()。

A. G中存在回路
B. G中每个顶点的入度为1
C. G的邻接矩阵是对称的
D. 不存在弧 $V_3, V_1>

ex1.png

11.3 图的遍历

GraphTraversal.png

12 查找算法

  • 五大查找
    • 顺序表查找
      • 顺序查找
      • 二分查找
      • 索引顺序查找
    • 树表查找
      • 二叉排序树
    • 散列表查找
      • 哈希查找

12.1 顺序查找

  顺序查找的过程:将待查找的关键字可key的元素从头到尾与表中元素进行比较,如果中间存在关键字为key的元素,则返回成功,否则返回失败。顺序查找主要针对少量的、无规则的数据。

1
4 7 10 18 30 2 46 24 15

12.2 二分查找

  二分法查找的基本过程是:(设R[low, …, high]是当前的查找区)

  • 确定该区间的中间位置:mid = [(low + high) / 2],向下取整。
  • 将待查的k值与R[mid].key比较,若相等,则查找成功并返回此位置,否则需确定新的查找区间,继续二分查找,具体方法如下。
    • 若R[mid].key > k,则由表的有序性可知R[mid, …, n].key均大于k,因此若表中存在关键字等于k的结点,则该结点必定是在位置mid左边的子表R[low, …, mid -1]中。因此,新的查找区间是左子表R[low, …, high],其中high = mid - 1.
    • 若R[mid].key < k,则要查找的k必在mid的右子表R[mid + 1, …, high]中,即新的查找区间是右子表R[low, …, high],其中low = mid + 1。
    • 若R[mid].key = k,则查找成功,算法结束。
  • 下次查找是针对新的查找区间进行,重复步骤(1)和(2)。
  • 在查找过程中,low逐步增加,而high逐步减少。如果high < low,则查找失败,算法结束。

12.3 二叉查找树(排序)

  二叉查找树的定义:二叉排序树或者是一颗空树,或者是具有如下特性的二叉树。

  • 若它的左子树不空,则左子树上所有节点的值均小于根节点的值。
  • 若它的有子树不空,则右子树上所有节点的值均大于根节点的值。
  • 它的左、右子树也都分别是二叉排序树。

  对二叉查找树进行中序遍历,即可得到有序的序列。

BinarySortTree.png

  查找过程:二叉查找(排序)树是先对待查找的数据进行生成树,确保数的左分支值小于右分支的值,然后再去和每个结点的父结点比较大小,查找最合适的范围。这个算法的查找效率很高,但是如果使用这种查找方法要首先创建数。
  具体步骤为。

  • 若查找的关键字等于根节点的关键字,查找成功。
  • 若查找的关键字小于根节点的关键字,递归查找左子树。
  • 若查找的关键字大于根节点的关键字,递归查找右子树。
  • 若子树为空,则查找不成功。

12.4 二叉平衡树

  定义:又称AVL树。它或者是一颗空树,或者是具有下列性质的二叉树:它的左子树或右子树都是平衡二叉树,且左子树和右子树的深度之差的绝对值不超过1。

  平衡因子。
  二叉树上任一结点的左子树深度减去右子树深度的差值,称为此结点的平衡因子。

AVL.png

12.5 例题

  1. 关于二叉排序树的说法,错误的是(C)。

A. 对于二叉排序树进行中序遍历,必定得到结点关键字的有序序列
B. 依据关键字无序的序列建立二叉排序,也可能构造出单支树
C. 若构造二叉排序树时进行平衡化处理,则根节点的左子树结点数与右子树结点数的差值一定不超过1
D. 若构造二叉排序树时进行平衡化处理,则根结点的左子树高度与右子树高度的差值一定不超过1

12.5 哈夫曼树

  定义:给定N个权值作为N个叶子节点,构造一颗二叉树,若该树的带权路径长度达到最小,称这样的二叉树为最优二叉树,也称为哈夫曼树。哈夫曼树是带权路径长度最短的数,权值较大的结点离根较近。
  一般可以按下面步骤构建。

  • 将所有左、右子树都为空的作为根节点。
  • 在森林中选取两棵根节点的权值最小的数作为一棵新树的左、右子树,且置新树的附加根节点的权值为其左、右子树上根结点的权值之和。
  • 从森林中删除这两棵树,同时把新树加入到森林中。
  • 重复2、3步骤,直到森林中只有一棵树为止,此树便是哈夫曼树。

HuffmanTree.png

HuffmanTree_.png

  应用场景:对字符集中的字符进行编码和译码。

12.6 例题

  1. 以下有关哈夫曼树的说法中,错误的是(C)。

A. 哈夫曼树又被称为最优二叉树
B. 哈夫曼树是一种带权路径长度最短的树
C. 具有n个叶子结点的权值为 $W_1, W_2, …, W_n$ 的最优二叉树是唯一的
D. 哈夫曼树可以用来进行通信电文的编码和解码

13 B树

  B树,有时又写为B-树或B_树(其中的“-”或者“_”只是连字符,并不读作“B减树”)。一颗m阶的B树是一颗平衡的多路搜索树,它或者是空树,或者是满足下列性质的树。

  1. 树中每个结点至多有m棵子树。
  2. 若根结点不是叶子结点,则至少有两棵子树。
  3. 除根之外的所有非终端结点至少有[m/2](向上取整)棵子树。
  4. 所有的非终端结点中包含下列信息数据:

   $(n, A_0, K_1, A_1, K_2, A_2, …, K_n, A_n)$ ,其中: $K_i (i = 1, 2, …, n)$ 为关键字,且 $K_i < K_{i + 1}$ (i = 1, …, n - 1)。
   $A_i (i = 0, …, n)$ 为指向子树根结点的指针,且指针 $A_{i -1}$ 所指子树中所有结点的关键字均小于 $K_i(i = 1, …, n)$ , $A_n$ 所指子树中所有结点的关键字均大于 $K_n$ , $n ([m / 2] - 1 \leq n \leq m - 1)$ 为关键字的个数(或n + 1为子树个数)。其中[m / 2]表示向上取整。

  1. 所有的叶子结点都出现在同一层次上,并且不带信息(可以看作是外部结点或查找失败的结点,实际上这些结点不存在,指向这些结点的指针为空)。

BTree.png

14 B+树

  是B-树的一种变型,一个m阶的B+树具有如下几个特征。

  • 每个叶子结点中含有n个关键字和n个指向记录的指针,并且所有叶子节点彼此相链接构成一个有序链表,其头指针指向含最小关键字的节点。
  • 每个非叶子节点中的关键字 $K_i$ 即为其相应指针 $A_i$ 所指子树中关键字的最大值。
  • 所有叶子节点都处在统一层次上,每个叶子节点中关键字的个数均介于[m / 2](向上取整)和m之间。

B+Tree.png

15 散列表

  散列表构造的基本思想是:已知关键字集合U,最大关键字为m,设计一个函数Hash,它以关键字为自变量,关键字的存储地址为因变量,将关键字映射到一个有限的、地址连续的区间T[0 .. n - 1](n << m)中,这个区间就称为散列表,散列查找中使用的转换函数称为散列函数。

  例:假设有一个大小为7的表,现在要将(13, 18, 19s, 50, 20, 27)散列到表中。

  • 选择散列函数,例如使用hash(x) = x % 7作为散列函数。
  • 计算数据散列值,并放到合适的位置。
哈希地址 0 1 2 3 4 5 6
关键码 50 18 19 13

  地址重复时出现冲突,即散列冲突。

15.1 解决散列冲突

  • 链地址法(拉链法)
  • 开放地址法

   $H_i = (Hash(key) + d_i) % m$ i = 1, 2, …, k $(k \leq m - 1)$
  其中Hash(key)为哈希函数,m为哈希表的表长,di为增量序列。常见的增量序列有三种。

  • di = 1, 2, 3, …, m - 1,称为线性他侧再散列。
  • di = $1^2, {-1}^2, 2^2, {-2}^2, 3^3, …, ±k^2$ ,称为二次探测再散列。
  • di = 伪随机数列,称为随机探测再散列,如:di = Random(key)。

15.2 例题

  1. 用哈希表存储元素时,需要进行冲突(碰撞)处理,冲突是指(B)。

A. 关键字被依次映射到地址编号连续的存储位置
B. 关键字不同的元素被映射到相同的存储位置
C. 关键字相同的元素被映射到不同的存储位置
D. 关键字被映射到哈希表之外的位置

16 总结

  考查形式主要是概念区分以及部分计算题型,主要出现在上午的选择题当中。

  • 树的遍历
  • 图的遍历
  • 典型的时间复杂度

  需要记忆。

  • 数据结构与算法的概念
  • 线性表(顺序表、链表、栈、队列)
  • 数组与矩阵
  • 树与二叉树
  • 查找(二分查找、哈希)

  查找过程:二叉查找(排序)树是先对待查找的数据进行生成树,确保数的左分支值小于右分支的值,然后再去和每个结点的父结点比较大小,查找最合适的范围。这个算法的查找效率很高,但是如果使用这种查找方法要首先创建数。
  具体步骤为。

  • 若查找的关键字等于根节点的关键字,查找成功。
  • 若查找的关键字小于根节点的关键字,递归查找左子树。
  • 若查找的关键字大于根节点的关键字,递归查找右子树。
  • 若子树为空,则查找不成功。

12.4 二叉平衡树

  定义:又称AVL树。它或者是一颗空树,或者是具有下列性质的二叉树:它的左子树或右子树都是平衡二叉树,且左子树和右子树的深度之差的绝对值不超过1。

  平衡因子。
  二叉树上任一结点的左子树深度减去右子树深度的差值,称为此结点的平衡因子。

第九章——数据结构与算法

前言:
   计算机第九章节主要知识点。

1 知识点介绍

  • 数据结构与算法概念
  • 线性表
  • 数组与矩阵
  • 树与二叉树
  • 查找

2 数据结构定义

  • 数据结构
    • 数据逻辑结构:指数据元素之间的管理。
      • 线性结构:一对一关系
      • 非线性结构:一对多,多对多关系
    • 数据物理结构:数据在物理设备上具体如何存储。

3 算法概念

  算法的5个重要特征

  • 又穷性:执行有穷步之后结束,且每一步都可在有穷时间内完成。
  • 确定性:算法中每一条指令都必须由确切的含义,不能含糊不清。
  • 输入(>= 0)
  • 输出(>= 1)
  • 有效性(可行性):算法的每个步骤都能有效执行并能在执行有限此后得到确定的结果,例如a = 0,b / a就无效。

4 伪代码

  伪代码是一种算法描述语言,介于自然语言与编程语言之间,不用拘泥于具体的实现。

Pseudocode.png

5 线性表

5.1 线性表的概念

  常见线性表的两种存储结构。

  • 顺序存储结构(如:顺序表)
  • 链式存储结构(如:链表)

  逻辑上连续,物理上不一定连续。

  • 顺序表:随机存取。查询和修改容易,元素插入和删除麻烦,需要移动元素。
  • 链表
    • 单链表
    • 循环链表
    • 双向链表

LinearList.png

5.2 链表基本操作

  • 单链表删除结点
  • 单链表插入结点
  • 双向链表删除结点
  • 双向链表插入结点

LinkedList.png

5.3 例题

  1. 以下关于单链表存储结构特征的叙述中,不正确的是(D)。

A. 表中结点所占用存储空间的地址不必是连续的
B. 在表中任意位置进行插入和删除操作都不用移动元素
C. 所需空间与结点个数成正比
D. 可随机访问表中的任一结点

5.4 队列和栈

  元素按照a、b、c的次序进入栈,请尝试写出其所有可能的出栈序。

QueueAndStack.png

5.5 例题

  1. 令序列X、Y、Z的每个元素都按顺序进栈,且每个元素进栈和出栈仅一次,则不可能得到的出栈序列是(C)。

A. XYZ
B. XZY
C. ZXY
D. YZX

6 广义表

  广义表示n个表元素组成的有限序列,是线性表的推广,通常用递归的形式进行定义,记作: $LS = (a_0, a_1, …, a_n)$

注:其中LS是表名, $a_i$ 是表元素,它可以是表(称做子表),也可以是数据元素(称为原子)。其中n是广义表的长度(也就是最外层包含的元素个数),n = 0的广义表为空表;而递归定义的重数就是广义表的深度,直观地说,就是定义中所含括号的重数(原子的深度为0,空表的深度为1)。

例,有广义表LS1 = (a, (b, c), (d, e)),其长度为?深度为?
答案:长度为3,深度为2。

7 串

  串是仅由字符构成的有限序列,是取值范围受限的线性表,一般记为 S = ‘a1a2…an’,其中S是串名,单引号括起来的字符序列是串值。

8 数组

  二维数组分按行存储和按列存储。c/c++的多维数组是按行、连续存储逇。FORTRAN语言,Matlab中,数组按列优先顺序存储。

数组类型 存储地址计算
一维数组a[n] a[i]的存储地址为:a + i * len
二维数组a[m][n] a[i][j]的存储地址(按行存储)为:a + (i * n + j) * len
a[i][j]存储地址(按列存储)为:a + (j * m + i) * len

8.1 例题

  1. 数组a[1 … n, 1 … m](n > 1, m > 1)中的元素以行为主序存放,每个元素占用1个存储伟,则数组元素a[i, j] $(1 \leq i \leq n, 1 \leq j \leq m)$ 相对于数组空间首地址的偏移量为(A)

A. (i - 1) * m + j - 1
B. (i - 1) * n + j - 1
C. (j - 1) * m + i - 1
D. (j - 1) * n + i - 1

  1. 若二维数组arr[1 … M, 1 … N]的首地址为base,数组元素按列存储且每个元素占用K个存储单元,则元素arr[i, j]在该数组空间的地址为()。

A. base + ((i - 1) * M + j - 1) * K
B. base + ((i - 1) * N + j - 1) * K
C. base + ((j - 1) * M + i - 1) * K
D. base + ((j - 1) * N + i - 1) * K

9 树与二叉树

  • 结点的度
  • 树的高度
  • 叶子结点
  • 分支结点
  • 内部结点
  • 父结点
  • 子结点
  • 兄弟结点
  • 层次

BinaryTree.png

BinaryTree_1.png

  二叉树的重要特征。

  • 在二叉树的第i层上最多有 $2^{i - 1}$ 个结点 $(i \geq 1)$ ;
  • 深度为k的二叉树最多有 $2^k - 1$ 个结点 $(k \geq 1)$ ;
  • 对任何一颗二叉树,如果其叶子结点数为 $n_0$ ,度为2的结点数为 $n_2$ ,则 $n_0 = n_2 + 1$ 。
  • 如果对一颗有n个结点的完全二叉树的结点按层序编号(从第1层到 $log_2n + 1$ 层,每层从左到右),则对任一结点i $(i \geq i \geq n)$ ,有
    • 如果i = 1,则结点i无父结点,是二叉树的根;如果i > 1,则父结点是i / 2;
    • 如果2i > n,则结点i为叶子结点,无左子结点;否则,其左子结点是结点2i;
    • 如果2i + 1 > n,则结点i无右叶子结点,否则,其右子结点是结点2i + 1;

9.1 二叉树遍历

  • 前序遍历(根左右)
  • 中序遍历(左根右)
  • 后序遍历(左右根)
  • 层序遍历

  前序遍历:12457836,中序遍历:42785136,后序遍历:48752631,层次遍历:12345678。

TraversalOfBinaryTree.png

10 堆

  堆是计算机科学中的一类特殊的数据结构的统称。堆通常是一个可以被看做一颗完全二叉树的数组对象。
  若n个元素的序列 ${a_1, a_2 … a_n}$ 满足

Formula.png

  则分别称该序列 ${a_1, a_2, … a_n}$ 为小根堆和大根堆。
  从堆的定义可以看出,对实质是满足如下性质的完全二叉树:

  • 二叉树中任一非叶子结点均小于(大于)它的孩子结点。
  • 堆总是一颗完全二叉树。

  例如:下面序列为堆,对应的完全二叉树分别为。

1
2
98 77 35 62 55 14 35 48
14 48 35 62 55 98 35 77

Heap.png

10.1 例题

  1. 对于n个元素的关键字序列 ${k_1, k_2, … k_n}$ ,当且仅当满足关系 $k_j \leq k_{2i}$ 且 $k_i \leq k_{2i + 1}$ {i = 1.2…[n/2]}时称其为小根堆(小顶堆)。以下序列中,(D)不是小根堆。

A. 16, 25, 40, 55, 30, 50, 45
B. 16, 40, 25, 50, 45, 30, 55
C. 16, 25, 39, 41, 45, 43, 50
D. 16, 40, 25, 53, 39, 55, 45

11 图

11.1 图的存储

11.1.1 邻接矩阵表示法

  邻接矩阵表示法用一个n阶方阵R来存放图中各结点的关联信息,其矩阵元素 $R_{ij}$ 定义为。
  为无向图。表示稀疏矩阵时空间浪费大。

FigureOfTheStorage.png

11.1.2 邻接链条表示法

  首先把每个顶点的邻接顶点用链表表示出来,然后用一个一维数组来顺序存储上面每个链表的头指针。

ListFigure.png

11.2 例题

  1. 某有向图G的邻接表如下图所示,可看出该图中存在弧 $<v_2, V3>$ 而不存在从顶点 $V_1$ 出发的弧。以下关于图G的叙述中,错误的是()。

A. G中存在回路
B. G中每个顶点的入度为1
C. G的邻接矩阵是对称的
D. 不存在弧 $V_3, V_1>

ex1.png

11.3 图的遍历

GraphTraversal.png

12 查找算法

  • 五大查找
    • 顺序表查找
      • 顺序查找
      • 二分查找
      • 索引顺序查找
    • 树表查找
      • 二叉排序树
    • 散列表查找
      • 哈希查找

12.1 顺序查找

  顺序查找的过程:将待查找的关键字可key的元素从头到尾与表中元素进行比较,如果中间存在关键字为key的元素,则返回成功,否则返回失败。顺序查找主要针对少量的、无规则的数据。

1
4 7 10 18 30 2 46 24 15

12.2 二分查找

  二分法查找的基本过程是:(设R[low, …, high]是当前的查找区)

  • 确定该区间的中间位置:mid = [(low + high) / 2],向下取整。
  • 将待查的k值与R[mid].key比较,若相等,则查找成功并返回此位置,否则需确定新的查找区间,继续二分查找,具体方法如下。
    • 若R[mid].key > k,则由表的有序性可知R[mid, …, n].key均大于k,因此若表中存在关键字等于k的结点,则该结点必定是在位置mid左边的子表R[low, …, mid -1]中。因此,新的查找区间是左子表R[low, …, high],其中high = mid - 1.
    • 若R[mid].key < k,则要查找的k必在mid的右子表R[mid + 1, …, high]中,即新的查找区间是右子表R[low, …, high],其中low = mid + 1。
    • 若R[mid].key = k,则查找成功,算法结束。
  • 下次查找是针对新的查找区间进行,重复步骤(1)和(2)。
  • 在查找过程中,low逐步增加,而high逐步减少。如果high < low,则查找失败,算法结束。

12.3 二叉查找树(排序)

  二叉查找树的定义:二叉排序树或者是一颗空树,或者是具有如下特性的二叉树。

  • 若它的左子树不空,则左子树上所有节点的值均小于根节点的值。
  • 若它的有子树不空,则右子树上所有节点的值均大于根节点的值。
  • 它的左、右子树也都分别是二叉排序树。

  对二叉查找树进行中序遍历,即可得到有序的序列。

BinarySortTree.png

  查找过程:二叉查找(排序)树是先对待查找的数据进行生成树,确保数的左分支值小于右分支的值,然后再去和每个结点的父结点比较大小,查找最合适的范围。这个算法的查找效率很高,但是如果使用这种查找方法要首先创建数。
  具体步骤为。

  • 若查找的关键字等于根节点的关键字,查找成功。
  • 若查找的关键字小于根节点的关键字,递归查找左子树。
  • 若查找的关键字大于根节点的关键字,递归查找右子树。
  • 若子树为空,则查找不成功。

12.4 二叉平衡树

  定义:又称AVL树。它或者是一颗空树,或者是具有下列性质的二叉树:它的左子树或右子树都是平衡二叉树,且左子树和右子树的深度之差的绝对值不超过1。

  平衡因子。
  二叉树上任一结点的左子树深度减去右子树深度的差值,称为此结点的平衡因子。

AVL.png

12.5 例题

  1. 关于二叉排序树的说法,错误的是(C)。

A. 对于二叉排序树进行中序遍历,必定得到结点关键字的有序序列
B. 依据关键字无序的序列建立二叉排序,也可能构造出单支树
C. 若构造二叉排序树时进行平衡化处理,则根节点的左子树结点数与右子树结点数的差值一定不超过1
D. 若构造二叉排序树时进行平衡化处理,则根结点的左子树高度与右子树高度的差值一定不超过1

12.5 哈夫曼树

  定义:给定N个权值作为N个叶子节点,构造一颗二叉树,若该树的带权路径长度达到最小,称这样的二叉树为最优二叉树,也称为哈夫曼树。哈夫曼树是带权路径长度最短的数,权值较大的结点离根较近。
  一般可以按下面步骤构建。

  • 将所有左、右子树都为空的作为根节点。
  • 在森林中选取两棵根节点的权值最小的数作为一棵新树的左、右子树,且置新树的附加根节点的权值为其左、右子树上根结点的权值之和。
  • 从森林中删除这两棵树,同时把新树加入到森林中。
  • 重复2、3步骤,直到森林中只有一棵树为止,此树便是哈夫曼树。

HuffmanTree.png

HuffmanTree_.png

  应用场景:对字符集中的字符进行编码和译码。

12.6 例题

  1. 以下有关哈夫曼树的说法中,错误的是(C)。

A. 哈夫曼树又被称为最优二叉树
B. 哈夫曼树是一种带权路径长度最短的树
C. 具有n个叶子结点的权值为 $W_1, W_2, …, W_n$ 的最优二叉树是唯一的
D. 哈夫曼树可以用来进行通信电文的编码和解码

13 B树

  B树,有时又写为B-树或B_树(其中的“-”或者“_”只是连字符,并不读作“B减树”)。一颗m阶的B树是一颗平衡的多路搜索树,它或者是空树,或者是满足下列性质的树。

  1. 树中每个结点至多有m棵子树。
  2. 若根结点不是叶子结点,则至少有两棵子树。
  3. 除根之外的所有非终端结点至少有[m/2](向上取整)棵子树。
  4. 所有的非终端结点中包含下列信息数据:

   $(n, A_0, K_1, A_1, K_2, A_2, …, K_n, A_n)$ ,其中: $K_i (i = 1, 2, …, n)$ 为关键字,且 $K_i < K_{i + 1}$ (i = 1, …, n - 1)。
   $A_i (i = 0, …, n)$ 为指向子树根结点的指针,且指针 $A_{i -1}$ 所指子树中所有结点的关键字均小于 $K_i(i = 1, …, n)$ , $A_n$ 所指子树中所有结点的关键字均大于 $K_n$ , $n ([m / 2] - 1 \leq n \leq m - 1)$ 为关键字的个数(或n + 1为子树个数)。其中[m / 2]表示向上取整。

  1. 所有的叶子结点都出现在同一层次上,并且不带信息(可以看作是外部结点或查找失败的结点,实际上这些结点不存在,指向这些结点的指针为空)。

BTree.png

14 B+树

  是B-树的一种变型,一个m阶的B+树具有如下几个特征。

  • 每个叶子结点中含有n个关键字和n个指向记录的指针,并且所有叶子节点彼此相链接构成一个有序链表,其头指针指向含最小关键字的节点。
  • 每个非叶子节点中的关键字 $K_i$ 即为其相应指针 $A_i$ 所指子树中关键字的最大值。
  • 所有叶子节点都处在统一层次上,每个叶子节点中关键字的个数均介于[m / 2](向上取整)和m之间。

B+Tree.png

15 散列表

  散列表构造的基本思想是:已知关键字集合U,最大关键字为m,设计一个函数Hash,它以关键字为自变量,关键字的存储地址为因变量,将关键字映射到一个有限的、地址连续的区间T[0 .. n - 1](n << m)中,这个区间就称为散列表,散列查找中使用的转换函数称为散列函数。

  例:假设有一个大小为7的表,现在要将(13, 18, 19s, 50, 20, 27)散列到表中。

  • 选择散列函数,例如使用hash(x) = x % 7作为散列函数。
  • 计算数据散列值,并放到合适的位置。
哈希地址 0 1 2 3 4 5 6
关键码 50 18 19 13

  地址重复时出现冲突,即散列冲突。

15.1 解决散列冲突

  • 链地址法(拉链法)
  • 开放地址法

   $H_i = (Hash(key) + d_i) % m$ i = 1, 2, …, k $(k \leq m - 1)$
  其中Hash(key)为哈希函数,m为哈希表的表长,di为增量序列。常见的增量序列有三种。

  • di = 1, 2, 3, …, m - 1,称为线性他侧再散列。
  • di = $1^2, {-1}^2, 2^2, {-2}^2, 3^3, …, ±k^2$ ,称为二次探测再散列。
  • di = 伪随机数列,称为随机探测再散列,如:di = Random(key)。

15.2 例题

  1. 用哈希表存储元素时,需要进行冲突(碰撞)处理,冲突是指(B)。

A. 关键字被依次映射到地址编号连续的存储位置
B. 关键字不同的元素被映射到相同的存储位置
C. 关键字相同的元素被映射到不同的存储位置
D. 关键字被映射到哈希表之外的位置

16 总结

  考查形式主要是概念区分以及部分计算题型,主要出现在上午的选择题当中。

  • 树的遍历
  • 图的遍历
  • 典型的时间复杂度

  需要记忆。

  • 数据结构与算法的概念
  • 线性表(顺序表、链表、栈、队列)
  • 数组与矩阵
  • 树与二叉树
  • 查找(二分查找、哈希)

12.5 例题

  1. 关于二叉排序树的说法,错误的是(C)。

A. 对于二叉排序树进行中序遍历,必定得到结点关键字的有序序列
B. 依据关键字无序的序列建立二叉排序,也可能构造出单支树
C. 若构造二叉排序树时进行平衡化处理,则根节点的左子树结点数与右子树结点数的差值一定不超过1
D. 若构造二叉排序树时进行平衡化处理,则根结点的左子树高度与右子树高度的差值一定不超过1

12.5 哈夫曼树

  定义:给定N个权值作为N个叶子节点,构造一颗二叉树,若该树的带权路径长度达到最小,称这样的二叉树为最优二叉树,也称为哈夫曼树。哈夫曼树是带权路径长度最短的数,权值较大的结点离根较近。
  一般可以按下面步骤构建。

  • 将所有左、右子树都为空的作为根节点。
  • 在森林中选取两棵根节点的权值最小的数作为一棵新树的左、右子树,且置新树的附加根节点的权值为其左、右子树上根结点的权值之和。
  • 从森林中删除这两棵树,同时把新树加入到森林中。
  • 重复2、3步骤,直到森林中只有一棵树为止,此树便是哈夫曼树。

第九章——数据结构与算法

前言:
   计算机第九章节主要知识点。

1 知识点介绍

  • 数据结构与算法概念
  • 线性表
  • 数组与矩阵
  • 树与二叉树
  • 查找

2 数据结构定义

  • 数据结构
    • 数据逻辑结构:指数据元素之间的管理。
      • 线性结构:一对一关系
      • 非线性结构:一对多,多对多关系
    • 数据物理结构:数据在物理设备上具体如何存储。

3 算法概念

  算法的5个重要特征

  • 又穷性:执行有穷步之后结束,且每一步都可在有穷时间内完成。
  • 确定性:算法中每一条指令都必须由确切的含义,不能含糊不清。
  • 输入(>= 0)
  • 输出(>= 1)
  • 有效性(可行性):算法的每个步骤都能有效执行并能在执行有限此后得到确定的结果,例如a = 0,b / a就无效。

4 伪代码

  伪代码是一种算法描述语言,介于自然语言与编程语言之间,不用拘泥于具体的实现。

Pseudocode.png

5 线性表

5.1 线性表的概念

  常见线性表的两种存储结构。

  • 顺序存储结构(如:顺序表)
  • 链式存储结构(如:链表)

  逻辑上连续,物理上不一定连续。

  • 顺序表:随机存取。查询和修改容易,元素插入和删除麻烦,需要移动元素。
  • 链表
    • 单链表
    • 循环链表
    • 双向链表

LinearList.png

5.2 链表基本操作

  • 单链表删除结点
  • 单链表插入结点
  • 双向链表删除结点
  • 双向链表插入结点

LinkedList.png

5.3 例题

  1. 以下关于单链表存储结构特征的叙述中,不正确的是(D)。

A. 表中结点所占用存储空间的地址不必是连续的
B. 在表中任意位置进行插入和删除操作都不用移动元素
C. 所需空间与结点个数成正比
D. 可随机访问表中的任一结点

5.4 队列和栈

  元素按照a、b、c的次序进入栈,请尝试写出其所有可能的出栈序。

QueueAndStack.png

5.5 例题

  1. 令序列X、Y、Z的每个元素都按顺序进栈,且每个元素进栈和出栈仅一次,则不可能得到的出栈序列是(C)。

A. XYZ
B. XZY
C. ZXY
D. YZX

6 广义表

  广义表示n个表元素组成的有限序列,是线性表的推广,通常用递归的形式进行定义,记作: $LS = (a_0, a_1, …, a_n)$

注:其中LS是表名, $a_i$ 是表元素,它可以是表(称做子表),也可以是数据元素(称为原子)。其中n是广义表的长度(也就是最外层包含的元素个数),n = 0的广义表为空表;而递归定义的重数就是广义表的深度,直观地说,就是定义中所含括号的重数(原子的深度为0,空表的深度为1)。

例,有广义表LS1 = (a, (b, c), (d, e)),其长度为?深度为?
答案:长度为3,深度为2。

7 串

  串是仅由字符构成的有限序列,是取值范围受限的线性表,一般记为 S = ‘a1a2…an’,其中S是串名,单引号括起来的字符序列是串值。

8 数组

  二维数组分按行存储和按列存储。c/c++的多维数组是按行、连续存储逇。FORTRAN语言,Matlab中,数组按列优先顺序存储。

数组类型 存储地址计算
一维数组a[n] a[i]的存储地址为:a + i * len
二维数组a[m][n] a[i][j]的存储地址(按行存储)为:a + (i * n + j) * len
a[i][j]存储地址(按列存储)为:a + (j * m + i) * len

8.1 例题

  1. 数组a[1 … n, 1 … m](n > 1, m > 1)中的元素以行为主序存放,每个元素占用1个存储伟,则数组元素a[i, j] $(1 \leq i \leq n, 1 \leq j \leq m)$ 相对于数组空间首地址的偏移量为(A)

A. (i - 1) * m + j - 1
B. (i - 1) * n + j - 1
C. (j - 1) * m + i - 1
D. (j - 1) * n + i - 1

  1. 若二维数组arr[1 … M, 1 … N]的首地址为base,数组元素按列存储且每个元素占用K个存储单元,则元素arr[i, j]在该数组空间的地址为()。

A. base + ((i - 1) * M + j - 1) * K
B. base + ((i - 1) * N + j - 1) * K
C. base + ((j - 1) * M + i - 1) * K
D. base + ((j - 1) * N + i - 1) * K

9 树与二叉树

  • 结点的度
  • 树的高度
  • 叶子结点
  • 分支结点
  • 内部结点
  • 父结点
  • 子结点
  • 兄弟结点
  • 层次

BinaryTree.png

BinaryTree_1.png

  二叉树的重要特征。

  • 在二叉树的第i层上最多有 $2^{i - 1}$ 个结点 $(i \geq 1)$ ;
  • 深度为k的二叉树最多有 $2^k - 1$ 个结点 $(k \geq 1)$ ;
  • 对任何一颗二叉树,如果其叶子结点数为 $n_0$ ,度为2的结点数为 $n_2$ ,则 $n_0 = n_2 + 1$ 。
  • 如果对一颗有n个结点的完全二叉树的结点按层序编号(从第1层到 $log_2n + 1$ 层,每层从左到右),则对任一结点i $(i \geq i \geq n)$ ,有
    • 如果i = 1,则结点i无父结点,是二叉树的根;如果i > 1,则父结点是i / 2;
    • 如果2i > n,则结点i为叶子结点,无左子结点;否则,其左子结点是结点2i;
    • 如果2i + 1 > n,则结点i无右叶子结点,否则,其右子结点是结点2i + 1;

9.1 二叉树遍历

  • 前序遍历(根左右)
  • 中序遍历(左根右)
  • 后序遍历(左右根)
  • 层序遍历

  前序遍历:12457836,中序遍历:42785136,后序遍历:48752631,层次遍历:12345678。

TraversalOfBinaryTree.png

10 堆

  堆是计算机科学中的一类特殊的数据结构的统称。堆通常是一个可以被看做一颗完全二叉树的数组对象。
  若n个元素的序列 ${a_1, a_2 … a_n}$ 满足

Formula.png

  则分别称该序列 ${a_1, a_2, … a_n}$ 为小根堆和大根堆。
  从堆的定义可以看出,对实质是满足如下性质的完全二叉树:

  • 二叉树中任一非叶子结点均小于(大于)它的孩子结点。
  • 堆总是一颗完全二叉树。

  例如:下面序列为堆,对应的完全二叉树分别为。

1
2
98 77 35 62 55 14 35 48
14 48 35 62 55 98 35 77

Heap.png

10.1 例题

  1. 对于n个元素的关键字序列 ${k_1, k_2, … k_n}$ ,当且仅当满足关系 $k_j \leq k_{2i}$ 且 $k_i \leq k_{2i + 1}$ {i = 1.2…[n/2]}时称其为小根堆(小顶堆)。以下序列中,(D)不是小根堆。

A. 16, 25, 40, 55, 30, 50, 45
B. 16, 40, 25, 50, 45, 30, 55
C. 16, 25, 39, 41, 45, 43, 50
D. 16, 40, 25, 53, 39, 55, 45

11 图

11.1 图的存储

11.1.1 邻接矩阵表示法

  邻接矩阵表示法用一个n阶方阵R来存放图中各结点的关联信息,其矩阵元素 $R_{ij}$ 定义为。
  为无向图。表示稀疏矩阵时空间浪费大。

FigureOfTheStorage.png

11.1.2 邻接链条表示法

  首先把每个顶点的邻接顶点用链表表示出来,然后用一个一维数组来顺序存储上面每个链表的头指针。

ListFigure.png

11.2 例题

  1. 某有向图G的邻接表如下图所示,可看出该图中存在弧 $<v_2, V3>$ 而不存在从顶点 $V_1$ 出发的弧。以下关于图G的叙述中,错误的是()。

A. G中存在回路
B. G中每个顶点的入度为1
C. G的邻接矩阵是对称的
D. 不存在弧 $V_3, V_1>

ex1.png

11.3 图的遍历

GraphTraversal.png

12 查找算法

  • 五大查找
    • 顺序表查找
      • 顺序查找
      • 二分查找
      • 索引顺序查找
    • 树表查找
      • 二叉排序树
    • 散列表查找
      • 哈希查找

12.1 顺序查找

  顺序查找的过程:将待查找的关键字可key的元素从头到尾与表中元素进行比较,如果中间存在关键字为key的元素,则返回成功,否则返回失败。顺序查找主要针对少量的、无规则的数据。

1
4 7 10 18 30 2 46 24 15

12.2 二分查找

  二分法查找的基本过程是:(设R[low, …, high]是当前的查找区)

  • 确定该区间的中间位置:mid = [(low + high) / 2],向下取整。
  • 将待查的k值与R[mid].key比较,若相等,则查找成功并返回此位置,否则需确定新的查找区间,继续二分查找,具体方法如下。
    • 若R[mid].key > k,则由表的有序性可知R[mid, …, n].key均大于k,因此若表中存在关键字等于k的结点,则该结点必定是在位置mid左边的子表R[low, …, mid -1]中。因此,新的查找区间是左子表R[low, …, high],其中high = mid - 1.
    • 若R[mid].key < k,则要查找的k必在mid的右子表R[mid + 1, …, high]中,即新的查找区间是右子表R[low, …, high],其中low = mid + 1。
    • 若R[mid].key = k,则查找成功,算法结束。
  • 下次查找是针对新的查找区间进行,重复步骤(1)和(2)。
  • 在查找过程中,low逐步增加,而high逐步减少。如果high < low,则查找失败,算法结束。

12.3 二叉查找树(排序)

  二叉查找树的定义:二叉排序树或者是一颗空树,或者是具有如下特性的二叉树。

  • 若它的左子树不空,则左子树上所有节点的值均小于根节点的值。
  • 若它的有子树不空,则右子树上所有节点的值均大于根节点的值。
  • 它的左、右子树也都分别是二叉排序树。

  对二叉查找树进行中序遍历,即可得到有序的序列。

BinarySortTree.png

  查找过程:二叉查找(排序)树是先对待查找的数据进行生成树,确保数的左分支值小于右分支的值,然后再去和每个结点的父结点比较大小,查找最合适的范围。这个算法的查找效率很高,但是如果使用这种查找方法要首先创建数。
  具体步骤为。

  • 若查找的关键字等于根节点的关键字,查找成功。
  • 若查找的关键字小于根节点的关键字,递归查找左子树。
  • 若查找的关键字大于根节点的关键字,递归查找右子树。
  • 若子树为空,则查找不成功。

12.4 二叉平衡树

  定义:又称AVL树。它或者是一颗空树,或者是具有下列性质的二叉树:它的左子树或右子树都是平衡二叉树,且左子树和右子树的深度之差的绝对值不超过1。

  平衡因子。
  二叉树上任一结点的左子树深度减去右子树深度的差值,称为此结点的平衡因子。

AVL.png

12.5 例题

  1. 关于二叉排序树的说法,错误的是(C)。

A. 对于二叉排序树进行中序遍历,必定得到结点关键字的有序序列
B. 依据关键字无序的序列建立二叉排序,也可能构造出单支树
C. 若构造二叉排序树时进行平衡化处理,则根节点的左子树结点数与右子树结点数的差值一定不超过1
D. 若构造二叉排序树时进行平衡化处理,则根结点的左子树高度与右子树高度的差值一定不超过1

12.5 哈夫曼树

  定义:给定N个权值作为N个叶子节点,构造一颗二叉树,若该树的带权路径长度达到最小,称这样的二叉树为最优二叉树,也称为哈夫曼树。哈夫曼树是带权路径长度最短的数,权值较大的结点离根较近。
  一般可以按下面步骤构建。

  • 将所有左、右子树都为空的作为根节点。
  • 在森林中选取两棵根节点的权值最小的数作为一棵新树的左、右子树,且置新树的附加根节点的权值为其左、右子树上根结点的权值之和。
  • 从森林中删除这两棵树,同时把新树加入到森林中。
  • 重复2、3步骤,直到森林中只有一棵树为止,此树便是哈夫曼树。

HuffmanTree.png

HuffmanTree_.png

  应用场景:对字符集中的字符进行编码和译码。

12.6 例题

  1. 以下有关哈夫曼树的说法中,错误的是(C)。

A. 哈夫曼树又被称为最优二叉树
B. 哈夫曼树是一种带权路径长度最短的树
C. 具有n个叶子结点的权值为 $W_1, W_2, …, W_n$ 的最优二叉树是唯一的
D. 哈夫曼树可以用来进行通信电文的编码和解码

13 B树

  B树,有时又写为B-树或B_树(其中的“-”或者“_”只是连字符,并不读作“B减树”)。一颗m阶的B树是一颗平衡的多路搜索树,它或者是空树,或者是满足下列性质的树。

  1. 树中每个结点至多有m棵子树。
  2. 若根结点不是叶子结点,则至少有两棵子树。
  3. 除根之外的所有非终端结点至少有[m/2](向上取整)棵子树。
  4. 所有的非终端结点中包含下列信息数据:

   $(n, A_0, K_1, A_1, K_2, A_2, …, K_n, A_n)$ ,其中: $K_i (i = 1, 2, …, n)$ 为关键字,且 $K_i < K_{i + 1}$ (i = 1, …, n - 1)。
   $A_i (i = 0, …, n)$ 为指向子树根结点的指针,且指针 $A_{i -1}$ 所指子树中所有结点的关键字均小于 $K_i(i = 1, …, n)$ , $A_n$ 所指子树中所有结点的关键字均大于 $K_n$ , $n ([m / 2] - 1 \leq n \leq m - 1)$ 为关键字的个数(或n + 1为子树个数)。其中[m / 2]表示向上取整。

  1. 所有的叶子结点都出现在同一层次上,并且不带信息(可以看作是外部结点或查找失败的结点,实际上这些结点不存在,指向这些结点的指针为空)。

BTree.png

14 B+树

  是B-树的一种变型,一个m阶的B+树具有如下几个特征。

  • 每个叶子结点中含有n个关键字和n个指向记录的指针,并且所有叶子节点彼此相链接构成一个有序链表,其头指针指向含最小关键字的节点。
  • 每个非叶子节点中的关键字 $K_i$ 即为其相应指针 $A_i$ 所指子树中关键字的最大值。
  • 所有叶子节点都处在统一层次上,每个叶子节点中关键字的个数均介于[m / 2](向上取整)和m之间。

B+Tree.png

15 散列表

  散列表构造的基本思想是:已知关键字集合U,最大关键字为m,设计一个函数Hash,它以关键字为自变量,关键字的存储地址为因变量,将关键字映射到一个有限的、地址连续的区间T[0 .. n - 1](n << m)中,这个区间就称为散列表,散列查找中使用的转换函数称为散列函数。

  例:假设有一个大小为7的表,现在要将(13, 18, 19s, 50, 20, 27)散列到表中。

  • 选择散列函数,例如使用hash(x) = x % 7作为散列函数。
  • 计算数据散列值,并放到合适的位置。
哈希地址 0 1 2 3 4 5 6
关键码 50 18 19 13

  地址重复时出现冲突,即散列冲突。

15.1 解决散列冲突

  • 链地址法(拉链法)
  • 开放地址法

   $H_i = (Hash(key) + d_i) % m$ i = 1, 2, …, k $(k \leq m - 1)$
  其中Hash(key)为哈希函数,m为哈希表的表长,di为增量序列。常见的增量序列有三种。

  • di = 1, 2, 3, …, m - 1,称为线性他侧再散列。
  • di = $1^2, {-1}^2, 2^2, {-2}^2, 3^3, …, ±k^2$ ,称为二次探测再散列。
  • di = 伪随机数列,称为随机探测再散列,如:di = Random(key)。

15.2 例题

  1. 用哈希表存储元素时,需要进行冲突(碰撞)处理,冲突是指(B)。

A. 关键字被依次映射到地址编号连续的存储位置
B. 关键字不同的元素被映射到相同的存储位置
C. 关键字相同的元素被映射到不同的存储位置
D. 关键字被映射到哈希表之外的位置

16 总结

  考查形式主要是概念区分以及部分计算题型,主要出现在上午的选择题当中。

  • 树的遍历
  • 图的遍历
  • 典型的时间复杂度

  需要记忆。

  • 数据结构与算法的概念
  • 线性表(顺序表、链表、栈、队列)
  • 数组与矩阵
  • 树与二叉树
  • 查找(二分查找、哈希)

第九章——数据结构与算法

前言:
   计算机第九章节主要知识点。

1 知识点介绍

  • 数据结构与算法概念
  • 线性表
  • 数组与矩阵
  • 树与二叉树
  • 查找

2 数据结构定义

  • 数据结构
    • 数据逻辑结构:指数据元素之间的管理。
      • 线性结构:一对一关系
      • 非线性结构:一对多,多对多关系
    • 数据物理结构:数据在物理设备上具体如何存储。

3 算法概念

  算法的5个重要特征

  • 又穷性:执行有穷步之后结束,且每一步都可在有穷时间内完成。
  • 确定性:算法中每一条指令都必须由确切的含义,不能含糊不清。
  • 输入(>= 0)
  • 输出(>= 1)
  • 有效性(可行性):算法的每个步骤都能有效执行并能在执行有限此后得到确定的结果,例如a = 0,b / a就无效。

4 伪代码

  伪代码是一种算法描述语言,介于自然语言与编程语言之间,不用拘泥于具体的实现。

Pseudocode.png

5 线性表

5.1 线性表的概念

  常见线性表的两种存储结构。

  • 顺序存储结构(如:顺序表)
  • 链式存储结构(如:链表)

  逻辑上连续,物理上不一定连续。

  • 顺序表:随机存取。查询和修改容易,元素插入和删除麻烦,需要移动元素。
  • 链表
    • 单链表
    • 循环链表
    • 双向链表

LinearList.png

5.2 链表基本操作

  • 单链表删除结点
  • 单链表插入结点
  • 双向链表删除结点
  • 双向链表插入结点

LinkedList.png

5.3 例题

  1. 以下关于单链表存储结构特征的叙述中,不正确的是(D)。

A. 表中结点所占用存储空间的地址不必是连续的
B. 在表中任意位置进行插入和删除操作都不用移动元素
C. 所需空间与结点个数成正比
D. 可随机访问表中的任一结点

5.4 队列和栈

  元素按照a、b、c的次序进入栈,请尝试写出其所有可能的出栈序。

QueueAndStack.png

5.5 例题

  1. 令序列X、Y、Z的每个元素都按顺序进栈,且每个元素进栈和出栈仅一次,则不可能得到的出栈序列是(C)。

A. XYZ
B. XZY
C. ZXY
D. YZX

6 广义表

  广义表示n个表元素组成的有限序列,是线性表的推广,通常用递归的形式进行定义,记作: $LS = (a_0, a_1, …, a_n)$

注:其中LS是表名, $a_i$ 是表元素,它可以是表(称做子表),也可以是数据元素(称为原子)。其中n是广义表的长度(也就是最外层包含的元素个数),n = 0的广义表为空表;而递归定义的重数就是广义表的深度,直观地说,就是定义中所含括号的重数(原子的深度为0,空表的深度为1)。

例,有广义表LS1 = (a, (b, c), (d, e)),其长度为?深度为?
答案:长度为3,深度为2。

7 串

  串是仅由字符构成的有限序列,是取值范围受限的线性表,一般记为 S = ‘a1a2…an’,其中S是串名,单引号括起来的字符序列是串值。

8 数组

  二维数组分按行存储和按列存储。c/c++的多维数组是按行、连续存储逇。FORTRAN语言,Matlab中,数组按列优先顺序存储。

数组类型 存储地址计算
一维数组a[n] a[i]的存储地址为:a + i * len
二维数组a[m][n] a[i][j]的存储地址(按行存储)为:a + (i * n + j) * len
a[i][j]存储地址(按列存储)为:a + (j * m + i) * len

8.1 例题

  1. 数组a[1 … n, 1 … m](n > 1, m > 1)中的元素以行为主序存放,每个元素占用1个存储伟,则数组元素a[i, j] $(1 \leq i \leq n, 1 \leq j \leq m)$ 相对于数组空间首地址的偏移量为(A)

A. (i - 1) * m + j - 1
B. (i - 1) * n + j - 1
C. (j - 1) * m + i - 1
D. (j - 1) * n + i - 1

  1. 若二维数组arr[1 … M, 1 … N]的首地址为base,数组元素按列存储且每个元素占用K个存储单元,则元素arr[i, j]在该数组空间的地址为()。

A. base + ((i - 1) * M + j - 1) * K
B. base + ((i - 1) * N + j - 1) * K
C. base + ((j - 1) * M + i - 1) * K
D. base + ((j - 1) * N + i - 1) * K

9 树与二叉树

  • 结点的度
  • 树的高度
  • 叶子结点
  • 分支结点
  • 内部结点
  • 父结点
  • 子结点
  • 兄弟结点
  • 层次

BinaryTree.png

BinaryTree_1.png

  二叉树的重要特征。

  • 在二叉树的第i层上最多有 $2^{i - 1}$ 个结点 $(i \geq 1)$ ;
  • 深度为k的二叉树最多有 $2^k - 1$ 个结点 $(k \geq 1)$ ;
  • 对任何一颗二叉树,如果其叶子结点数为 $n_0$ ,度为2的结点数为 $n_2$ ,则 $n_0 = n_2 + 1$ 。
  • 如果对一颗有n个结点的完全二叉树的结点按层序编号(从第1层到 $log_2n + 1$ 层,每层从左到右),则对任一结点i $(i \geq i \geq n)$ ,有
    • 如果i = 1,则结点i无父结点,是二叉树的根;如果i > 1,则父结点是i / 2;
    • 如果2i > n,则结点i为叶子结点,无左子结点;否则,其左子结点是结点2i;
    • 如果2i + 1 > n,则结点i无右叶子结点,否则,其右子结点是结点2i + 1;

9.1 二叉树遍历

  • 前序遍历(根左右)
  • 中序遍历(左根右)
  • 后序遍历(左右根)
  • 层序遍历

  前序遍历:12457836,中序遍历:42785136,后序遍历:48752631,层次遍历:12345678。

TraversalOfBinaryTree.png

10 堆

  堆是计算机科学中的一类特殊的数据结构的统称。堆通常是一个可以被看做一颗完全二叉树的数组对象。
  若n个元素的序列 ${a_1, a_2 … a_n}$ 满足

Formula.png

  则分别称该序列 ${a_1, a_2, … a_n}$ 为小根堆和大根堆。
  从堆的定义可以看出,对实质是满足如下性质的完全二叉树:

  • 二叉树中任一非叶子结点均小于(大于)它的孩子结点。
  • 堆总是一颗完全二叉树。

  例如:下面序列为堆,对应的完全二叉树分别为。

1
2
98 77 35 62 55 14 35 48
14 48 35 62 55 98 35 77

Heap.png

10.1 例题

  1. 对于n个元素的关键字序列 ${k_1, k_2, … k_n}$ ,当且仅当满足关系 $k_j \leq k_{2i}$ 且 $k_i \leq k_{2i + 1}$ {i = 1.2…[n/2]}时称其为小根堆(小顶堆)。以下序列中,(D)不是小根堆。

A. 16, 25, 40, 55, 30, 50, 45
B. 16, 40, 25, 50, 45, 30, 55
C. 16, 25, 39, 41, 45, 43, 50
D. 16, 40, 25, 53, 39, 55, 45

11 图

11.1 图的存储

11.1.1 邻接矩阵表示法

  邻接矩阵表示法用一个n阶方阵R来存放图中各结点的关联信息,其矩阵元素 $R_{ij}$ 定义为。
  为无向图。表示稀疏矩阵时空间浪费大。

FigureOfTheStorage.png

11.1.2 邻接链条表示法

  首先把每个顶点的邻接顶点用链表表示出来,然后用一个一维数组来顺序存储上面每个链表的头指针。

ListFigure.png

11.2 例题

  1. 某有向图G的邻接表如下图所示,可看出该图中存在弧 $<v_2, V3>$ 而不存在从顶点 $V_1$ 出发的弧。以下关于图G的叙述中,错误的是()。

A. G中存在回路
B. G中每个顶点的入度为1
C. G的邻接矩阵是对称的
D. 不存在弧 $V_3, V_1>

ex1.png

11.3 图的遍历

GraphTraversal.png

12 查找算法

  • 五大查找
    • 顺序表查找
      • 顺序查找
      • 二分查找
      • 索引顺序查找
    • 树表查找
      • 二叉排序树
    • 散列表查找
      • 哈希查找

12.1 顺序查找

  顺序查找的过程:将待查找的关键字可key的元素从头到尾与表中元素进行比较,如果中间存在关键字为key的元素,则返回成功,否则返回失败。顺序查找主要针对少量的、无规则的数据。

1
4 7 10 18 30 2 46 24 15

12.2 二分查找

  二分法查找的基本过程是:(设R[low, …, high]是当前的查找区)

  • 确定该区间的中间位置:mid = [(low + high) / 2],向下取整。
  • 将待查的k值与R[mid].key比较,若相等,则查找成功并返回此位置,否则需确定新的查找区间,继续二分查找,具体方法如下。
    • 若R[mid].key > k,则由表的有序性可知R[mid, …, n].key均大于k,因此若表中存在关键字等于k的结点,则该结点必定是在位置mid左边的子表R[low, …, mid -1]中。因此,新的查找区间是左子表R[low, …, high],其中high = mid - 1.
    • 若R[mid].key < k,则要查找的k必在mid的右子表R[mid + 1, …, high]中,即新的查找区间是右子表R[low, …, high],其中low = mid + 1。
    • 若R[mid].key = k,则查找成功,算法结束。
  • 下次查找是针对新的查找区间进行,重复步骤(1)和(2)。
  • 在查找过程中,low逐步增加,而high逐步减少。如果high < low,则查找失败,算法结束。

12.3 二叉查找树(排序)

  二叉查找树的定义:二叉排序树或者是一颗空树,或者是具有如下特性的二叉树。

  • 若它的左子树不空,则左子树上所有节点的值均小于根节点的值。
  • 若它的有子树不空,则右子树上所有节点的值均大于根节点的值。
  • 它的左、右子树也都分别是二叉排序树。

  对二叉查找树进行中序遍历,即可得到有序的序列。

BinarySortTree.png

  查找过程:二叉查找(排序)树是先对待查找的数据进行生成树,确保数的左分支值小于右分支的值,然后再去和每个结点的父结点比较大小,查找最合适的范围。这个算法的查找效率很高,但是如果使用这种查找方法要首先创建数。
  具体步骤为。

  • 若查找的关键字等于根节点的关键字,查找成功。
  • 若查找的关键字小于根节点的关键字,递归查找左子树。
  • 若查找的关键字大于根节点的关键字,递归查找右子树。
  • 若子树为空,则查找不成功。

12.4 二叉平衡树

  定义:又称AVL树。它或者是一颗空树,或者是具有下列性质的二叉树:它的左子树或右子树都是平衡二叉树,且左子树和右子树的深度之差的绝对值不超过1。

  平衡因子。
  二叉树上任一结点的左子树深度减去右子树深度的差值,称为此结点的平衡因子。

AVL.png

12.5 例题

  1. 关于二叉排序树的说法,错误的是(C)。

A. 对于二叉排序树进行中序遍历,必定得到结点关键字的有序序列
B. 依据关键字无序的序列建立二叉排序,也可能构造出单支树
C. 若构造二叉排序树时进行平衡化处理,则根节点的左子树结点数与右子树结点数的差值一定不超过1
D. 若构造二叉排序树时进行平衡化处理,则根结点的左子树高度与右子树高度的差值一定不超过1

12.5 哈夫曼树

  定义:给定N个权值作为N个叶子节点,构造一颗二叉树,若该树的带权路径长度达到最小,称这样的二叉树为最优二叉树,也称为哈夫曼树。哈夫曼树是带权路径长度最短的数,权值较大的结点离根较近。
  一般可以按下面步骤构建。

  • 将所有左、右子树都为空的作为根节点。
  • 在森林中选取两棵根节点的权值最小的数作为一棵新树的左、右子树,且置新树的附加根节点的权值为其左、右子树上根结点的权值之和。
  • 从森林中删除这两棵树,同时把新树加入到森林中。
  • 重复2、3步骤,直到森林中只有一棵树为止,此树便是哈夫曼树。

HuffmanTree.png

HuffmanTree_.png

  应用场景:对字符集中的字符进行编码和译码。

12.6 例题

  1. 以下有关哈夫曼树的说法中,错误的是(C)。

A. 哈夫曼树又被称为最优二叉树
B. 哈夫曼树是一种带权路径长度最短的树
C. 具有n个叶子结点的权值为 $W_1, W_2, …, W_n$ 的最优二叉树是唯一的
D. 哈夫曼树可以用来进行通信电文的编码和解码

13 B树

  B树,有时又写为B-树或B_树(其中的“-”或者“_”只是连字符,并不读作“B减树”)。一颗m阶的B树是一颗平衡的多路搜索树,它或者是空树,或者是满足下列性质的树。

  1. 树中每个结点至多有m棵子树。
  2. 若根结点不是叶子结点,则至少有两棵子树。
  3. 除根之外的所有非终端结点至少有[m/2](向上取整)棵子树。
  4. 所有的非终端结点中包含下列信息数据:

   $(n, A_0, K_1, A_1, K_2, A_2, …, K_n, A_n)$ ,其中: $K_i (i = 1, 2, …, n)$ 为关键字,且 $K_i < K_{i + 1}$ (i = 1, …, n - 1)。
   $A_i (i = 0, …, n)$ 为指向子树根结点的指针,且指针 $A_{i -1}$ 所指子树中所有结点的关键字均小于 $K_i(i = 1, …, n)$ , $A_n$ 所指子树中所有结点的关键字均大于 $K_n$ , $n ([m / 2] - 1 \leq n \leq m - 1)$ 为关键字的个数(或n + 1为子树个数)。其中[m / 2]表示向上取整。

  1. 所有的叶子结点都出现在同一层次上,并且不带信息(可以看作是外部结点或查找失败的结点,实际上这些结点不存在,指向这些结点的指针为空)。

BTree.png

14 B+树

  是B-树的一种变型,一个m阶的B+树具有如下几个特征。

  • 每个叶子结点中含有n个关键字和n个指向记录的指针,并且所有叶子节点彼此相链接构成一个有序链表,其头指针指向含最小关键字的节点。
  • 每个非叶子节点中的关键字 $K_i$ 即为其相应指针 $A_i$ 所指子树中关键字的最大值。
  • 所有叶子节点都处在统一层次上,每个叶子节点中关键字的个数均介于[m / 2](向上取整)和m之间。

B+Tree.png

15 散列表

  散列表构造的基本思想是:已知关键字集合U,最大关键字为m,设计一个函数Hash,它以关键字为自变量,关键字的存储地址为因变量,将关键字映射到一个有限的、地址连续的区间T[0 .. n - 1](n << m)中,这个区间就称为散列表,散列查找中使用的转换函数称为散列函数。

  例:假设有一个大小为7的表,现在要将(13, 18, 19s, 50, 20, 27)散列到表中。

  • 选择散列函数,例如使用hash(x) = x % 7作为散列函数。
  • 计算数据散列值,并放到合适的位置。
哈希地址 0 1 2 3 4 5 6
关键码 50 18 19 13

  地址重复时出现冲突,即散列冲突。

15.1 解决散列冲突

  • 链地址法(拉链法)
  • 开放地址法

   $H_i = (Hash(key) + d_i) % m$ i = 1, 2, …, k $(k \leq m - 1)$
  其中Hash(key)为哈希函数,m为哈希表的表长,di为增量序列。常见的增量序列有三种。

  • di = 1, 2, 3, …, m - 1,称为线性他侧再散列。
  • di = $1^2, {-1}^2, 2^2, {-2}^2, 3^3, …, ±k^2$ ,称为二次探测再散列。
  • di = 伪随机数列,称为随机探测再散列,如:di = Random(key)。

15.2 例题

  1. 用哈希表存储元素时,需要进行冲突(碰撞)处理,冲突是指(B)。

A. 关键字被依次映射到地址编号连续的存储位置
B. 关键字不同的元素被映射到相同的存储位置
C. 关键字相同的元素被映射到不同的存储位置
D. 关键字被映射到哈希表之外的位置

16 总结

  考查形式主要是概念区分以及部分计算题型,主要出现在上午的选择题当中。

  • 树的遍历
  • 图的遍历
  • 典型的时间复杂度

  需要记忆。

  • 数据结构与算法的概念
  • 线性表(顺序表、链表、栈、队列)
  • 数组与矩阵
  • 树与二叉树
  • 查找(二分查找、哈希)

  应用场景:对字符集中的字符进行编码和译码。

12.6 例题

  1. 以下有关哈夫曼树的说法中,错误的是(C)。

A. 哈夫曼树又被称为最优二叉树
B. 哈夫曼树是一种带权路径长度最短的树
C. 具有n个叶子结点的权值为 $W_1, W_2, …, W_n$ 的最优二叉树是唯一的
D. 哈夫曼树可以用来进行通信电文的编码和解码

13 B树

  B树,有时又写为B-树或B_树(其中的“-”或者“_”只是连字符,并不读作“B减树”)。一颗m阶的B树是一颗平衡的多路搜索树,它或者是空树,或者是满足下列性质的树。

  1. 树中每个结点至多有m棵子树。
  2. 若根结点不是叶子结点,则至少有两棵子树。
  3. 除根之外的所有非终端结点至少有[m/2](向上取整)棵子树。
  4. 所有的非终端结点中包含下列信息数据:

   $(n, A_0, K_1, A_1, K_2, A_2, …, K_n, A_n)$ ,其中: $K_i (i = 1, 2, …, n)$ 为关键字,且 $K_i < K_{i + 1}$ (i = 1, …, n - 1)。
   $A_i (i = 0, …, n)$ 为指向子树根结点的指针,且指针 $A_{i -1}$ 所指子树中所有结点的关键字均小于 $K_i(i = 1, …, n)$ , $A_n$ 所指子树中所有结点的关键字均大于 $K_n$ , $n ([m / 2] - 1 \leq n \leq m - 1)$ 为关键字的个数(或n + 1为子树个数)。其中[m / 2]表示向上取整。

  1. 所有的叶子结点都出现在同一层次上,并且不带信息(可以看作是外部结点或查找失败的结点,实际上这些结点不存在,指向这些结点的指针为空)。

第九章——数据结构与算法

前言:
   计算机第九章节主要知识点。

1 知识点介绍

  • 数据结构与算法概念
  • 线性表
  • 数组与矩阵
  • 树与二叉树
  • 查找

2 数据结构定义

  • 数据结构
    • 数据逻辑结构:指数据元素之间的管理。
      • 线性结构:一对一关系
      • 非线性结构:一对多,多对多关系
    • 数据物理结构:数据在物理设备上具体如何存储。

3 算法概念

  算法的5个重要特征

  • 又穷性:执行有穷步之后结束,且每一步都可在有穷时间内完成。
  • 确定性:算法中每一条指令都必须由确切的含义,不能含糊不清。
  • 输入(>= 0)
  • 输出(>= 1)
  • 有效性(可行性):算法的每个步骤都能有效执行并能在执行有限此后得到确定的结果,例如a = 0,b / a就无效。

4 伪代码

  伪代码是一种算法描述语言,介于自然语言与编程语言之间,不用拘泥于具体的实现。

Pseudocode.png

5 线性表

5.1 线性表的概念

  常见线性表的两种存储结构。

  • 顺序存储结构(如:顺序表)
  • 链式存储结构(如:链表)

  逻辑上连续,物理上不一定连续。

  • 顺序表:随机存取。查询和修改容易,元素插入和删除麻烦,需要移动元素。
  • 链表
    • 单链表
    • 循环链表
    • 双向链表

LinearList.png

5.2 链表基本操作

  • 单链表删除结点
  • 单链表插入结点
  • 双向链表删除结点
  • 双向链表插入结点

LinkedList.png

5.3 例题

  1. 以下关于单链表存储结构特征的叙述中,不正确的是(D)。

A. 表中结点所占用存储空间的地址不必是连续的
B. 在表中任意位置进行插入和删除操作都不用移动元素
C. 所需空间与结点个数成正比
D. 可随机访问表中的任一结点

5.4 队列和栈

  元素按照a、b、c的次序进入栈,请尝试写出其所有可能的出栈序。

QueueAndStack.png

5.5 例题

  1. 令序列X、Y、Z的每个元素都按顺序进栈,且每个元素进栈和出栈仅一次,则不可能得到的出栈序列是(C)。

A. XYZ
B. XZY
C. ZXY
D. YZX

6 广义表

  广义表示n个表元素组成的有限序列,是线性表的推广,通常用递归的形式进行定义,记作: $LS = (a_0, a_1, …, a_n)$

注:其中LS是表名, $a_i$ 是表元素,它可以是表(称做子表),也可以是数据元素(称为原子)。其中n是广义表的长度(也就是最外层包含的元素个数),n = 0的广义表为空表;而递归定义的重数就是广义表的深度,直观地说,就是定义中所含括号的重数(原子的深度为0,空表的深度为1)。

例,有广义表LS1 = (a, (b, c), (d, e)),其长度为?深度为?
答案:长度为3,深度为2。

7 串

  串是仅由字符构成的有限序列,是取值范围受限的线性表,一般记为 S = ‘a1a2…an’,其中S是串名,单引号括起来的字符序列是串值。

8 数组

  二维数组分按行存储和按列存储。c/c++的多维数组是按行、连续存储逇。FORTRAN语言,Matlab中,数组按列优先顺序存储。

数组类型 存储地址计算
一维数组a[n] a[i]的存储地址为:a + i * len
二维数组a[m][n] a[i][j]的存储地址(按行存储)为:a + (i * n + j) * len
a[i][j]存储地址(按列存储)为:a + (j * m + i) * len

8.1 例题

  1. 数组a[1 … n, 1 … m](n > 1, m > 1)中的元素以行为主序存放,每个元素占用1个存储伟,则数组元素a[i, j] $(1 \leq i \leq n, 1 \leq j \leq m)$ 相对于数组空间首地址的偏移量为(A)

A. (i - 1) * m + j - 1
B. (i - 1) * n + j - 1
C. (j - 1) * m + i - 1
D. (j - 1) * n + i - 1

  1. 若二维数组arr[1 … M, 1 … N]的首地址为base,数组元素按列存储且每个元素占用K个存储单元,则元素arr[i, j]在该数组空间的地址为()。

A. base + ((i - 1) * M + j - 1) * K
B. base + ((i - 1) * N + j - 1) * K
C. base + ((j - 1) * M + i - 1) * K
D. base + ((j - 1) * N + i - 1) * K

9 树与二叉树

  • 结点的度
  • 树的高度
  • 叶子结点
  • 分支结点
  • 内部结点
  • 父结点
  • 子结点
  • 兄弟结点
  • 层次

BinaryTree.png

BinaryTree_1.png

  二叉树的重要特征。

  • 在二叉树的第i层上最多有 $2^{i - 1}$ 个结点 $(i \geq 1)$ ;
  • 深度为k的二叉树最多有 $2^k - 1$ 个结点 $(k \geq 1)$ ;
  • 对任何一颗二叉树,如果其叶子结点数为 $n_0$ ,度为2的结点数为 $n_2$ ,则 $n_0 = n_2 + 1$ 。
  • 如果对一颗有n个结点的完全二叉树的结点按层序编号(从第1层到 $log_2n + 1$ 层,每层从左到右),则对任一结点i $(i \geq i \geq n)$ ,有
    • 如果i = 1,则结点i无父结点,是二叉树的根;如果i > 1,则父结点是i / 2;
    • 如果2i > n,则结点i为叶子结点,无左子结点;否则,其左子结点是结点2i;
    • 如果2i + 1 > n,则结点i无右叶子结点,否则,其右子结点是结点2i + 1;

9.1 二叉树遍历

  • 前序遍历(根左右)
  • 中序遍历(左根右)
  • 后序遍历(左右根)
  • 层序遍历

  前序遍历:12457836,中序遍历:42785136,后序遍历:48752631,层次遍历:12345678。

TraversalOfBinaryTree.png

10 堆

  堆是计算机科学中的一类特殊的数据结构的统称。堆通常是一个可以被看做一颗完全二叉树的数组对象。
  若n个元素的序列 ${a_1, a_2 … a_n}$ 满足

Formula.png

  则分别称该序列 ${a_1, a_2, … a_n}$ 为小根堆和大根堆。
  从堆的定义可以看出,对实质是满足如下性质的完全二叉树:

  • 二叉树中任一非叶子结点均小于(大于)它的孩子结点。
  • 堆总是一颗完全二叉树。

  例如:下面序列为堆,对应的完全二叉树分别为。

1
2
98 77 35 62 55 14 35 48
14 48 35 62 55 98 35 77

Heap.png

10.1 例题

  1. 对于n个元素的关键字序列 ${k_1, k_2, … k_n}$ ,当且仅当满足关系 $k_j \leq k_{2i}$ 且 $k_i \leq k_{2i + 1}$ {i = 1.2…[n/2]}时称其为小根堆(小顶堆)。以下序列中,(D)不是小根堆。

A. 16, 25, 40, 55, 30, 50, 45
B. 16, 40, 25, 50, 45, 30, 55
C. 16, 25, 39, 41, 45, 43, 50
D. 16, 40, 25, 53, 39, 55, 45

11 图

11.1 图的存储

11.1.1 邻接矩阵表示法

  邻接矩阵表示法用一个n阶方阵R来存放图中各结点的关联信息,其矩阵元素 $R_{ij}$ 定义为。
  为无向图。表示稀疏矩阵时空间浪费大。

FigureOfTheStorage.png

11.1.2 邻接链条表示法

  首先把每个顶点的邻接顶点用链表表示出来,然后用一个一维数组来顺序存储上面每个链表的头指针。

ListFigure.png

11.2 例题

  1. 某有向图G的邻接表如下图所示,可看出该图中存在弧 $<v_2, V3>$ 而不存在从顶点 $V_1$ 出发的弧。以下关于图G的叙述中,错误的是()。

A. G中存在回路
B. G中每个顶点的入度为1
C. G的邻接矩阵是对称的
D. 不存在弧 $V_3, V_1>

ex1.png

11.3 图的遍历

GraphTraversal.png

12 查找算法

  • 五大查找
    • 顺序表查找
      • 顺序查找
      • 二分查找
      • 索引顺序查找
    • 树表查找
      • 二叉排序树
    • 散列表查找
      • 哈希查找

12.1 顺序查找

  顺序查找的过程:将待查找的关键字可key的元素从头到尾与表中元素进行比较,如果中间存在关键字为key的元素,则返回成功,否则返回失败。顺序查找主要针对少量的、无规则的数据。

1
4 7 10 18 30 2 46 24 15

12.2 二分查找

  二分法查找的基本过程是:(设R[low, …, high]是当前的查找区)

  • 确定该区间的中间位置:mid = [(low + high) / 2],向下取整。
  • 将待查的k值与R[mid].key比较,若相等,则查找成功并返回此位置,否则需确定新的查找区间,继续二分查找,具体方法如下。
    • 若R[mid].key > k,则由表的有序性可知R[mid, …, n].key均大于k,因此若表中存在关键字等于k的结点,则该结点必定是在位置mid左边的子表R[low, …, mid -1]中。因此,新的查找区间是左子表R[low, …, high],其中high = mid - 1.
    • 若R[mid].key < k,则要查找的k必在mid的右子表R[mid + 1, …, high]中,即新的查找区间是右子表R[low, …, high],其中low = mid + 1。
    • 若R[mid].key = k,则查找成功,算法结束。
  • 下次查找是针对新的查找区间进行,重复步骤(1)和(2)。
  • 在查找过程中,low逐步增加,而high逐步减少。如果high < low,则查找失败,算法结束。

12.3 二叉查找树(排序)

  二叉查找树的定义:二叉排序树或者是一颗空树,或者是具有如下特性的二叉树。

  • 若它的左子树不空,则左子树上所有节点的值均小于根节点的值。
  • 若它的有子树不空,则右子树上所有节点的值均大于根节点的值。
  • 它的左、右子树也都分别是二叉排序树。

  对二叉查找树进行中序遍历,即可得到有序的序列。

BinarySortTree.png

  查找过程:二叉查找(排序)树是先对待查找的数据进行生成树,确保数的左分支值小于右分支的值,然后再去和每个结点的父结点比较大小,查找最合适的范围。这个算法的查找效率很高,但是如果使用这种查找方法要首先创建数。
  具体步骤为。

  • 若查找的关键字等于根节点的关键字,查找成功。
  • 若查找的关键字小于根节点的关键字,递归查找左子树。
  • 若查找的关键字大于根节点的关键字,递归查找右子树。
  • 若子树为空,则查找不成功。

12.4 二叉平衡树

  定义:又称AVL树。它或者是一颗空树,或者是具有下列性质的二叉树:它的左子树或右子树都是平衡二叉树,且左子树和右子树的深度之差的绝对值不超过1。

  平衡因子。
  二叉树上任一结点的左子树深度减去右子树深度的差值,称为此结点的平衡因子。

AVL.png

12.5 例题

  1. 关于二叉排序树的说法,错误的是(C)。

A. 对于二叉排序树进行中序遍历,必定得到结点关键字的有序序列
B. 依据关键字无序的序列建立二叉排序,也可能构造出单支树
C. 若构造二叉排序树时进行平衡化处理,则根节点的左子树结点数与右子树结点数的差值一定不超过1
D. 若构造二叉排序树时进行平衡化处理,则根结点的左子树高度与右子树高度的差值一定不超过1

12.5 哈夫曼树

  定义:给定N个权值作为N个叶子节点,构造一颗二叉树,若该树的带权路径长度达到最小,称这样的二叉树为最优二叉树,也称为哈夫曼树。哈夫曼树是带权路径长度最短的数,权值较大的结点离根较近。
  一般可以按下面步骤构建。

  • 将所有左、右子树都为空的作为根节点。
  • 在森林中选取两棵根节点的权值最小的数作为一棵新树的左、右子树,且置新树的附加根节点的权值为其左、右子树上根结点的权值之和。
  • 从森林中删除这两棵树,同时把新树加入到森林中。
  • 重复2、3步骤,直到森林中只有一棵树为止,此树便是哈夫曼树。

HuffmanTree.png

HuffmanTree_.png

  应用场景:对字符集中的字符进行编码和译码。

12.6 例题

  1. 以下有关哈夫曼树的说法中,错误的是(C)。

A. 哈夫曼树又被称为最优二叉树
B. 哈夫曼树是一种带权路径长度最短的树
C. 具有n个叶子结点的权值为 $W_1, W_2, …, W_n$ 的最优二叉树是唯一的
D. 哈夫曼树可以用来进行通信电文的编码和解码

13 B树

  B树,有时又写为B-树或B_树(其中的“-”或者“_”只是连字符,并不读作“B减树”)。一颗m阶的B树是一颗平衡的多路搜索树,它或者是空树,或者是满足下列性质的树。

  1. 树中每个结点至多有m棵子树。
  2. 若根结点不是叶子结点,则至少有两棵子树。
  3. 除根之外的所有非终端结点至少有[m/2](向上取整)棵子树。
  4. 所有的非终端结点中包含下列信息数据:

   $(n, A_0, K_1, A_1, K_2, A_2, …, K_n, A_n)$ ,其中: $K_i (i = 1, 2, …, n)$ 为关键字,且 $K_i < K_{i + 1}$ (i = 1, …, n - 1)。
   $A_i (i = 0, …, n)$ 为指向子树根结点的指针,且指针 $A_{i -1}$ 所指子树中所有结点的关键字均小于 $K_i(i = 1, …, n)$ , $A_n$ 所指子树中所有结点的关键字均大于 $K_n$ , $n ([m / 2] - 1 \leq n \leq m - 1)$ 为关键字的个数(或n + 1为子树个数)。其中[m / 2]表示向上取整。

  1. 所有的叶子结点都出现在同一层次上,并且不带信息(可以看作是外部结点或查找失败的结点,实际上这些结点不存在,指向这些结点的指针为空)。

BTree.png

14 B+树

  是B-树的一种变型,一个m阶的B+树具有如下几个特征。

  • 每个叶子结点中含有n个关键字和n个指向记录的指针,并且所有叶子节点彼此相链接构成一个有序链表,其头指针指向含最小关键字的节点。
  • 每个非叶子节点中的关键字 $K_i$ 即为其相应指针 $A_i$ 所指子树中关键字的最大值。
  • 所有叶子节点都处在统一层次上,每个叶子节点中关键字的个数均介于[m / 2](向上取整)和m之间。

B+Tree.png

15 散列表

  散列表构造的基本思想是:已知关键字集合U,最大关键字为m,设计一个函数Hash,它以关键字为自变量,关键字的存储地址为因变量,将关键字映射到一个有限的、地址连续的区间T[0 .. n - 1](n << m)中,这个区间就称为散列表,散列查找中使用的转换函数称为散列函数。

  例:假设有一个大小为7的表,现在要将(13, 18, 19s, 50, 20, 27)散列到表中。

  • 选择散列函数,例如使用hash(x) = x % 7作为散列函数。
  • 计算数据散列值,并放到合适的位置。
哈希地址 0 1 2 3 4 5 6
关键码 50 18 19 13

  地址重复时出现冲突,即散列冲突。

15.1 解决散列冲突

  • 链地址法(拉链法)
  • 开放地址法

   $H_i = (Hash(key) + d_i) % m$ i = 1, 2, …, k $(k \leq m - 1)$
  其中Hash(key)为哈希函数,m为哈希表的表长,di为增量序列。常见的增量序列有三种。

  • di = 1, 2, 3, …, m - 1,称为线性他侧再散列。
  • di = $1^2, {-1}^2, 2^2, {-2}^2, 3^3, …, ±k^2$ ,称为二次探测再散列。
  • di = 伪随机数列,称为随机探测再散列,如:di = Random(key)。

15.2 例题

  1. 用哈希表存储元素时,需要进行冲突(碰撞)处理,冲突是指(B)。

A. 关键字被依次映射到地址编号连续的存储位置
B. 关键字不同的元素被映射到相同的存储位置
C. 关键字相同的元素被映射到不同的存储位置
D. 关键字被映射到哈希表之外的位置

16 总结

  考查形式主要是概念区分以及部分计算题型,主要出现在上午的选择题当中。

  • 树的遍历
  • 图的遍历
  • 典型的时间复杂度

  需要记忆。

  • 数据结构与算法的概念
  • 线性表(顺序表、链表、栈、队列)
  • 数组与矩阵
  • 树与二叉树
  • 查找(二分查找、哈希)

14 B+树

  是B-树的一种变型,一个m阶的B+树具有如下几个特征。

  • 每个叶子结点中含有n个关键字和n个指向记录的指针,并且所有叶子节点彼此相链接构成一个有序链表,其头指针指向含最小关键字的节点。
  • 每个非叶子节点中的关键字 $K_i$ 即为其相应指针 $A_i$ 所指子树中关键字的最大值。
  • 所有叶子节点都处在统一层次上,每个叶子节点中关键字的个数均介于[m / 2](向上取整)和m之间。

第九章——数据结构与算法

前言:
   计算机第九章节主要知识点。

1 知识点介绍

  • 数据结构与算法概念
  • 线性表
  • 数组与矩阵
  • 树与二叉树
  • 查找

2 数据结构定义

  • 数据结构
    • 数据逻辑结构:指数据元素之间的管理。
      • 线性结构:一对一关系
      • 非线性结构:一对多,多对多关系
    • 数据物理结构:数据在物理设备上具体如何存储。

3 算法概念

  算法的5个重要特征

  • 又穷性:执行有穷步之后结束,且每一步都可在有穷时间内完成。
  • 确定性:算法中每一条指令都必须由确切的含义,不能含糊不清。
  • 输入(>= 0)
  • 输出(>= 1)
  • 有效性(可行性):算法的每个步骤都能有效执行并能在执行有限此后得到确定的结果,例如a = 0,b / a就无效。

4 伪代码

  伪代码是一种算法描述语言,介于自然语言与编程语言之间,不用拘泥于具体的实现。

Pseudocode.png

5 线性表

5.1 线性表的概念

  常见线性表的两种存储结构。

  • 顺序存储结构(如:顺序表)
  • 链式存储结构(如:链表)

  逻辑上连续,物理上不一定连续。

  • 顺序表:随机存取。查询和修改容易,元素插入和删除麻烦,需要移动元素。
  • 链表
    • 单链表
    • 循环链表
    • 双向链表

LinearList.png

5.2 链表基本操作

  • 单链表删除结点
  • 单链表插入结点
  • 双向链表删除结点
  • 双向链表插入结点

LinkedList.png

5.3 例题

  1. 以下关于单链表存储结构特征的叙述中,不正确的是(D)。

A. 表中结点所占用存储空间的地址不必是连续的
B. 在表中任意位置进行插入和删除操作都不用移动元素
C. 所需空间与结点个数成正比
D. 可随机访问表中的任一结点

5.4 队列和栈

  元素按照a、b、c的次序进入栈,请尝试写出其所有可能的出栈序。

QueueAndStack.png

5.5 例题

  1. 令序列X、Y、Z的每个元素都按顺序进栈,且每个元素进栈和出栈仅一次,则不可能得到的出栈序列是(C)。

A. XYZ
B. XZY
C. ZXY
D. YZX

6 广义表

  广义表示n个表元素组成的有限序列,是线性表的推广,通常用递归的形式进行定义,记作: $LS = (a_0, a_1, …, a_n)$

注:其中LS是表名, $a_i$ 是表元素,它可以是表(称做子表),也可以是数据元素(称为原子)。其中n是广义表的长度(也就是最外层包含的元素个数),n = 0的广义表为空表;而递归定义的重数就是广义表的深度,直观地说,就是定义中所含括号的重数(原子的深度为0,空表的深度为1)。

例,有广义表LS1 = (a, (b, c), (d, e)),其长度为?深度为?
答案:长度为3,深度为2。

7 串

  串是仅由字符构成的有限序列,是取值范围受限的线性表,一般记为 S = ‘a1a2…an’,其中S是串名,单引号括起来的字符序列是串值。

8 数组

  二维数组分按行存储和按列存储。c/c++的多维数组是按行、连续存储逇。FORTRAN语言,Matlab中,数组按列优先顺序存储。

数组类型 存储地址计算
一维数组a[n] a[i]的存储地址为:a + i * len
二维数组a[m][n] a[i][j]的存储地址(按行存储)为:a + (i * n + j) * len
a[i][j]存储地址(按列存储)为:a + (j * m + i) * len

8.1 例题

  1. 数组a[1 … n, 1 … m](n > 1, m > 1)中的元素以行为主序存放,每个元素占用1个存储伟,则数组元素a[i, j] $(1 \leq i \leq n, 1 \leq j \leq m)$ 相对于数组空间首地址的偏移量为(A)

A. (i - 1) * m + j - 1
B. (i - 1) * n + j - 1
C. (j - 1) * m + i - 1
D. (j - 1) * n + i - 1

  1. 若二维数组arr[1 … M, 1 … N]的首地址为base,数组元素按列存储且每个元素占用K个存储单元,则元素arr[i, j]在该数组空间的地址为()。

A. base + ((i - 1) * M + j - 1) * K
B. base + ((i - 1) * N + j - 1) * K
C. base + ((j - 1) * M + i - 1) * K
D. base + ((j - 1) * N + i - 1) * K

9 树与二叉树

  • 结点的度
  • 树的高度
  • 叶子结点
  • 分支结点
  • 内部结点
  • 父结点
  • 子结点
  • 兄弟结点
  • 层次

BinaryTree.png

BinaryTree_1.png

  二叉树的重要特征。

  • 在二叉树的第i层上最多有 $2^{i - 1}$ 个结点 $(i \geq 1)$ ;
  • 深度为k的二叉树最多有 $2^k - 1$ 个结点 $(k \geq 1)$ ;
  • 对任何一颗二叉树,如果其叶子结点数为 $n_0$ ,度为2的结点数为 $n_2$ ,则 $n_0 = n_2 + 1$ 。
  • 如果对一颗有n个结点的完全二叉树的结点按层序编号(从第1层到 $log_2n + 1$ 层,每层从左到右),则对任一结点i $(i \geq i \geq n)$ ,有
    • 如果i = 1,则结点i无父结点,是二叉树的根;如果i > 1,则父结点是i / 2;
    • 如果2i > n,则结点i为叶子结点,无左子结点;否则,其左子结点是结点2i;
    • 如果2i + 1 > n,则结点i无右叶子结点,否则,其右子结点是结点2i + 1;

9.1 二叉树遍历

  • 前序遍历(根左右)
  • 中序遍历(左根右)
  • 后序遍历(左右根)
  • 层序遍历

  前序遍历:12457836,中序遍历:42785136,后序遍历:48752631,层次遍历:12345678。

TraversalOfBinaryTree.png

10 堆

  堆是计算机科学中的一类特殊的数据结构的统称。堆通常是一个可以被看做一颗完全二叉树的数组对象。
  若n个元素的序列 ${a_1, a_2 … a_n}$ 满足

Formula.png

  则分别称该序列 ${a_1, a_2, … a_n}$ 为小根堆和大根堆。
  从堆的定义可以看出,对实质是满足如下性质的完全二叉树:

  • 二叉树中任一非叶子结点均小于(大于)它的孩子结点。
  • 堆总是一颗完全二叉树。

  例如:下面序列为堆,对应的完全二叉树分别为。

1
2
98 77 35 62 55 14 35 48
14 48 35 62 55 98 35 77

Heap.png

10.1 例题

  1. 对于n个元素的关键字序列 ${k_1, k_2, … k_n}$ ,当且仅当满足关系 $k_j \leq k_{2i}$ 且 $k_i \leq k_{2i + 1}$ {i = 1.2…[n/2]}时称其为小根堆(小顶堆)。以下序列中,(D)不是小根堆。

A. 16, 25, 40, 55, 30, 50, 45
B. 16, 40, 25, 50, 45, 30, 55
C. 16, 25, 39, 41, 45, 43, 50
D. 16, 40, 25, 53, 39, 55, 45

11 图

11.1 图的存储

11.1.1 邻接矩阵表示法

  邻接矩阵表示法用一个n阶方阵R来存放图中各结点的关联信息,其矩阵元素 $R_{ij}$ 定义为。
  为无向图。表示稀疏矩阵时空间浪费大。

FigureOfTheStorage.png

11.1.2 邻接链条表示法

  首先把每个顶点的邻接顶点用链表表示出来,然后用一个一维数组来顺序存储上面每个链表的头指针。

ListFigure.png

11.2 例题

  1. 某有向图G的邻接表如下图所示,可看出该图中存在弧 $<v_2, V3>$ 而不存在从顶点 $V_1$ 出发的弧。以下关于图G的叙述中,错误的是()。

A. G中存在回路
B. G中每个顶点的入度为1
C. G的邻接矩阵是对称的
D. 不存在弧 $V_3, V_1>

ex1.png

11.3 图的遍历

GraphTraversal.png

12 查找算法

  • 五大查找
    • 顺序表查找
      • 顺序查找
      • 二分查找
      • 索引顺序查找
    • 树表查找
      • 二叉排序树
    • 散列表查找
      • 哈希查找

12.1 顺序查找

  顺序查找的过程:将待查找的关键字可key的元素从头到尾与表中元素进行比较,如果中间存在关键字为key的元素,则返回成功,否则返回失败。顺序查找主要针对少量的、无规则的数据。

1
4 7 10 18 30 2 46 24 15

12.2 二分查找

  二分法查找的基本过程是:(设R[low, …, high]是当前的查找区)

  • 确定该区间的中间位置:mid = [(low + high) / 2],向下取整。
  • 将待查的k值与R[mid].key比较,若相等,则查找成功并返回此位置,否则需确定新的查找区间,继续二分查找,具体方法如下。
    • 若R[mid].key > k,则由表的有序性可知R[mid, …, n].key均大于k,因此若表中存在关键字等于k的结点,则该结点必定是在位置mid左边的子表R[low, …, mid -1]中。因此,新的查找区间是左子表R[low, …, high],其中high = mid - 1.
    • 若R[mid].key < k,则要查找的k必在mid的右子表R[mid + 1, …, high]中,即新的查找区间是右子表R[low, …, high],其中low = mid + 1。
    • 若R[mid].key = k,则查找成功,算法结束。
  • 下次查找是针对新的查找区间进行,重复步骤(1)和(2)。
  • 在查找过程中,low逐步增加,而high逐步减少。如果high < low,则查找失败,算法结束。

12.3 二叉查找树(排序)

  二叉查找树的定义:二叉排序树或者是一颗空树,或者是具有如下特性的二叉树。

  • 若它的左子树不空,则左子树上所有节点的值均小于根节点的值。
  • 若它的有子树不空,则右子树上所有节点的值均大于根节点的值。
  • 它的左、右子树也都分别是二叉排序树。

  对二叉查找树进行中序遍历,即可得到有序的序列。

BinarySortTree.png

  查找过程:二叉查找(排序)树是先对待查找的数据进行生成树,确保数的左分支值小于右分支的值,然后再去和每个结点的父结点比较大小,查找最合适的范围。这个算法的查找效率很高,但是如果使用这种查找方法要首先创建数。
  具体步骤为。

  • 若查找的关键字等于根节点的关键字,查找成功。
  • 若查找的关键字小于根节点的关键字,递归查找左子树。
  • 若查找的关键字大于根节点的关键字,递归查找右子树。
  • 若子树为空,则查找不成功。

12.4 二叉平衡树

  定义:又称AVL树。它或者是一颗空树,或者是具有下列性质的二叉树:它的左子树或右子树都是平衡二叉树,且左子树和右子树的深度之差的绝对值不超过1。

  平衡因子。
  二叉树上任一结点的左子树深度减去右子树深度的差值,称为此结点的平衡因子。

AVL.png

12.5 例题

  1. 关于二叉排序树的说法,错误的是(C)。

A. 对于二叉排序树进行中序遍历,必定得到结点关键字的有序序列
B. 依据关键字无序的序列建立二叉排序,也可能构造出单支树
C. 若构造二叉排序树时进行平衡化处理,则根节点的左子树结点数与右子树结点数的差值一定不超过1
D. 若构造二叉排序树时进行平衡化处理,则根结点的左子树高度与右子树高度的差值一定不超过1

12.5 哈夫曼树

  定义:给定N个权值作为N个叶子节点,构造一颗二叉树,若该树的带权路径长度达到最小,称这样的二叉树为最优二叉树,也称为哈夫曼树。哈夫曼树是带权路径长度最短的数,权值较大的结点离根较近。
  一般可以按下面步骤构建。

  • 将所有左、右子树都为空的作为根节点。
  • 在森林中选取两棵根节点的权值最小的数作为一棵新树的左、右子树,且置新树的附加根节点的权值为其左、右子树上根结点的权值之和。
  • 从森林中删除这两棵树,同时把新树加入到森林中。
  • 重复2、3步骤,直到森林中只有一棵树为止,此树便是哈夫曼树。

HuffmanTree.png

HuffmanTree_.png

  应用场景:对字符集中的字符进行编码和译码。

12.6 例题

  1. 以下有关哈夫曼树的说法中,错误的是(C)。

A. 哈夫曼树又被称为最优二叉树
B. 哈夫曼树是一种带权路径长度最短的树
C. 具有n个叶子结点的权值为 $W_1, W_2, …, W_n$ 的最优二叉树是唯一的
D. 哈夫曼树可以用来进行通信电文的编码和解码

13 B树

  B树,有时又写为B-树或B_树(其中的“-”或者“_”只是连字符,并不读作“B减树”)。一颗m阶的B树是一颗平衡的多路搜索树,它或者是空树,或者是满足下列性质的树。

  1. 树中每个结点至多有m棵子树。
  2. 若根结点不是叶子结点,则至少有两棵子树。
  3. 除根之外的所有非终端结点至少有[m/2](向上取整)棵子树。
  4. 所有的非终端结点中包含下列信息数据:

   $(n, A_0, K_1, A_1, K_2, A_2, …, K_n, A_n)$ ,其中: $K_i (i = 1, 2, …, n)$ 为关键字,且 $K_i < K_{i + 1}$ (i = 1, …, n - 1)。
   $A_i (i = 0, …, n)$ 为指向子树根结点的指针,且指针 $A_{i -1}$ 所指子树中所有结点的关键字均小于 $K_i(i = 1, …, n)$ , $A_n$ 所指子树中所有结点的关键字均大于 $K_n$ , $n ([m / 2] - 1 \leq n \leq m - 1)$ 为关键字的个数(或n + 1为子树个数)。其中[m / 2]表示向上取整。

  1. 所有的叶子结点都出现在同一层次上,并且不带信息(可以看作是外部结点或查找失败的结点,实际上这些结点不存在,指向这些结点的指针为空)。

BTree.png

14 B+树

  是B-树的一种变型,一个m阶的B+树具有如下几个特征。

  • 每个叶子结点中含有n个关键字和n个指向记录的指针,并且所有叶子节点彼此相链接构成一个有序链表,其头指针指向含最小关键字的节点。
  • 每个非叶子节点中的关键字 $K_i$ 即为其相应指针 $A_i$ 所指子树中关键字的最大值。
  • 所有叶子节点都处在统一层次上,每个叶子节点中关键字的个数均介于[m / 2](向上取整)和m之间。

B+Tree.png

15 散列表

  散列表构造的基本思想是:已知关键字集合U,最大关键字为m,设计一个函数Hash,它以关键字为自变量,关键字的存储地址为因变量,将关键字映射到一个有限的、地址连续的区间T[0 .. n - 1](n << m)中,这个区间就称为散列表,散列查找中使用的转换函数称为散列函数。

  例:假设有一个大小为7的表,现在要将(13, 18, 19s, 50, 20, 27)散列到表中。

  • 选择散列函数,例如使用hash(x) = x % 7作为散列函数。
  • 计算数据散列值,并放到合适的位置。
哈希地址 0 1 2 3 4 5 6
关键码 50 18 19 13

  地址重复时出现冲突,即散列冲突。

15.1 解决散列冲突

  • 链地址法(拉链法)
  • 开放地址法

   $H_i = (Hash(key) + d_i) % m$ i = 1, 2, …, k $(k \leq m - 1)$
  其中Hash(key)为哈希函数,m为哈希表的表长,di为增量序列。常见的增量序列有三种。

  • di = 1, 2, 3, …, m - 1,称为线性他侧再散列。
  • di = $1^2, {-1}^2, 2^2, {-2}^2, 3^3, …, ±k^2$ ,称为二次探测再散列。
  • di = 伪随机数列,称为随机探测再散列,如:di = Random(key)。

15.2 例题

  1. 用哈希表存储元素时,需要进行冲突(碰撞)处理,冲突是指(B)。

A. 关键字被依次映射到地址编号连续的存储位置
B. 关键字不同的元素被映射到相同的存储位置
C. 关键字相同的元素被映射到不同的存储位置
D. 关键字被映射到哈希表之外的位置

16 总结

  考查形式主要是概念区分以及部分计算题型,主要出现在上午的选择题当中。

  • 树的遍历
  • 图的遍历
  • 典型的时间复杂度

  需要记忆。

  • 数据结构与算法的概念
  • 线性表(顺序表、链表、栈、队列)
  • 数组与矩阵
  • 树与二叉树
  • 查找(二分查找、哈希)

15 散列表

  散列表构造的基本思想是:已知关键字集合U,最大关键字为m,设计一个函数Hash,它以关键字为自变量,关键字的存储地址为因变量,将关键字映射到一个有限的、地址连续的区间T[0 .. n - 1](n << m)中,这个区间就称为散列表,散列查找中使用的转换函数称为散列函数。

  例:假设有一个大小为7的表,现在要将(13, 18, 19s, 50, 20, 27)散列到表中。

  • 选择散列函数,例如使用hash(x) = x % 7作为散列函数。
  • 计算数据散列值,并放到合适的位置。
哈希地址 0 1 2 3 4 5 6
关键码 50 18 19 13

  地址重复时出现冲突,即散列冲突。

15.1 解决散列冲突

  • 链地址法(拉链法)
  • 开放地址法

   $H_i = (Hash(key) + d_i) % m$ i = 1, 2, …, k $(k \leq m - 1)$
  其中Hash(key)为哈希函数,m为哈希表的表长,di为增量序列。常见的增量序列有三种。

  • di = 1, 2, 3, …, m - 1,称为线性他侧再散列。
  • di = $1^2, {-1}^2, 2^2, {-2}^2, 3^3, …, ±k^2$ ,称为二次探测再散列。
  • di = 伪随机数列,称为随机探测再散列,如:di = Random(key)。

15.2 例题

  1. 用哈希表存储元素时,需要进行冲突(碰撞)处理,冲突是指(B)。

A. 关键字被依次映射到地址编号连续的存储位置
B. 关键字不同的元素被映射到相同的存储位置
C. 关键字相同的元素被映射到不同的存储位置
D. 关键字被映射到哈希表之外的位置

16 总结

  考查形式主要是概念区分以及部分计算题型,主要出现在上午的选择题当中。

  • 树的遍历
  • 图的遍历
  • 典型的时间复杂度

  需要记忆。

  • 数据结构与算法的概念
  • 线性表(顺序表、链表、栈、队列)
  • 数组与矩阵
  • 树与二叉树
  • 查找(二分查找、哈希)