1 数据结构分类
1.1 逻辑结构分类
- 集合结构
- 线性结构:线性表、栈、队列、串
- 树形结构
- 图形结构
1.2 物理结构分类
逻辑结构在计算机中的真正表示方式(又称为映射)称为物理结构,也可叫做存储结构
- 顺序存储结构:数组
- 链式存储结构
- 索引存储结构
- 散列存储结构
2 算法
2.1 算法的特性:
- 有穷性
- 确定性
- 可行性
2.2 算法效率
- 时间复杂度
- 空间复杂度
3 线性表:List
线性表是具有相同特性的数据元素的一个有限序列。是一种典型的线性结构。
3.1 顺序表
顺序表(元素)特点:顺序存储结构
地址连续、依次存放、随机存储、类型相同
定义顺序表的类型:
#define SQLMAXSIZE 100 // 线性表存储空间的初始分配量
typedef int SqlElemType;
typedef struct __Sqlist {
SqlElemType *base;
int length;
} Sqlist;
例子:
定义顺序表类型时内存分配:
3.2 链表
3.2.1 单链表
- 单链表由头节点(不存放数据只存放下个节点的地址)和n个节点组成,
- 每个节点分为两个域:数据域和指针域(存放下个节点的地址)
- 第n个节点的指针域为NULL。
- 单链表是由头指针唯一确定,因此单链表可以用头指针的名字来命名,为链式存储结构。
3.2.1.1 单链表类型的定义
例子:
或:
3.1.2.2 销毁单链表
3.2.1.3 清空链表
链表仍存在,但链表中无元素,成为空链表(头指针和头节点仍然存在)。
3.2.1.4 求单链表的表长
从首元节点开始,依次计数所有节点。
3.2.2 双链表
节点有两个指针域的的链表。
3.2.3 循环链表
首尾相接的链表
4 栈和队列
栈和队列是限定插入和删除只能在表的“端点”进行的线性表。
4.1 栈(Stack)
特点是后进先出(LIFO),应用场景有:
- 进值转换
- 括号匹配的检验
- 行编辑程序
- 迷宫求解
- 表达式求值
- 八皇后问题
- 函数调用
- 递归调用实现
4.1.1 顺序栈
4.1.1.1 顺序栈类型定义
4.1.1.2 顺序栈的初始化
4.1.2 链栈
4.1.2.1 链栈类型定义
链栈是运算受限的单链表,只能在链表头部进行操作
4.1.2.2 链栈的初始化
4.1.2.3 链栈的入栈
4.1.2.4 链栈的出栈
4.2 队列(queue)
特点是先进先出(FIFO),应用于类似排队的场景中:
- 脱机打印输出:按申请的先后顺序依次输出
- 多用户系统中,多个用户排成队,分时地循环使用CPU和主存
- 按用户的优先级排成多个队,每个优先级一个队列
- 实时控制系统中,信号按接收的先后顺序依次处理
- 网络电文传输,按时到达的时间先后顺序依次进行
4.2.1 循环队列
只能在表的一端进行插入运算,在表的另一端进行删除运算的线性表
4.2.1.1 循环队列类型定义
4.2.1.2 循环队列的初始化
4.2.2 链队列
若用户无法估计所用队列长度,则宜采用链队列。
4.2.2.1 链队列类型定义
4.2.2.2 链队列的初始化
5 串、数组、广义表
5.1 串(String)
串是零个或多个任意字符组成的有限序列。
子串:一个串中任意个连续字符组成的串叫子串。
5.1.1 顺序串
5.1.1.1 顺序串的类型定义
存储从1开始,0闲置不用。
5.1.1.2 串的模式匹配算法
目的:确定主串中所含子串(模式串)第一次出现的位置(定位)。
1. BF算法
Brute-Force 简称 BF算法,又称为简单匹配算法,采用穷举法的思路。时间:O(n*m)
2. KMP算法
主串S 中指针i 不必回溯,子串T中j 回溯,可提速到O(n+m);
相比BF算法,KMP算法增加一个 next数组,通过 next数组将 j回溯;
求模式串(子串)的next数组:
即:
代码:
5.1.2 链串
5.1.2.1 链串(块链)的类型定义
5.2 数组
按一定格式排列起来的,具有相同类型的数据元素的集合。
一维数组的 声明格式:数据类型 变量名称[长度]; int num[4];
二维数组的 声明格式:数据类型 变量名称[行数][列数]; int mun[2][3];
5.3 广义表(LS)
6 树(Tree)
6.1 树的基本定义
- 根结点:非空树中无前驱结点的结点
- 结点的度:结点拥有的子树数(即直接的分枝个数)
- 树的度:树内各结点的度的最大值
- 叶子结点:终端结点(度为0)
- 树的深度:树中结点的最大层次
- 有序树:树中结点的各子树从左至右有次序(最左边的为第一个孩子)
- 无序树:树中各结点无序
- 森林:是m(m≥0)棵互不相交的树的集合
6.2 二叉树的定义
- 二叉树是最多只有两个“叉”的树(度≤2),任何树都可以和二叉树相互转换;
- 二叉树不是树的特殊情况,它们是两个概念;
- 二叉树结点的子树要区分左子树和右子树,即使只有一棵树也要区分,说明其是左子树,还是右子树;
6.2.1 二叉树的抽象类型定义
6.2.2 二叉树的性质
- 在二叉树的第 i 层上至多有 个结点(i≥1),至少有1个结点
- 深度为 k 的二叉树至多有
- 深度为 k 的二叉树至少有 k 个结点
- 对于任何一个二叉树 T,如果其叶子树为 ,度为 2 的结点数为 ,则
6.3 满二叉树
- 每一层上的结点数都是最大结点数(即每层都满:)
- 叶子结点全部在最底层
6.4 完全二叉树
深度为 k 的具有 n 个结点的二叉树,当且仅当其每一个结点都与深度为 k 的满二叉树中编号为 1~n 的结点一一对应时,称之为 完全二叉树。
即:在满二叉树中,从最后一个结点开始,连续去掉任意个结点,都是一颗完全二叉树。
6.4.1 完全二叉树的性质
- 具有 n 个结点的完全二叉树的深度为
- 如果对一颗有 n 个结点的完全二叉树(深度为 )的结点按层序编号(从第1层到第 层,每层从左到右),则对任一结点编号 i(1 ≤ i ≤ n),有:
6.5 二叉树的存储结构
6.5.1 二叉树的顺序存储结构
实现:按满二叉树的结点层次编号,依次存放二叉树中的数据元素。
存储结构:(适用满二叉树或完全二叉树)
6.5.2 二叉树的链式存储结构
6.5.2.1 二叉链表
在 n 个结点的二叉链表中,有 n+1 个空指针域。
6.5.2.2 三叉链表
6.5.3 遍历二叉树算法(递归方法)
若二叉树为空,则进行空操作。
6.5.3.1 二叉树先序遍历算法
例:
6.5.3.2 二叉树中序遍历算法
遍历算法对比:
6.5.4 中序遍历二叉树算法(非递归方法)
6.5.5 二叉树的层次遍历(队列)
对于一颗二叉树,从左到右,从上到下进行遍历。
6.6 二叉树的建立算法(先序 读入字符)
6.7 二叉树的复制算法
6.8 计算二叉树的深度算法
6.9 计算二叉树结点总数算法
6.10 计算二叉树的叶子结点数算法
6.11 线索二叉树
如果某个结点的左孩子为空,则将空的左孩子指针域改为指向其前驱;如果某个结点的右孩子为空,则将空的右孩子指针域改为指向其后继-----这种改变指向的指针称为“线索”,即线索二叉树。
例:线索化
线索二叉树结构:
6.12 树的存储结构
6.12.1 双亲表示法
6.12.2 孩子链表
6.12.3 孩子兄弟表示法 (二叉链表表示法)
6.13 树与二叉树的转换
6.13.1 将树转换为二叉树
6.13.2 将二叉树转换为树
6.14 森林与二叉树的转换
6.14.1 森林转换为二叉树
6.14.2 二叉树转换为森林
6.15 树与森林的遍历
6.15.1 树的遍历(三种方式)
6.15.2 森林的遍历
6.16 哈夫曼树
哈夫曼树即是:带权路径长度(WPL)最短的树。
贪心算法:构造哈夫曼树时首先选择权值最小的叶子结点。
6.16.1 构造哈夫曼树方法
6.16.2 哈夫曼树(结点类型定义):一维结构数组
6.16.3 构造哈夫曼树算法
6.16.4 哈夫曼编码算法
哈夫曼编码是前缀码,且是最优前缀码。
哈夫曼编码构造算法:
7 图(Grap)
7.1 图的抽象数据类型定义
7.2 图的存储结构
7.2.1 数组(邻接矩阵)表示法
缺陷:插入和删除顶点不便
7.2.2 链式存储结构(邻接表)
7.3 图的遍历
7.3.1 深度优先搜索(DFS)
7.3.2 广度优先搜索(BFS)
7.4 图的应用
7.4.1 构造最小生成树
7.4.1.1 普里姆算法(Prim)
7.4.1.2 克鲁斯卡尔算法(KrusKal)
最小生成树并不唯一
7.4.2 寻找最短路径
7.4.2.1 单源最短路径——迪杰斯特拉算法(Dijkstra)
7.4.2.2 所有顶点间的最短路径——弗洛伊德算法(Floyd)
7.4.3 有向无环图及其应用
7.4.3.1 拓扑排序
7.4.3.2 关键路径
8 查找
8.1 线性表的查找——线性存储结构
8.1.1 顺序查找(线性查找)
或:
改进:从后往前查找
8.1.2 折半查找(二分查找或对分查找)
8.1.3 分块查找
8.2 树表的查找——树型存储结构
8.2.1 二叉排序树
8.2.2 平衡二叉树
8.3哈希表的查找——散列存储结构
8.3.1 散列函数的构造方法
8.3.1.1 直接订址法
8.3.1.2 除留余数法
8.3.2 散列表冲突解决方法
8.3.2.1 开放定址法
8.3.2.2 链地址法(拉链法)
8.3.3 散列表的查找
9 排序
9.1 排序的分类
9.2 插入排序
9.2.1 直接插入排序
9.2.2 折半插入排序
9.2.3 希尔排序
9.3 交换排序
9.3.1 冒泡排序
9.3.2 快速排序
快速排序不适于对原本有序或基本有序的记录序列进行排序。