随笔分类 - 【190】数据结构与算法
摘要:一、传统哈希取模算法的局限性 简单地说,哈希就是一个键值对存储,在给定键的情况下,可以非常高效地找到所关联的值。 要了解一致性哈希,首先我们必须了解传统的哈希及其在大规模分布式系统中的局限性。 当数据太大而无法存储在一个节点或机器上时,系统中需要多个这样的节点或机器来存储它。比如,使用多个 Web 
        阅读全文
                
摘要:我们日常使用压缩和解压软件的频率可谓是非常高,而最基本的压缩算法 —— 赫夫曼编码,其中使用的二叉树就是赫夫曼树。在介绍赫夫曼编码之前,我们先来介绍赫夫曼树。 什么是赫夫曼树 我们通过一个例子来引入什么是赫夫曼树。 我们在中小学每年期末考试结束后都会领到成绩单,成绩单上列出我们考试分数的等级,比如优
        阅读全文
                
摘要:十大经典排序算法 菜鸟教程链接 排序算法是《数据结构与算法》中最基本的算法之一。 排序算法可以分为内部排序和外部排序,内部排序是数据记录在内存中进行排序,而外部排序是因排序的数据很大,一次不能容纳全部的排序记录,在排序过程中需要访问外存。常见的内部排序算法有:插入排序、希尔排序、选择排序、冒泡排序、
        阅读全文
                
摘要:堆和堆的构建 什么是堆 堆是一种特殊的二叉树,具备以下特性: 堆是一个完全二叉树 每个节点的值都必须大于等于(或小于等于)其左右孩子节点的值 如果每个节点的值都大于等于左右孩子节点的值,这样的堆叫大顶堆;如果每个节点的值都小于等于左右孩子节点的值,这样的堆叫小顶堆。 上图中,左侧的堆是大顶堆,右侧的
        阅读全文
                
摘要:前面几篇分享中我们陆续介绍了平衡二叉树的定义、实现原理、构建过程演示以及对应的实现代码,我们提到平衡二叉树是最理想的二叉排序树,性能最好,也最稳定,但是缺点是维护成本高,需要在插入和删除节点时维护新树的平衡性,所以工程实践中,我们倾向于使用另一种二叉排序树 —— 红黑树,什么是红黑树?红黑树的性能如
        阅读全文
                
摘要:引子 上一篇我们介绍了二叉排序树,并且提到理想情况下,二叉排序树的插入、删除、查找时间复杂度都是 ,非常高效,而且它是一种动态的数据结构,插入删除性能合查找一样好,不像之前提到的二分查找,虽然查找性能也是 ,但是需要先对线性表进行排序,二排序的最好时间复杂度也是 ,所以二分查找不适合动态结构的排序。
        阅读全文
                
摘要:为什么要引入二叉排序树 我们前面已经介绍了很多数据结构,比如数组、链表、散列表等,数组查找性能高,但是插入、删除性能差,链表插入、删除性能高,但查找性能差,在不考虑散列冲突的话,散列表的插入、删除、查找性能都很高,但是前提是没有散列冲突,此外,散列表存储的数据是无序的,散列表的扩容非常麻烦,涉及到散
        阅读全文
                
摘要:二叉树的定义及其特性 树的相关概念 树这种数据结构模拟了自然界中树的概念,自然界中的树有根、叶子、枝干,数据结构中的树也是如此,只不过是倒过来的: 其中的每个元素叫做节点。树的顶点(没有父元素的节点)叫根节点,如 E;每个分支的末端节点(没有子元素的节点)叫叶子节点,如 G、H、I、J、K、L;用来
        阅读全文
                
摘要:今天开始,我们将花三篇文章的篇幅由浅及深地介绍几个字符串匹配算法,首先从最简单的字符串匹配算法 —— BF 算法说起,BF 是 Brute Force 的缩写,中文译作暴力匹配算法,也叫朴素匹配算法。 BF算法(暴力匹配算法) BF 算法的原理很简单,在继续介绍之前,我们先引入两个术语: 主串和模式
        阅读全文
                
摘要:散列表 散列表(HashTable,也叫哈希表),是根据键(Key)直接访问在内存存储位置的数据结构。 其实现原理是: 通过散列函数(也叫哈希函数)将元素的键映射为数组下标(转化后的值叫做散列值或哈希值),然后在对应下标位置存储记录值。当我们按照键值查询元素时,就是用同样的散列函数,将键值转化数组下
        阅读全文
                
