数据结构
文章平均质量分 75
guoziqing506
这个作者很懒,什么都没留下…
展开
-
自序:我为什么写这样一个博客
有时我在想,我活在这个世界上,到底追求的是什么呢?抛开金钱,美女二者不谈,还剩下的,只怕是做一点自己喜欢的事情。写这个博客,在我个人看来,就是个有趣的事。我打小脑子并不算太好使,虽不说“冥顽不化”,但也绝对不是“玲珑剔透”。到了高考,和智商最相关的数学就自然而然,成为我最差的一门。我曾经幻想,我终于可以上大学了,终于不用纠结于令我“发指”的数学了。然而,上天总会给人开各种令你“哭笑不得原创 2016-03-21 19:35:28 · 1088 阅读 · 3 评论 -
并查集(Union-Find)算法详解
并查集(Union-Find)是解决动态连通性问题的一类非常高效的数据结构。本文中,我将尽我所能用最简单,最清晰的逻辑展示出并查集的构造过程,同时还将对其中的关键步骤给出相应的Python代码。动态连通性可以想象一张地图上有很多点,有些点之间是有道路相互联通的,而有些点则没有。如果我们现在要从点A走向点B,那么一个关键的问题就是判断我们能否从A走到B呢?换句话说,A和B是否是连通的。这是动态连通性最原创 2017-12-08 16:15:05 · 56842 阅读 · 6 评论 -
Bloom Filter原理与实现
在做与Web爬虫有关的任务时,经常这样需要做这样的判断:对于新爬到的URL,我们需要判断这个新的URL是否已经在已有的URL集合中存在了。但是当已经存在的URL集合的数据量极其庞大时,这个存在性的判断工作就变得很有挑战性。把这个问题抽象出来,就是说:现在需要一种算法(工具),帮助我们实现一种高效而准确的,元素针对集合的存在性判断。为了解决上面说的这一类问题,人们从简入难,想出了很多办法:原创 2016-10-19 22:37:31 · 2942 阅读 · 0 评论 -
简单理解KMP算法
KMP算法是迄今为止最为高效的字符串匹配算法。当然,在KMP算法出现之前,有关字符串的匹配问题当然经过了一个漫长的探索过程。从一开始最简单的朴素字符串匹配算法,到Rabin-Karp算法,再到有限自动机算法等等,可以说任何一个伟大算法的诞生都不可能是一朝一夕之功,在它之前一定有大量的理论及实验的基础。所以,想要彻底理解KMP算法最好是从头开始,对整个字符串的匹配问题有个完整的了解。但是,我在这篇博文原创 2016-08-09 14:53:41 · 1423 阅读 · 1 评论 -
Kd-tree原理与实现
数据应用当中,最近邻查询是非常重要的功能。不论是信息检索,推荐系统,还是数据库查询,最近邻查询(Nearst Neighbor Search)可谓无处不在。它要实现的是帮助我们找到数据中和查询最接近的一个或多个数据条目(前者叫NN search, 后者也叫kNN),其实本质上是一样的,我在这篇博客中讲的Kd-tree主要是针对NN问题的。其实,这种问题本来是很容易解决的,只要设计好了数据相似度原创 2017-02-24 17:24:37 · 22264 阅读 · 6 评论 -
计算几何问题汇总--圆与矩形
我在上一篇博客中(详见:计算几何问题汇总–点与线的位置关系)谈到了计算几何最基本的问题:解决点与线(线段or直线)的位置关系判断。那么,更进一步,还需要探讨复杂一点的情况:比如面与线,面与面之间的关系。本文中,我就先说说最常见的两种几何图形:圆与矩形。我将就矩形与圆的碰撞判断问题、线与矩形、线与圆之间的碰撞问题作出分析,以及给出这些解决问题的算法、代码。在此之前,我默认所有对本文内容感兴趣的读者,都原创 2016-10-07 20:28:34 · 4886 阅读 · 1 评论 -
赫夫曼编码原理与实现
1951年,Huffman在MIT信息论的同学需要选择是完成学期报告还是期末考试。导师Robert M. Fano给他们的学期报告的题目是,寻找最有效的二进制编码。由于无法证明哪个已有编码是最有效的,Huffman放弃对已有编码的研究,转向新的探索,最终发现了基于有序频率二叉树编码的想法,并很快证明了这个方法是最有效的。由于这个算法,学生终于青出于蓝,超过了他那曾经和信息论创立者香农共同研究过类似编原创 2016-10-11 16:10:58 · 4107 阅读 · 0 评论 -
最大公约数、欧几里得算法与求解模线性方程
最大公约数是指两个或多个整数的约数中最大的一个。这个概念在小学时代,我们就已经知道了。但是今天依然把这个问题拿出来,是因为由最大公约数引发的一系列问题,成为了公钥密码学的基础,所以有必要对此类问题的来龙去脉再做一个了解。原创 2016-10-10 11:47:54 · 2226 阅读 · 0 评论 -
堆的实现与优先队列
堆(Heap)这种数据结构对我们来说是极为有用的。因为它可以非常方便地帮我们完成高效的动态的排序。接下来,我将给出堆的原理以及实现堆的具体操作。先看一下堆的结构,在此,只需要牢记两点:1. 堆是一棵完全二叉树2. 堆中每个节点都大于等于其任何子节点所谓完全二叉树,一定要满足这个特征:这棵树除最后一层外,每一层都是满的,且最后一层如果不满,所有节点都位于最左边。看下图原创 2016-08-31 09:34:18 · 888 阅读 · 0 评论 -
深度优先搜索
深度优先搜索(Depth First Search)是一种遍历图中节点的策略,顾名思义,其核心思想是:只要可能,就在图中尽可能“深入”。具体来说,我们从图中一个节点出发(可以设这个节点为V1),按照某种策略寻找到V1的一条出发边,延出发边找到下一个节点(设为V2),再按照刚才的策略,找到v2的一条出发边,再去找新的节点。。。以此类推,直到不能再“深入”了(方便起见,我现在假设搜索到了节点Vn,上一原创 2016-04-14 13:34:03 · 1370 阅读 · 0 评论 -
快速排序
快速排序:输入:乱序n长数组输出:排序好的n长数组时间复杂度:O(nlogn)空间复杂度:O(1)快速排序的基本逻辑是这样的:每次随机挑选一个数组的元素,作为“枢轴”,然后扫描数组中其他的所有元素,将小于枢轴的,排列在枢轴的左侧,大于枢轴的,排列在枢轴的右侧。然后再分别对枢轴左右两侧的部分数组进行快速排序(这是一个递归的逻辑),这样,当递归运算“触底”后(每次需要快排的原创 2016-03-22 08:27:20 · 1005 阅读 · 0 评论 -
桶排序
百度百科上对于桶排序的描述是这样的:桶排序 (Bucket sort)或所谓的箱排序,是一个排序算法,工作的原理是将数组分到有限数量的桶子里。每个桶子再个别排序(有可能再使用别的排序算法或是以递归方式继续使用桶排序进行排序)。说的更清楚一些,可以这样理解:假设现在全国有500w考生参加考试,我们现在需要对所有考生的成绩进行排序,那么即便用我们前面讲过的“归并排序”,“快速排序”等方原创 2016-03-22 08:31:16 · 1128 阅读 · 0 评论 -
排序
排序算法属于算法基本功,单论难度,都是非常简单的。所以经常作为算法的入门,作为新手来说,可以作为初始的学习材料。训练排序主要的目的,是了解基本的排序原理和将算法编写为代码的基本方法。 大致来说,常见的排序算法有以下几种:冒泡排序(Bubble Sort);选择排序(Selection Sort);插入排序(Insertion Sort );归并排序(Merge Sort);快速排序(Q原创 2016-03-21 19:43:00 · 662 阅读 · 0 评论 -
冒泡排序与选择排序
冒泡排序(Bubble Sort):输入:乱序n长数组输出:排序好的n长数组时间复杂度:O(n^2)空间复杂度:O(1)冒泡排序的原理是对数组多次扫描,每次扫描都对相邻的两个元素的顺序进行调整。假设我们按升序排列数组,那么相邻两个元素中如果左边的元素大于右边的元素,就交换这两个元素位置,否则不交换。依次扫描过数组中全部元素。可见第一次扫描就使得数组的最大值排在了数组的最原创 2016-03-21 19:57:24 · 937 阅读 · 0 评论 -
插入排序
插入排序(Insertion Sort):输入:乱序n长数组输出:排序好的n长数组时间复杂度:O(n^2)空间复杂度:O(1)插入排序原理与冒泡排序和选择排序(关于这两种排序见我上一篇博客)是类似的,都是通过多次对数组扫描完成,不同的是,插入排序需扫描的部分数组的长度是不断递增的,因为它是通过不断向已经排序好的数组中插入新的元素完成排序的,随着插入元素的递增,数组长度递原创 2016-03-21 20:07:21 · 815 阅读 · 0 评论 -
归并排序
归并排序:输入:乱序n长数组输出:排序好的n长数组时间复杂度:O(nlogn)空间复杂度:O(n)我们已经学习了冒泡排序,选择排序与插入排序。深究这几种方法的原理,都是通过反复扫描数组,调整数组内元素的排列顺序来实现的。那么有没有其他思路呢?我们来看归并排序的方法。其实,就排序本身讲,归并排序并不是效率最好的(其空间复杂度高于后面要讲的快速排序),但是学习归原创 2016-03-21 20:18:18 · 1160 阅读 · 0 评论 -
链表简述
其实学习编程的时候,一开始差不多都是先写出“hello, world”,其后就开始接触数组了,因为使用计算机完成计算的一个重大优势就是可以进行批量处理(想一想用手算或者使用普通计算器是做不到这一点的),而将要处理的数据存储在一个数组里面就实现了这种功能。数组是最基本的数据结构,他是顺序存储数据的,也就是说,每个数据在数组当中都有一个隐含的索引(基本上都是从0开始的所谓数组的下标),下标加上数据本身原创 2016-04-28 13:55:22 · 1100 阅读 · 0 评论 -
递归(斐波那契数列)
递归是一种极为常用的编程思想。比较官方的解释是“可以在函数内部,直接或间接地调用函数自身”,我一般把他称为“一种有技术含量的偷懒算法”。为什么这么说呢?因为递归函数不需要我们对运算过程的每一步的细节了解详细,而只需要我们知道两点:1. 函数是如何“升级”的。也就是这一步需要解决的问题与其子问题之间的关系2. 函数到什么位置“触底”,“触底”后返回什么?原创 2016-04-04 19:26:47 · 1400 阅读 · 0 评论 -
B树与B+树
B树是为实现高效的磁盘存取而设计的多叉平衡搜索树。这个概念在文件系统,数据库系统中非常重要。当然,有关于B树的产生,发展,结构等等方面的介绍已经非常详细,所以本文只是介绍有关于B树和B+树最核心的知识点,也算是我本人的学习笔记。至于详细的资料,因为毕竟有着太多,所以不再赘述。可以向大家推荐一篇博客:从B树、B+树、B*树谈到R 树,这篇文章中,作者对于B树系列数据结构的讲解非常详细,我的这篇博客,原创 2017-03-20 15:59:33 · 68449 阅读 · 22 评论