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

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 排序算法性能比较

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值