摘要:插入查找 $container[ $middle ]) { $lower = $middle + 1; } else { return $middle; } } return false; } // + // | 方案测试 | php || PHPStorm 右键 Run // + echo ins
        阅读全文
                
摘要:前面我们提到的二分查找适用于有序线性表的查找,此外针对二分查找还有升级版的插值查找,以及利用斐波那契原理进行查找的斐波那契查找,在后面的随笔里会补充对应的实现,一般我们使用二分查找就可以了。 我们也提到二分查找不适用于高速增长的海量数据,因为维护这个排序非常麻烦,所以我们引出索引这种数据结构。 索引
        阅读全文
                
摘要:二分查找的引入 在介绍二分查找之前,对于基于数字索引的数组元素的查找,我们可能第一反应都是遍历这个数组,直到给定数组元素值和待查找的值相等时,返回索引值并退出,否则一直遍历到最后一个元素,如果还是没有找到则返回 1,这样的查找虽然是简单粗暴了点,但是对于规模不大的数据集,也是没什么问题的,不过很明显
        阅读全文
                
摘要:快速排序 实现原理 归并排序算法虽好,但是不是原地排序算法,需要消耗额外的内存空间,今天我们要介绍的是常规排序里综合排名最高的排序算法:快速排序,江湖人称「快排」。 快排的核心思想是这样的: 如果要排序数组中下标从 p 到 r 之间的一组数据,我们选择 p 到 r 之间的任意一个数据作为 pivot
        阅读全文
                
摘要:归并排序 实现原理 所谓归并排序,指的是如果要排序一个数组,我们先把数组从中间分成前后两部分,然后对前后两部分分别排序,再将排好序的两部分合并在一起,这样整个数组就都有序了。 归并排序使用了分治思想,分治,顾名思义,就是分而治之,将一个大问题分解成小的子问题来解决。说到这里,可能你就能联想起我们之前
        阅读全文
                
摘要:选择排序 实现原理 选择排序算法的实现思路有点类似插入排序,也分已排序区间和未排序区间。但是选择排序每次会从未排序区间中找到最小的元素,将其放到已排序区间的末尾。图示如下: 同样,可以在 VisuAlgo 上看动态图:https://visualgo.net/zh/sorting。 示例代码 选择排
        阅读全文
                
摘要:插入排序 实现原理 插入排序的原理是:我们将数组中的数据分为两个区间,已排序区间和未排序区间。初始已排序区间只有一个元素,就是数组的第一个元素。插入算法的核心思想是取未排序区间中的元素,在已排序区间中找到合适的插入位置将其插入,并保证已排序区间数据一直有序。重复这个过程,直到未排序区间中元素为空,算
        阅读全文
                
摘要:常见基于选择的排序算法有冒泡排序、插入排序、选择排序、归并排序和快速排序,我们在选择排序算法的时候,通常会根据以下几个维度来考虑: 1. 时间复杂度 2. 空间复杂度(对内存空间的消耗) 3. 算法的稳定性(如果待排序的序列中存在值相等的元素,经过排序之后,相等元素之间原有的先后顺序不变) 我们首先
        阅读全文
                
摘要:介绍完数组和链表,以及两个特殊的线性结构栈和队列后,已经算是迈入了数据结构的门了,后面很多其他更复杂的数据结构都会基于数组和链表来实现,比如散列表、树、图等,有些甚至需要结合数组和链表来实现,在继续介绍后续复杂的数据结构之前,我们穿插进来一些常见的排序算法和查找算法,在系统介绍这些算法之前,我们先来
        阅读全文
                
摘要:另一种跟栈很相似的数据结构 —— 队列,和栈一样,队列也是一中特殊的线性表结构,只不过队列是在一端插入,另一端删除,就跟我们平常排队一样的道理,从队尾入队,在队头出去,所以队列的特性是先入先出(FIFO),允许插入的一端叫队尾,允许删除的一端叫队头。 一张图可以形象的体现两者的差别: 队列 和栈一样
        阅读全文
                

 
         浙公网安备 33010602011771号
浙公网安备 33010602011771号