经典数据结构与算法

经典数据结构

向量 Vector

 

列表 List

 

栈 Stack

 

队列 Queue

 

Steap (Stack + Heap)

 

Queap (Queue + Heap)

 

BBST

1. AVL
2. B树
3. Red-Black Tree
4. Splay Tree

 

跳转表 Skip List

 

图 Graph

 

并查集 DSU

Disjoint Set Union

时间复杂度O(α(n)),其中α表示Ackermann函数的反函数,单词操作平均运行时间接近于一个很小的常数

 

优先级队列(interface) Priority Queue

 

完全二叉堆 Complete Heap

 

锦标赛树 Tournament Tree

 

左式堆 Left Heap

 

串 String

 

 

经典算法

快速幂

an次方

时间复杂度O(logn)

 

countOnes

统计整数二进制展开中数位1的总数

时间复杂度O(ones),正比于数位1的总数

 

总和最大区段

从整数序列A[n]中,求总和最大的区段的和(有多个时,短者优先)

时间复杂度O(n)

 

斐波那契数列

斐波那契数列:1, 1, 2, 3, 5, 8... 求第n个数字(从1开始编号)

时间复杂度O(n)

 

最长公共子序列 LCS

Longest Common Subsequence problem 求两序列(长度分别为nm)最长公共子序列中的长度

时间复杂度O(mn)

 

就地循环移位

仅用O(1)辅助空间,将数组A[0,n)中的元素向左循环移动k个单位

 

埃氏筛法 Eratosthenes

找出1~n中所有的素数

时间复杂度O(nlogn)

 

二分查找 BS

Binary Search 有序(可能有重)数列S中查找指定值e,返回不大于e的最后一个元素。

时间复杂度O(logn)

 

findKth

无序数列S中查找第k大的元素

时间复杂度O(n)

 

排序 Sort

将无序(可能有重)数列S[lo,hi)从小到大排序

1. 冒泡排序 BubbleSort

时间复杂度:最好O(n),最坏O(n2)

2. 归并排序 MergeSort

时间复杂度O(nlogn)

3. 选择排序 SelectionSort

时间复杂度O(n2),但元素移动操作显著少于冒泡排序

4. 插入排序 InsertionSort

时间复杂度:最好O(n),最坏O(n2)

5. 桶排序 BucketSort

时间复杂度:平均O(n+n2k+k)(n),最坏O(n2)(其中n为数组元素数量,k为桶数量)

6. 基数排序 RadixSort

时间复杂度O(n)(若将位数d视作常数)

7. 堆排序 HeapSort

时间复杂度O(nlogn)

8. 快速排序 QuickSort

 

统计序列逆序对

统计序列A中逆序对的个数

时间复杂度O(nlogn)

 

最大间隙问题 MaxGap

给定n个实数x1,x2,...,xn,求这些数在实轴上相邻2个数之间的最大差值。

时间复杂度O(n)

 

进制转换

以10进制转16进制为例,自高而低输出结果

时间复杂度O(n)n为原整数位数

 

括号匹配

给定算式x,判断算式中的括号是否匹配。设只存在一种括号。

时间复杂度O(n)n为算式字符长度

 

甄别禁形(非栈混洗)

Stack Permutation 给定1~n的一个序列x,判断该序列是否为栈混洗

时间复杂度O(n)

 

表达式求值

给定含运算符和数字的表达式,求解其值

1. 中缀表达式求值 Infix Notation

时间复杂度O(n)

2. 后缀表达式求值 RPN

Reverse Polish Notation

时间复杂度O(n)

3. 中缀表达式转后缀表达式求值

 

直方图内最大矩形

H[0,n)为非负整数的直方图,求直方图内最大的矩形面积(若有多种情况同解,则取最左边的解)

时间复杂度O(n)

 

二叉树的遍历

时间复杂度O(n)

1. 前序遍历

递归写法

迭代写法

2. 中序遍历

递归写法

迭代写法

3. 后序遍历

递归写法

迭代写法

4. 层次遍历

 

Huffman算法:最优带权编码树

已知待编码的字符集ch[]及其出现频率freq[],求最优二进制编码规则使得编码后的总字符最短,输出字符集中各字符的编码。

1. 优先级队列

时间复杂度:初始化优先级队列O(n) + 建树O(nlogn) = O(nlogn)

2. 栈+有序队列

时间复杂度:排序建栈O(nlogn) + 队列建树O(n) = O(nlogn)

 

KD-tree

1. 1D Range Query

给定在x轴上的点集P=p1,p2,...,pn。对于任意给定的区间I=(x1,x2],求 ① 点集P落在区间I中的点个数,并 ② 遍历所有IP中的点

2. Planar Range Query

给定在平面上的点集P=p1,p2,...,pn。对于任意给定的二维区间R=(x1,x2]×(y1,y2],求 ① 点集P落在区间R中的点个数,并 ② 遍历所有RP中的点

下例出自DSA PA3-5 temperature

时间复杂度:建树O(nlogn) + 单次查询O(r+n)

 

Interval Tree

Given a set of intervals in general position on the x-axis: S={si=[xi,xi|1in]} and a query point qx Find all intervals that contain qx: {si=[xi,xi]|xiqxxi}

时间复杂度:建树O(nlogn) + 穿刺查询O(r+logn)

 

Segment Tree

一般情况

下例出自DSA PA 3-4-2 Kidd 长大后的黑羽快斗也成为了一位魔术师,他开始了扑克牌练习。 他首先把一叠扑克以正面朝上的姿态顺次在桌上排成一行,之后的每一次挥一挥衣袖,都会反转一连串的扑克,改变它们的正反朝向。为了检验自己的心算能力,快斗会随时问自己:目前从第i张扑克牌到第j张扑克牌(包含第i和第j张扑克牌),一共被反转过几次?

时间复杂度O(mlog(m))m为离散化叶节点数量)

 

搜索图

1. 广度优先搜索 BFS

时间复杂度O(n+e)

2. 深度优先搜索 DFS

时间复杂度O(n+e)

3. 优先级搜索 PFS

时间复杂度:更新优先级O(n+e) + 选出优先级最高者O(n2)(邻接表)

 

拓扑排序 TSort

TSort: Topological Sort;有向无环图:Directed Acyclic Graph 任给有向图G(不一定是DAG),尝试将所有顶点排成一个线性序列,使其次序与原图相容(每一顶点都不会通过边指向前驱顶点)。若原图存在回路(即并非DAG),检查并报告。否则,给出一个相容的线性序列。

顺序输出零入度顶点

时间复杂度O(n+e)

逆序输出零出度顶点

时间复杂度O(n+e)

 

最短路径

1. Dijkstra算法

给定顶点s,计算s到其余各个顶点的最短路径及长度 假定:各边权重均为正

时间复杂度O(n2)(通过其他数据结构可以优化到O(elogn),O(eloge)

2. Floyd-Warshall算法

给定带权网络G,计算器中所有点对之间的最短距离

时间复杂度O(n3)

 

最小支撑树 MST

Minimum Spanning Tree 求联通网络N=(V;E)的子图T=(V;F),使得T的总权重w(T)=eFw(e)最小

1. Prim算法

时间复杂度O((n+e)logn(优先级队列算法),O(n2)(普通PFS)

2. Kruskal算法

时间复杂度O(eloge+elogn)

 

串匹配

1. KMP算法

Knuth-Morris-Pratt

时间复杂度O(n)

2. BM算法

Boyer-Moore BM算法 = BC + GS

时间复杂度:Best Case: O(nm),Worst Case: O(n+m)

3. Karp-Rabin算法