
数据结构
五道口纳什
wx公众号/B站:五道口纳什
展开
-
图的表示
Python 数据结构与算法——图(Graph)1. 邻接矩阵 vs 邻接表(压缩的邻接矩阵)邻接矩阵的缺点是:空间占用与结点数的平方成正比,可能带来很大的浪费;邻接矩阵不容易增加新的结点,不太适合以逐步扩充的方式构造图对象;原创 2016-09-01 15:00:15 · 955 阅读 · 0 评论 -
适度平衡树
适度平衡树,是指将树高限制为“渐进地不超过 O(logn)O(\log n)”。举例:AVL 树;伸展树;红黑树;kd-树;当然这些都可以归入平衡二叉搜索树(BBST,Balanced Binary Search Tree)之列。原创 2016-09-20 07:57:10 · 1080 阅读 · 0 评论 -
伸展树(splay tree)
伸展树的设计思路,鉴于数据访问的局部性(28原则)在实际应用中普遍存在,将按照“最常用者优先”的启发策略。尽管在最坏情况下其单次操作需要 O(n)O(n) 时间,但分摊而言仍然 O(logn)O(\log n) 以内。与 AVL 树一样,伸展树也是平衡二叉搜索树的一种实现。原创 2016-09-20 10:32:04 · 864 阅读 · 0 评论 -
数据局部性(data locality)
信息处理的典型模式是,将所有数据项视为一个集合,并将其组织为适宜的数据结构(或者说使用适宜的数据结构对之进行存储以及组织),进而借助操作接口高效访问。为了考查和评价各操作接口的效率,除了从最坏情况的角度出发,也可假定所有操作彼此独立、次序随机且概率均等,也即从平均情况的角度出发。然而,实际中,后一尺度所依赖的假定条件(独立随机等概率),往往不足以反映真实的情况。原创 2016-09-20 10:53:26 · 9067 阅读 · 0 评论 -
快慢指针 —— 链表中点
使用 快慢双指针,快指针一次走两步,慢指针一次走一步,十分 tricky;原创 2016-09-23 12:20:39 · 1330 阅读 · 0 评论 -
数据结构与算法的实现 —— 结点定义与数据结构的选择
1. 图最小生成树(MST),比如在对使用( Kruskal 或 Prim)算法得到的最小生成树进行表示时,其实是把最小生成树(MST)当做一些列边的集合,进行存储。对于边而言,具有三个属性,分别是起点 viv_i 和终点 vjv_j,以及边上的信息比如权值 ww。也即最小生成树是边的集合,而边的形式是 ((vi,vj),w)((v_i,v_j), w);Kruskal 算法reps = ran原创 2016-09-02 10:58:05 · 1612 阅读 · 0 评论 -
散列:散列函数与散列表(hash table)
1. 散列函数如果输入的关键字是整数,则一般合理方法是直接返回对表大小取模(Key mod TableSize)的结果,除非 Key 碰巧具有一些不太理想的特质。如,表的大小为 10,而关键字都是 10 的倍数,显然此时都会被散列在 0 的位置。为了避免上述情况的发生,好的方法是保证表的大小是素数(除了 1 和自身没有其他的因子)。原创 2016-09-20 15:22:14 · 1159 阅读 · 0 评论 -
HashTable 解决碰撞(冲突)的方法 —— 分离链接法(separate chaining)
1. ListNode 及 HashTable 的类型声明2. HashTable 的创建原创 2016-09-21 10:17:37 · 3051 阅读 · 0 评论 -
数据结构实现时所需的成员变量、标准对外接口
1. vector2. stack@vector3. 二叉搜索树4. AVL原创 2016-09-18 18:32:01 · 1114 阅读 · 0 评论 -
二叉堆(binary heap)—— 优先队列的实现
二叉堆因为对应着一棵完全二叉树,因而可以通过线性数组的方式实现。注意,数组第 0 个位置上的元素,作为根,还是第 1 个位置上的元素作为根?本文给出的实现,以数组第 1 个位置上的元素作为根,则其两个孩子 ⇒ 2*i, 2*i+1而第 0 个位置上的元素,则用来作为标志变量(Size 不包括此变量);在元素逐个插入的过程中(插入在合适的位置),实现二叉堆的构建;自然删除也需按着指定的规则;原创 2016-09-25 18:39:27 · 1233 阅读 · 0 评论 -
从二叉搜索树到平衡二叉搜索树
1. 树高与性能一个二叉搜索树(要求有序)需要支持的主要接口有:search()insert()remove()三者的时间复杂度均正比于二叉树的高度。在最坏的情况下,所有的内部结点(根和叶子除外),均为左孩子结点或右孩子结点。此时的查找效率甚至会降至 O(n)O(n),线性正比于数据集的规模。故若不能有效地控制树高,则就实际的性能而言,相比此前的向量和列表,二叉搜索树将无法体会出明显优势。原创 2016-09-19 22:49:39 · 986 阅读 · 0 评论 -
从二叉树到完全二叉树
之所以会出现完全二叉树的概念,是因为可由此在物理上,以线性表的方式实现逻辑上的完全二叉树。1. 完全二叉树对于一棵高度为 hh 的二叉树,如果其第 00 层至 h−1h-1 层(倒数第二层)原创 2016-08-23 16:03:34 · 1924 阅读 · 0 评论 -
图的概念及性质
1. 完全图完全图:任意两个顶点(两个不同的顶点)之间都有边的图(有向图或无向图);-原创 2016-09-01 19:09:19 · 2298 阅读 · 0 评论 -
图的最短路径问题
1. 最短路径问题带权有向图或带权无向图(网络,即网络是不区分方向的)中的每条边都附有一个权值,通常用于表示实际应用中顶点之间关系的某种度量(measure),表示其关联的紧密程度,如:长度、成本、代价等等这种长度一般具有可加性,可以看做一个抽象或者泛化的“距离(distance)”;定义:从 vv 到 v′v' 的所有路径中长度最短的路径就是 vv 到 v′v' 的最短路径,最短路径的长度称为原创 2016-09-02 12:57:56 · 1394 阅读 · 0 评论 -
表达式和计算的描述
1. 前缀、中缀、后缀(3−5)×(6+17×4)/3\left(3-5\right)\times \left(6+17\times 4\right)/3中缀形式,(3-5)*(6+17*4)/3前缀形式,/ * - 3 5 + 6 * 17 4 3后缀形式:3 5 - 6 17 4 * + * 3 / 2. 说明只有中缀形式需要保留括号,前缀和后缀无符号形式下也是无歧义的;中缀形式需要原创 2016-08-12 10:37:17 · 874 阅读 · 0 评论 -
图的重要性质
图的概念及性质1. 三角不等式性对于所有的 u,v,x∈Vu,v,x\in V,都有:δ(u,x)+δ(x,v)≤δ(u,v)\delta(u,x)+\delta(x,v)\leq \delta(u,v)不等式左边的小于等于右边的 ⇒ 不等式左边的不超过不等式右边的;原创 2016-09-02 19:04:36 · 1067 阅读 · 0 评论 -
哈希表(hash table)及其应用举例
哈希表最主要的有点在于我们利用它能够在 O(1)O(1) 时间查找某一元素,是效率最高的查找方式,其缺点是需要额外的空间实现哈希表。原创 2016-03-29 17:20:46 · 1347 阅读 · 0 评论 -
成员变量的妙用
通过成员变量的引入实现更为丰富的判断。比如对于二叉树结点类型而言,通过对指向父节点的指针的引入,实现对一个结点是否为根节点的判断(父节点为空则该节点为根节点)。原创 2016-09-16 18:24:38 · 909 阅读 · 0 评论 -
二叉树 —— 中序遍历结点的后继
想要获取中序遍历时某一节点的直接后继,首先在数据结构上,结点必须维护指向父节点的指针(parent), 因为当前结点的后继有可能是其父节点, 如果其本身没有右孩子;或者本身是左孩子结点;注意对当前结点进行分类讨论原创 2016-09-17 12:55:26 · 2023 阅读 · 0 评论 -
二叉树的遍历(先序/中序/后序,递归/迭代)与搜索
遍历一个数据结构,也即逐一地处理(可读可写)其中所有元素。1. 深度优先按深度优先的方式遍历一棵二叉树,需要做三件事(可能需要处理其中的数据):遍历左子树(L);遍历根节点(D);遍历右子树(R);全排列的话,A33=6A_3^3=6,但这里一般假定先处理左子树,后处理右子树,这样,根据根节点遍历的先后顺序,仅可得到三种遍历方式。原创 2016-08-22 00:01:25 · 1115 阅读 · 0 评论 -
数据结构 Tricks(一)—— 父节点和左右孩子索引号之间的关系
如果通过对编号的设计,实现存取元素时,不必区分左孩子还是右孩子,直接就可确定其父节点的编号。原创 2016-09-25 18:48:16 · 2980 阅读 · 0 评论 -
数据结构与算法总论
缓存结构无论是栈、队列还是优先队列,都可视为一种缓存结构,可将数据元素保存其中,可以访问和弹出。原创 2016-04-17 23:58:15 · 1051 阅读 · 0 评论 -
二叉搜索树相关性质的应用
1. 顺序性(中序序列单调非降);原创 2016-09-15 12:15:10 · 959 阅读 · 0 评论 -
二叉树的常用操作(节点的后继节点)
1. 一路沿左分支遍历// BinNode<T>* x;while (x){ visit(x->data); x = x->lChild;}当然,与之相对应的右分支可以用 Stack 存储,也可以使用 Queue,视具体的程序逻辑而定;原创 2016-09-18 20:12:55 · 1553 阅读 · 0 评论 -
数据结构——红黑树(red-black tree)
红黑树在改变元素数量和元素搜索方面都很出色,它保证节点安插时最多只会做两个重新链接(relink)的动作,而且到达某一元素的最长路径的深度,至多只是最短路径的深度的两倍。STL 中的重要容器——set/multiset 通常以红黑树(red-black tree)实现。原创 2016-02-29 20:29:00 · 1770 阅读 · 0 评论 -
从多路搜索树到 B-树
当数据规模大到内存已不足以容纳时(此时就需要存放在外存中),常规平衡二叉搜索树的效率将大打折扣。其原因在于,查找过程对外存的访问次数过多。例如,若将 10910^9(1 billion = 10 亿)个记录在外存中组织为 AVL 时,则每次查找大致都需要做 30 次外存访问。那么,应该如何有效减少外存操作呢?为此需要充分利用磁盘之类外部存储器的一个特性,单就时间成本而言,读取物理地址连续的 1000原创 2016-09-20 12:47:15 · 937 阅读 · 0 评论 -
高级数据结构及应用 —— 使用 bitmap 进行字符串去重
bitmap 即为由单个元素为 boolean(0/1, 0 表示未出现,1 表示已经出现过)的数组。如果C/C++ 没有原生的 boolean 类型,可以用 int 或 char 来作为 bitmap 使用,如果我们要判断某字符(char)是否出现过,使用 int 作为 bitmap 的底层数据结构,bitmap 即为 int 数组,一个 int 长度为 32 个 bit 位, c ...原创 2018-06-03 10:34:05 · 2489 阅读 · 0 评论 -
二进制比特位运算
1. 基本运算截断保留后 k 位,比如 83 == 0x0101 0011 保留后 5 位,即为 0x0001 0011 == 19 x &amp; (pow(2, k)-1)x &amp; 0x1fa 的第 k 位清零:a &amp;= ~(1 &lt;&lt; k)a 的第 k 位置 1:a |= (1 &lt;&lt; k)...原创 2018-06-01 22:11:11 · 2925 阅读 · 0 评论 -
C++ STL 数据结构与算法 —— 排序
1. Top k 大的数排序后直接索引输出:O(nlogn)O(nlogn)O(n\log n)std::sort(v.rbegin(), r.rend());return v[k-1];使用优先队列(O(klogn)O(klogn)O(k\log n),每 pop 一个元素,都需重排大顶堆):std::priority_queue<int> PQ(v.rbegi...原创 2018-07-07 17:43:49 · 2245 阅读 · 0 评论 -
位图(bitmap)—— C语言实现
位图应当具备的置一,清零,以及判断三大功能:#define BITS_PER_WORD 32#define MASK 0x1f#define SHIFT 5 // BITS_PER_WORD 与 MASK、SHIFT 是相匹配的, // 如果 BITS_PER_WORD 为 8,则 SHIFT 为 3,MASK 为 0x07 ...原创 2018-07-13 20:38:50 · 5259 阅读 · 0 评论 -
n 中选 m —— 随机采样的艺术
1…n 中个数随机取 m 个数,要求 1…n 中被取到的概率相同:Knuth 书中的随机数方法,很容易写出:void genkunth (int n, int m) { for (int i = 0; i &lt; n; ++i) { if (bigrand() % (n-i) &lt; m) { m--; cout ...原创 2018-07-13 21:17:54 · 1977 阅读 · 0 评论 -
图的度与握手定理
在一个教职工聚会上,与会者互相握手问候彼此,每位教授会记住他/她握手的次数(以图做建模,不同的教授代表不同的点,握手表示一个边的建立,两个顶点的连接,显然是无向图,A 与 B 握手 = A 同 B 握手 + B 同 A 握手)。在聚会的最后,系主任将所有教授握手的次数相加。通过证明下面的握手定理来说明系主任得到的结果是偶数原创 2017-07-03 08:40:47 · 3237 阅读 · 0 评论 -
图与自由树
树和图是不同的但有着密切联系的两种数据结构。自由树,是一个连通的、无环的无向图。一般情况下,我们提到一个图是树时,会省略掉形容词“自由”。称一个可能不连通的无向无环图为森林。许多树的算法对森林也适用。1. 自由树的若干性质令 G=(V,E)G=(V, E) 是一个无向图,下面的描述是等价的,GG 是自由树;GG 中任何两顶点由唯一简单路径相连;GG 是连通的,但从图中移除任意一条边得到的图均不原创 2017-07-03 08:23:00 · 2024 阅读 · 0 评论 -
数据结构实现时的注意事项
1. 普通队列与循环队列 对于循环队列而言,它的队列头(head)指向的就未必是物理上的第一个位置,而可以是物理上的任意位置。原创 2016-08-30 17:54:47 · 1297 阅读 · 0 评论 -
从二叉堆到左式堆
设计一种类似二叉堆的堆结构,能高效地支持合并操作(即以 O(N)(最坏) 的时间处理一次 Merge),而仅使用一个数组(经典二叉堆的实现)似乎很难。 原因在于,合并似乎需要把一个数组拷贝到另一个数组中去,对于相同大小的堆这将花费 Θ(N)\Theta (N)。正因如此,所有支持高效合并的高级数据结构都需要使用指针。原创 2016-10-01 22:29:15 · 1109 阅读 · 0 评论 -
区间树(segment tree)
区间树能够对保存的数据进行适当的预处理,以快速回复查询。区间树常用于在一维数组的特定区间对查询进行快速回复。区间树的最典型也是最简单的应用就是求区间最小值的问题。区间树的基本思路是,生成表示给定数组各区间的二叉树。原创 2016-10-19 18:55:31 · 3153 阅读 · 0 评论 -
树 —— 总论
真二叉树(proper binary tree):不含一度结点的树(只有 0 度和 2 度的结点);原创 2016-09-16 15:22:21 · 1101 阅读 · 0 评论 -
四叉树问题
四叉树(quad tree)数据结构能把大量数据压缩保存到内存空间,它总是将给定空间分割为 4 个, 然后以递归形式表示,故得名四叉树。其最著名的应用就是对黑白图像(当然也可以是任何一个二值图像)的压缩。四叉树会以字符串的形式对 2N⋅2N2^N\cdot 2^N 的黑白图像进行如下压缩,图像的所有像素为黑色,则无论图像的大小是多少,四叉树在该分支上的压缩结果都是 b(black)图像的所有像素原创 2016-09-07 11:00:33 · 3745 阅读 · 0 评论 -
Python 数据结构与算法 —— Kruskal 算法
1. 朴素版# 查def naive_find(C, u): while C[u] != u: u = C[u] return u# 并 def naive_union(C, u, v): u = naive_find(C, u) v = naive_find(C, v) C[u] = vdef naive_kruskal(G):原创 2016-04-06 17:57:32 · 3354 阅读 · 1 评论 -
最小生成树(MST,minimum spanning tree)
生成树:由图生成的树,由图转化为树,进一步可用对树的相关操作来对图进行操作。最小指的是权值最小;生成树是边的集合,如下图所示的最小生成树:MST={{a,b},{a,f},{f,c}}\text{MST}=\{\{a,b\},\{a,f\},\{f,c\}\} 本文主要探讨带权无向连通图(网络)上的最小生成树问题,以及求最小生成树的两个算法。0. 生成数nn 个顶点的图,有 n−1n-1 棵生原创 2016-09-02 08:12:35 · 3370 阅读 · 0 评论