liufeng2023
日拱一卒
展开
-
484-红黑树
红黑树:红黑树和AVL树的对比:红黑树也是一棵二叉搜索树。 满足每个节点的左子树的值都小于节点的值,节点的值都小于节点的右子树的值。(上面画的10和30不准确)红黑树的5个性质:面试问题:在红黑树中,节点的左右子树的高度差最多不能超过多少?根节点root分别到叶子节点1, 2,假设下面这种极端的情况:所以在红黑树中,长的最多不能超过短的2倍。我们还是按照BST树的插入方式进行的:只是增加了条件(需要满足红黑树的5个性质):如果父亲是红色节点,造成连续的红色节点,我们进行插入的调整如下:我们要新插入节点原创 2022-08-07 10:55:48 · 774 阅读 · 0 评论 -
314-哈夫曼树和哈夫曼编码
最佳判定树,最优二叉树。哈夫曼树又称为最佳判定树、最优二叉树,是一种带权路径长度最短的二叉树,常用于数据压缩。所谓树的带权路径长度,就是树中所有的叶子节点的权值乘以 其到根节点的路径长度,因此树的带权路径长度记为WPL = (W1 * L1 + W2 * L2 + W3 * L3 + … + Wn * Ln),N个权值Wi(i=1,2,…,n)构成一颗有N个叶子节点的二叉树,相应的叶子节点的路径的长度是Li(i=1,2,…,n)。(W1: 第一个叶子节点的权值L1: 第一个叶子节点到根路径的长度)重要概念原创 2022-06-02 23:20:59 · 745 阅读 · 0 评论 -
300-倒排索引的理论和实现
倒排索引的理论和实现1、应用场景1.1、百度,google等搜索引擎我们在打开百度,或者是谷歌,360浏览器,我们输入关键字以后;浏览器作为客户端把关键字发到对应的搜索引擎的服务器server端,服务器去分析这个关键字,在全网的所有网页html中(几千万,上亿个文件)中快速搜索出我们想要的内容;我们输一个关键字,敲一个回车,很快的所有的搜索结果都出来了,不到1秒的时间内搜索几千万个网页。为什么搜索这么快?依赖倒排索引!我们在自己的电脑上去搜索一个文件,速度却非常的慢,有时候几十分钟都搜索不原创 2022-05-31 21:49:43 · 279 阅读 · 0 评论 -
289-跳跃表SkipList
1、跳跃表SkipList介绍跳跃表性质:由很多层链表组成每一层都是一个有序的链表最底层(level 1)的链表包含所有元素如果一个元素出现在level i层的链表中,则它在level i之下的链表也都会出现每个节点都包含两个指针,一个指向同一链表中的下一个元素,一个指向下面一层的元素跳跃表的增加、删除、查询操作时间复杂度和红黑树一样,也是O(logn)。相比于红黑树,它的优势是:实现起来更加简单跳跃表的增加、删除操作只会改动局部,不像红黑树的增加、删除操作,因为需要节点重新着色和原创 2022-05-29 22:59:00 · 226 阅读 · 0 评论 -
272-Trie字典树、前缀树、单词查找树
Trie字典树、前缀树、单词查找树1、字典树理论讲解我们在浏览器上输入一个关键字时,浏览器都支持:当你正在输入关键字的时候,一边输入,它的下边的输入栏里就会给你自动的提醒,以你现在输入的串的前缀的所有可能出现的关键字都给你列出来了,你可以进行快速的选择,那现在有1千万个串,甚至1亿个串,如果现在输入个”abc“,怎么能够快速的把这个以abc开头的所有的关键字,串显示出来呢???(IDE的代码提示也是这样)如果说是每次输个abc,再去搜这1亿个串,哪怕是用一个哈希表,都没有那么快速的,因为你要搜的是原创 2022-05-24 22:56:33 · 123 阅读 · 0 评论 -
262-基数排序(桶排序)算法的思想和性能分析
基数排序算法的思想和性能分析基数排序算法的思想基数排序也称作: 桶排序思想: 把所有元素的个位进行排序,然后十位进行排序,然后百位进行排序,依次向高位递进,最后得到一个全局的小到大或者大到小的序列。我们看下面序列:如果每次比较的都是1位的话,比如说57和54,先比较个位,7大于4,十位,是5==5,也就是说,每次比较的这一位的话,取值范围就是0-9我们现在对下面这个序列进行桶排序:从左向右,依次遍历原始的数据,最开始,是个位进行比较43的个位是3,我们把43放在3号桶,47的个位是7原创 2022-05-21 16:34:43 · 256 阅读 · 0 评论 -
258-排序算法常见问题
算法库的头文件#include <algorithm>问题1:STL中的sort用的是什么排序算法sort源码:提供了2个版本。一个是使用less函数对象的从小到大版本:另外一个是你可以传入一个函数对象:里面主要调用的是_Sort_unchecked函数:sort主要采用的是快排:优化1:当元素个数小于32个:插入排序(快排是让元素越来越有序)优化2:堆排序_Ideal <= 0时,采用堆排序。_Ideal传进来的时候是元素的个数每进行一次递归原创 2022-05-20 23:21:06 · 216 阅读 · 0 评论 -
257-希尔&快排&归并&堆排-性能测试
希尔&快排&归并&堆排-性能测试代码#include <iostream>#include <algorithm>using namespace std;//堆的下沉调整void siftDown(int arr[], int i, int size){ int val = arr[i]; while (i < size / 2) { int child = 2 * i + 1; if (child + 1 < size原创 2022-05-20 21:52:57 · 273 阅读 · 0 评论 -
249-堆排序算法的思想和性能分析
1、堆排序算法的思想如果我们要从小到大排序,实现的就是大根堆如果我们要从大到小排序,实现的就是小根堆我们实现的是从小到大排序:首先,题目给我们的是一组原始的未排序的序列,我们把存在数组中的元素,在逻辑上看成1个二叉堆!我们要做的第一件事是:第1个非叶子节点的下标:(最后一个节点的下标-1)/2,就是图中的值为8的节点。然后进行一个大根堆的调整,和它的孩子进行比较进行判断,看看要不要下沉调整。大根堆: 当前节点的值要大于它的两个孩子,如果孩子的值大于当前节点,要和当前节点进行交换。原创 2022-05-19 23:20:54 · 238 阅读 · 0 评论 -
248-优先级队列的实现
优先级队列的实现默认是大根堆!#include <iostream>#include <functional>#include <stdlib.h>#include <time.h>using namespace std;//优先级队列实现(默认是大根堆) priority_queue(vector) push pop top empty sizeclass PriorityQueue{public: using Comp =原创 2022-05-19 21:39:22 · 122 阅读 · 0 评论 -
232-二叉堆&大根堆&小根堆理论
1、二叉堆介绍优先级队列,C++的容器适配器,底层是默认实现的大根堆结构。二叉堆,这个堆本身还是用数组存储着元素,物理上还是用数组存储的元素,只不过在逻辑上把它看成有1个入口的根节点,每1个节点都有2个孩子,没有孩子的最下面一层叫叶子节点,这样的一棵二叉树结构。完全二叉树的概念:下面这个新增加了一个10,不是完全二叉树!完全二叉树的好处:存储节点,可以省数组的内存空间。为什么我们可以把物理上用数组存储元素,在逻辑上看作一棵完全二叉树呢?我们看图中的数组存储元素从0号位置开始,原创 2022-05-17 23:01:02 · 486 阅读 · 0 评论 -
226-归并排序算法的思想和性能分析
归并排序算法的思想和性能分析1、归并排序算法的思想归并排序算法不仅仅可以做内排序(内存上的排序),还可以做外排序(磁盘上文件的数据的排序)归并排序算法: 归就是递归的归,递的过程是缩减数据规模到头,规模小到结果是已知的,然后归的过程是在计算各个规模的结果,累计出原始数据规模的结果。以递归的方式实现,在归的过程进行数据的合并,达到排序效果!我们看下面这一行待排序的序列要归并,首先要先递,递的过程是在缩小数据规模,对于数组来说,缩小数据规模就是缩小起始和末尾下标的数据的长度,递到序列里原创 2022-05-17 06:54:34 · 365 阅读 · 0 评论 -
221-快速排序算法的思想和性能分析
1、快速排序算法的思想下面是一组待排序的序列,我们现在要使用快速排序算法的思想解决。1、我们选取基准数,我们把第一个数字当做基准数进行元素的调整,对于数组来说,我们要涉及1个范围,用起始下标和末尾下标。我们用L表示左边的起始下标,R表示右边的起始下标我们用val=46,即首元素,作为基准数2、从R开始往前遍历,找第一个小于基准数val=46的数字,放到L的地方,53不小于基准数46,所以我们让R- -,R访问到65这个元素;65不小于基准数46,所以我们让R- -,R访问到32这个原创 2022-05-16 22:44:46 · 231 阅读 · 0 评论 -
210-冒泡&选择&插入&希尔算法性能统计
1、性能测试代码#include <iostream>#include <stdlib.h>#include <time.h>using namespace std;//希尔排序void ShellSort(int arr[], int size){ for (int gap = size / 2; gap > 0; gap /= 2)//100W 19 1000W 24 { for (int i = gap; i < size; i原创 2022-05-14 20:09:54 · 126 阅读 · 0 评论 -
209-希尔排序算法的思想和性能分析
1、希尔排序算法的思想和性能分析希尔排序可以认为是插入排序的一个优化,升级。如果数据序列从大的方向,从全局看,已经是趋于有序的,那么插入排序是所有排序算法中效率最高的。希尔排序就是从插入排序的这句中总结优化的,它以自己最大的能力在全局中不断地把数据调整成趋于有序的,这样使得插入排序效率就越来越高。插入排序是按顺序从左到右,依次定位到元素,然后在前面已排序的序列中找到合适的位置插入。0也就是说,随着插入排序的进行,只是前面那部分是有序的,从整体上表现出来,并不是越排越有序。而希尔排序对插入排序的优原创 2022-05-14 20:08:23 · 384 阅读 · 0 评论 -
208-插入排序算法的思想和性能分析(重要)
1、插入排序算法的思想特点: 从第二个元素开始,把前面的元素序列当作已经有序的,然后找合适的位置插入。优点: 插入排序是普通排序里面效率最高的排序算法,而且在数据越趋于有序的情况下,插入排序的效率是最高的。对于插入排序算法来说,不仅仅没有交换,而且比较的次数也少!插入排序: 每次会把前面的一组序列当做已经排序好的,然后把后面的元素,按照有序的方式插入到前面的序列就可以了。具体该怎么做呢?下面这是我们原始的一组待排序的序列。我们认为第一个元素25本身就是有序的序列,因为就一个元素25原创 2022-05-14 19:03:13 · 1045 阅读 · 0 评论 -
202-选择排序算法的思想和性能分析
1、选择排序特点及缺点特点: 每次在剩下的元素中选择值最小的元素,和当前元素进行交换。缺点: 相比于冒泡排序,交换的次数少了,但是比较的次数依然很多。2、选择排序算法的思想假如说,我们现在有一组未排序的序列:先定位到元素65,也就是说,从数组的0号位置开始,定位0号位置的元素。除我们定位的元素之外,在其后边的所有元素中去找一个最小值,然后和当前定位的元素进行交换。也就是说,每一次我们都要选择出来1个最小的元素放在定位的位置。我们是从0号位置65开始定位的。接下来,然后遍历65后面原创 2022-05-13 20:52:32 · 349 阅读 · 0 评论 -
201-冒泡排序算法的思想和性能分析(时间、空间复杂度 & 稳定性)
1、冒泡排序特点: 相邻元素两两比较,把值大的元素往下交换。缺点: 数据交换的次数太多了。2、冒泡排序算法的思想上图是无序的数据,要进行排序。冒泡排序就是:每一趟都是从开始的这个元素,两两进行比较,把大的元素往下交换(沉淀到底),把小的元素往上交换(冒泡);每一趟操作的数据都是除去前面的每一趟沉淀到底的数据之外的数据;每一趟处理的方式是一样的,只是数据量是不同的。第一趟:从开始的这个元素,两两进行比较,把大的元素往下交换(沉),把小的元素往上交换(冒泡)第一趟下来,整体没排序原创 2022-05-13 19:37:56 · 2169 阅读 · 1 评论 -
198-二分搜索算法(折半查找)
如果数据序列是无序的,我们采用的是线性搜索,时间复杂度是O(n)1、二分搜索算法(折半查找)—原理是基于有序序列的搜索我们定义2个下标,first和last;first初始值是0,last初始值是10每次进行搜索,采用的策略是:首先,计算出1个中间值:(0+10)/2=5然后把中间的值57和我们要搜索的元素val值比较如果我们要搜索的元素的值是57,等于这个中间值,那么就找到了。如果我们要搜索的元素的值大于这个中间值57因为是数据有序的序列,所以我们要搜索的元素值大.原创 2022-05-12 18:32:59 · 265 阅读 · 0 评论 -
190-AVL树-下(插入 & 删除操作)
1、AVL树insert插入代码实现AVL树也是一颗BST树,在BST树的插入基础上进行的!!#include <iostream>using namespace std;//AVL树 二叉平衡搜索树template<typename T>class AVLTree{private: //定义AVL树节点类型 struct Node { Node(T data = T()) :data_(data) , left_(nullptr)原创 2022-05-11 18:46:47 · 244 阅读 · 0 评论 -
189-AVL树-上(定义 & 节点平衡操作)
1、AVL树定义AVL树又叫二叉平衡搜索树是在BST树的基础上增加节点平衡操作(节点平衡:任意节点的左右子树高度差不超过1)(可以是0,1,-1)上图也称作BST树,但是搜索的时间复杂度不能达到对数时间了!已经相当于一个链表了!2、AVL树的旋转操作AVL树为了维护节点平衡引入的四种节点旋转操作节点失衡有四种原因!!1、左孩子的左子树太高了我们看到:40节点失衡了!不满足AVL树的概念了!所以我们为了得到一个平衡树(AVL)树,以达到log以2为底的n的时间复杂度要进行旋原创 2022-05-11 17:03:07 · 204 阅读 · 0 评论 -
176-BST树-下(前中后序 + 层序遍历)
1、BST树 前中后序遍历层序遍历:从根节点开始,一层一层的遍历,从上到下,从左到右依次遍历58,24,67,0,34,62,69,5,41,64,78我们把每一个节点看作V,它的左孩子看作L,它的右孩子看作R,规定L总是出现在R之前。所以,我们有3种组合方式:VLR (前序遍历)LVR (中序遍历)LRV (后序遍历)根据V的位置,我们就知道它是什么样的遍历:V代表当前节点的输出操作。L代表访问该节点的左孩子,不输出;R代表访问该节点的右孩子,不输出。1.1、前中后原创 2022-05-09 13:15:43 · 753 阅读 · 0 评论 -
175-BST树-上(定义、递归&非递归插入删除查询)
1、BST树定义BST树称作二叉搜索树(Binary Search Tree)或者二叉排序树(Binary Sort Tree),它或者是一棵空树;或者是具有下列性质的二叉树:1、若左子树不为空,则左子树上所有节点的值均小于它的根节点的值2、若右子树不为空,则右子树上所有节点的值均大于它的根节点的值3、左右子树也分别满足二叉搜索树性质特点: 每一个节点都满足 左孩子的值(不为空)< 父节点的值 <右孩子的值(不为空)类似于二分查找算法。在这棵树上,我们找一个元素,最多找4.原创 2022-05-09 01:15:06 · 233 阅读 · 0 评论 -
168-一致性哈希算法-负载均衡
场景1(业务服务器)–普通哈希算法存在的问题轮询算法: 第一个请求给server1,第二个请求给server2,第3个请求给server3,一直轮询下去。权重比算法: 比如说,给第1台分配1的权重,给第2台分配2的权重,给第3台分配1的权重,有4个请求到来,其中2个请求分配给第2台,其他两台各分配1个请求。最少连接算法: 负载均衡器要记录跟每一台服务器建立的连接,每次发请求的时候,跟哪台请求创建的连接最少就分发给哪台机器,哪台服务器连接少,说明其压力小,新来的请求就给到压力最小的服务器。哈希算法.原创 2022-05-08 00:51:25 · 631 阅读 · 0 评论 -
164-大数据处理-求topK问题(快排分割算法)
快排分割算法算法步骤找值最小的前3个元素,我们没有必要把全部数据排序。我们选择一个基准数:64;然后头尾定义i,j;从右向左找小于基准数64的,75大于64,18小于64,把18放在左边i的位置上,i++;然后从左向右找,大于基准数64的;找到80大于基准数64,把80放到右边j的位置,j- -;从右向左找小于基准数64的,2小于基准数,把2给i的位置,i++;然后从左向右找,大于基准数的。66大于基准数64,66放到j的位置,j- -;从右向左找小于基准数64的,0原创 2022-05-07 16:25:32 · 432 阅读 · 0 评论 -
162-大数据查重-布隆过滤器
布隆过滤器在缓存服务器redis,在黑名单过滤,钓鱼网站过滤,URL过滤这些场景中,布隆过滤器很常见布隆过滤器就是把哈希表方法和位图算法结合起来布隆过滤器讲解布隆过滤器增加元素假设 我们有3个哈希函数,位数组的长度是7个。我们通过第一个哈希函数,我们把这个key所要存储的数据不管是整数,还是字符串,还是IP地址,还是URL,作为输入参数,通过哈希函数得到的位置,就是位图数组范围内的一个下标。假设一个输入参数通过第一个哈希函数得出的结果是0通过第二个哈希函数得出的结果是4通过第原创 2022-05-07 00:52:29 · 895 阅读 · 0 评论 -
160-大数据查重-位图算法
大数据查重-位图算法位: 内存管理的最小单位是字节,一个字节是8个位。问题: 有1亿个整数,最大值不超过1亿,问都有哪些元素重复了?谁是第一个重复的? 内存限制100M1亿 = 100M如果是放到哈希表上:100M * 4 = 400M * 2 = 800M1、什么是位图算法?我们有下面一行数字:我们用一个位存储数字是否出现过的状态,那么这几个数字,我们的位图数组需要定义多长呢?处理方法:我们要找出这组数据的最大的数字19;因为小的值在位图数组里肯定是靠前存放,大的值靠后原创 2022-05-06 19:28:28 · 996 阅读 · 0 评论 -
153-哈希表总结
哈希表1亿大小 = 100M10亿个整数,占4G大小散列函数散列冲突处理原创 2022-05-05 20:14:14 · 174 阅读 · 0 评论 -
156-大数据查重-哈希表应用
大数据查重-哈希应用模拟问题1vector中放原始的数据,放着10000个随机的数字,有的数字有重复,有的数字没有重复,找第一个出现重复的数字#include <iostream>#include <vector>#include <unordered_set> #include <unordered_map>#include <stdlib.h>#include <time.h>#include <str原创 2022-05-06 00:31:27 · 203 阅读 · 0 评论 -
150-链式哈希表实现
C++、Java无序关联容器底层采用链式哈希表实现。为什么不采用线性探测哈希表?如果采用线性探测哈希表,缺陷是:2、发生哈希冲突时,需要从当前发生哈希冲突的位置向后不断的去找,找到第一个空闲的位置把元素放上,这个过程的时间复杂度就趋近于O(n)了,存储变慢了,查询和删除也变慢,哈希冲突的发生越严重,就越靠近O(n)的时间复杂度,这个时间复杂度能否优化?哈希冲突是无法避免的,但是发生哈希冲突以后,在进行增删查的时候,能不能把时间效率提高一点,不让它趋近于O(n)的时间复杂度呢?不能,因为它是一个线性原创 2022-05-05 00:49:35 · 895 阅读 · 0 评论 -
133-哈希表-线性探测法代码实现
1、哈希表-线性探测法理论线性探测法的理论我们在上一篇博客已经阐述了。现在我们来看看线性探测法的增删查的代码思想:1.1、哈希表的增加元素注意:往后遍历寻找空闲位置的时候,要注意是环形遍历哦!不然访问数组就越界了。在添加元素,发生位置被占用,即发生哈希冲突后,在向后遍历寻找空闲位置的时候,我们要知道,这个空闲的位置是有两种情况的:1、这个位置一直是空的,没放过元素。2、这个位置是空的,以前放过元素,后来被删除了。1.2、哈希表的查询操作当用哈希函数计算得出的下标值是3原创 2022-05-02 20:38:17 · 730 阅读 · 0 评论 -
132-哈希表的理论讲解
1、哈希表的定义哈希表增删查效率非常高,趋近于O(1);没有办法达到绝对的O(1),后面会学习到;哈希表什么时候用到?在进行大量的查询时会用到,只要是有速度快的查询的需求,都会想到哈希表。问题:我们想让这一组数据的查询的时间复杂度是O(1),怎么办?不管是存到链表还是数组里面,都是线性的查找,从第一个元素开始查,查一个比较一个,时间复杂度都是O(n)最快的方法是提供一张表,还是数组, 我们在存的时候,并不是挨个存储,而是元素值的本身作为下标存到数组相应的位置。我们把数组的原创 2022-05-02 17:49:09 · 282 阅读 · 0 评论 -
118-B-树& B+树 & B*树
B- 树我们一般叫“B树”,B是Balance平衡的意思。平衡树。m阶-平衡树 (一个节点有m个地址域,m-1个数据域)应用场景: 文件索引系统的实现。AVL树: 二阶平衡树。一个节点有2个地址域,1个数据域。(左右孩子的高度差是1,0,-1)B-树,所有叶子节点都在同一层,是非常平衡的一棵树!m阶B-树:最多有m个地址域(即m个孩子),m-1个数据域。除根节点和叶子节点外,其他每个节点至少有m的一半个孩子(比如说,m = 5,5/2=3,至少有3个孩子)。除原创 2022-04-30 23:26:29 · 215 阅读 · 0 评论 -
57-串操作—KMP算法
KMP算法举例:在第2步匹配失配了,说明前面abcde都是一一对应的。而且abcde都是不相同的;后面的3456步都是无效的匹配操作。应该从第7步开始匹配。j回退到哪里?和子串的形状有关;子串从x处回退到起始a处,因为x之前的每个字符都是不同的。第二种情况:子串有重复读字母;按照BF算法来进行匹配:在第2步时,失配了;回退,到第3步,这一步是没有必要的,因为前面a、b本来就是不相同的;同理第4步也是没有必要的;到第5步和第6步:(也是没有必要的)因为x前面的原创 2022-04-23 22:45:56 · 200 阅读 · 0 评论 -
56-串操作—BF算法
BF算法BF算法流程主串i和子串j分别从下标为0的地方开始匹配:相等,向后移动:相等,在向后移动:此时就不相等了;i和j分别回退:继续比较:不相等,继续向后移动。一直退到这里:相等,向后退:还是相等的,继续退;匹配成功:当 j 和自己长度相等时,表示找到了匹配失败:移动到最后时:此时不匹配,i会+1:BF算法流程代码实现#include <iostream>#include <memory>using name原创 2022-04-23 20:55:59 · 426 阅读 · 0 评论