第一章:基本数据结构
Part 1:算法复杂度1
1、时间复杂度
执行当前算法所耗费的“时间”(并非真实的时间,而是一种趋势)常采用大O表示法,即
T
(
n
)
=
O
[
f
(
n
)
]
T(n)=O[f(n)]
T(n)=O[f(n)]
其中f(n)表示每行代码执行次数之和(假设每行代码执行时间相同),下面给个例子
for (int i = 0; i < n; ++i)
int j = i;
T ( n ) = lim n → + ∞ O ( 1 + n ) = O ( n ) T(n)={\lim_{n\to+\infty}}O(1+n)=O(n) T(n)=n→+∞limO(1+n)=O(n)
为什么会使用到极限工具,因为该公式的全称是算法的渐进时间复杂度,并不代表真实的算法执行时间,而是算法执行时间的变化趋势
2、空间复杂度
执行当前算法所占的“空间”,也采用大O表示法,即
S
(
n
)
=
O
[
f
(
n
)
]
S(n)=O[f(n)]
S(n)=O[f(n)]
其中f(n)表示算法运行时所占用空间的度量,同样也是一个趋势
Part2:线性表
1、线性表的分类
- 顺序存储:逻辑上相邻,物理上也相邻——顺序表
- 链式存储:逻辑上相邻,物理上不一定相邻——链式表
2、顺序表
常采用一维数组实现
3、链式表
3.1 实现方式
{
指
针
{
单
链
表
⟶
扩
展
双
链
表
双
链
表
⟶
扩
展
循
环
双
链
表
数
组
\left\{\begin{array}{lr} 指针 \left\{\begin{array}{lr} 单链表\stackrel{扩展}{\longrightarrow}双链表\\ 双链表\stackrel{扩展}{\longrightarrow}循环双链表 \end{array}\right. \\ 数组 \end{array}\right.
⎩⎨⎧指针{单链表⟶扩展双链表双链表⟶扩展循环双链表数组
3.2指针实现方式
这个我实在是无法用markdown的mermaid来表示,只能先用图片的方式来代替一下,看看以后有没有方法用绘图的方式来表示
3.3数组实现方式
Part3:栈和队列
从本质上说,栈和队列即为操作受到限制的线性表
- 满足“后进先出”原则——栈
- 满足排队“先进先出”原则——队列
1、栈的实现
{ 指 针 : 链 栈 数 组 : 顺 序 栈 \left\{\begin{array}{lr} 指针:链栈 \\ 数组:顺序栈 \end{array}\right. {指针:链栈数组:顺序栈
2、队列的实现
{ 指 针 : 链 式 队 列 数 组 : 顺 序 队 列 ⟶ 扩 展 循 环 队 列 \left\{\begin{array}{lr} 指针:链式队列 \\ 数组:顺序队列\stackrel{扩展}{\longrightarrow}循环队列 \end{array}\right. {指针:链式队列数组:顺序队列⟶扩展循环队列
特殊的队列:双端队列
3、栈和队列的应用
3.1 栈的应用
3.1.1括号匹配
基本思路:扫描括号,如果栈顶元素和其匹配,则将栈顶元素出栈;如果不匹配,则将该括号入站
3.1.2中/后缀表达式
-
两个表达式:中缀与后缀
-
中缀表达式
即为正常人看得懂的表达式,如下例所示
A + B ∗ ( C − D ) + E / F A+B*(C-D)+E/F A+B∗(C−D)+E/F -
后缀表达式
计算机喜欢的表达式,如下例所示
A B C D − ∗ + E F / ABCD-*+EF/ ABCD−∗+EF/
-
-
用栈求后缀表达式的值
基本思路:从左到右扫描后缀表达式,如果遇到数字则入栈;如果遇到操作符,则从栈中取出两个数字运算,将运算结果入栈。扫描完毕,计算结束
-
中缀表达式转为后缀表达式
从左到右扫描中缀表达式,如果
-
遇到数字,直接输出
-
遇到操作符(operator)
-
括号
- “(”直接入栈
- “)“出栈到”(”
-
普通操作符(加减乘除)
入栈的operator要在范围内当老大,那么出栈高优先级的operator
-
扫描结束,全部出栈,结合一个例子来说明一下
-
3.2 队列的应用
在树的层次遍历中,采用队列实现
基本思想:首先根结点入队;然后出队第一个结点,并将其左右孩子入队。
Part4:多维数组
1、多维数组的存储
1.1 二维数组
(
a
00
a
01
a
10
a
11
)
\begin{pmatrix} a_{00} & a_{01} \\ a_{10} & a_{11} \\ \end{pmatrix}
(a00a10a01a11)
-
按照行优先:C语言采用
a 00 , a 01 , a 10 , a 11 a_{00},a_{01},a_{10},a_{11} a00,a01,a10,a11 -
按照列优先:FORTRAN语言采用
a 00 , a 10 , a 01 , a 11 a_{00},a_{10},a_{01},a_{11} a00,a10,a01,a11
1.2 高维数组
设有高维数组
A
2
∗
3
∗
4
A_{2*3*4}
A2∗3∗4
-
按照右侧下标优先
A 000 , A 001 , A 002 , A 003 . . . . A_{000},A_{001},A_{002},A_{003}.... A000,A001,A002,A003.... -
按照左侧下标优先
A 000 , A 100 , A 010 , A 110 . . . . A_{000},A_{100},A_{010},A_{110}.... A000,A100,A010,A110....
2、矩阵(二维数组)的降维
虽然说矩阵降维之后其高维的信息就会丢失,但是对于一些特殊的矩阵,可以采用一些特殊的手段,将其降维,并且保留其所有信息。
2.1主对角线相关矩阵
2.2稀疏矩阵
仅有几个非0元素的矩阵,故我们仅需存储其非0元素即可,常用结构数据或者十字链表法
算法的时间与空间复杂度(https://zhuanlan.zhihu.com/p/50479555) ↩︎