数据结构与算法基础(王卓)--学习笔记

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 单链表

  1. 单链表由头节点(不存放数据只存放下个节点的地址)和n个节点组成,
  2. 每个节点分为两个域:数据域和指针域(存放下个节点的地址)
  3. 第n个节点的指针域为NULL。
  4. 单链表是由头指针唯一确定,因此单链表可以用头指针的名字来命名,为链式存储结构。
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 二叉树的性质

  1. 在二叉树的第 i 层上至多有 2^{i-1} 个结点(i≥1),至少有1个结点
  2. 深度为 k 的二叉树至多有 2^{k}-1
  3. 深度为 k 的二叉树至少有 k 个结点
  4. 对于任何一个二叉树 T,如果其叶子树为 n_{0},度为 2 的结点数为 n_{2} ,则 n_{0}=n_{2}+1

6.3 满二叉树 

  •  每一层上的结点数都是最大结点数(即每层都满:2^{k}-1
  • 叶子结点全部在最底层

 6.4 完全二叉树

深度为 k 的具有 n 个结点的二叉树,当且仅当其每一个结点都与深度为 k 的满二叉树中编号为 1~n 的结点一一对应时,称之为 完全二叉树。

 即:在满二叉树中,从最后一个结点开始,连续去掉任意个结点,都是一颗完全二叉树

 6.4.1 完全二叉树的性质

  • 具有 n 个结点的完全二叉树的深度为 \left \lfloor log_{2}n \right \rfloor+1
  • 如果对一颗有 n 个结点的完全二叉树(深度为 \left \lfloor log_{2}n \right \rfloor+1)的结点按层序编号(从第1层到第 \left \lfloor log_{2}n \right \rfloor+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 快速排序

快速排序不适于对原本有序或基本有序的记录序列进行排序。

9.4 选择排序

9.4.1 简单选择排序

9.4.2 堆排序

9.5 归并排序

9.6 基数排序

9.7 排序算法性能比较

  • 27
    点赞
  • 30
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值