数据结构之七大查找算法

2023-12-02 10:40

本文主要是介绍数据结构之七大查找算法,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

七大查找算法

    • 一、顺序查找
    • 二、二分查找
    • 三、插值查找
    • 四、斐波那契查找
    • 五、树表查找
      • 5.1 最简单的树表查找算法——二叉树查找算法
      • 5.2 平衡查找树之2-3查找树(2-3 Tree)
      • 5.3 平衡查找树之红黑树(Red-Black Tree)
      • 5.4 B树和B+树(B Tree/B+ Tree)
      • 5.5 树表查找总结
    • 六、分块查找
    • 七、哈希查找
      • 7.1 什么是哈希表(Hash)?
      • 7.2 什么是哈希函数?

查找定义根据给定的某个值,在查找表中确定一个其关键字等于给定值的数据元素(或记录)。 
 
查找算法分类

(1)静态查找和动态查找;    
(注:静态或者动态都是针对查找表而言的。动态表指查找表中有删除和插入操作的表)  
(2)无序查找和有序查找。    
无序查找:被查找数列有序无序均可;    
有序查找:被查找数列必须为有序数列。

平均查找长度(Average Search Length,ASL)需和指定key进行比较的关键字的个数的期望值,称为查找算法在查找成功时的平均查找长度。  
对于含有n个数据元素的查找表,查找成功的平均查找长度为:ASL = Pi*Ci的和

Pi:查找表中第i个数据元素的概率。   Ci:找到第i个数据元素时已经比较过的次数。

一、顺序查找

(1)说明
顺序查找适合于存储结构为顺序存储或链接存储的线性表。

(2)基本思想
顺序查找也称为线形查找,属于无序查找算法。从数据结构线形表的一端开始,顺序扫描,依次将扫描到的结点关键字与给定值k相比较,若相等则表示查找成功;若扫描结束仍没有找到关键字等于k的结点,表示查找失败。

(3)复杂度分析:   
查找成功时的平均查找长度为:
(假设每个数据元素的概率相等) ASL = 1/n(1+2+3+…+n) = (n+1)/2 ;
当查找不成功时,需要n+1次比较,时间复杂度为O(n);

所以,顺序查找的时间复杂度为O(n)

(4)C++实现源码

//顺序查找
int SequenceSearch(int a[], int value, int n)
{int i;for(i=0; i<n; i++)if(a[i]==value)return i;return -1;
}

二、二分查找

(1)说明
元素必须是有序的,如果是无序的则要先进行排序操作。

(2)基本思想
也称为是折半查找,属于有序查找算法。用给定值k先与中间结点的关键字比较,中间结点把线形表分成两个子表,若相等则查找成功;若不相等,再根据k与该中间结点关键字的比较结果确定下一步查找哪个子表,这样递归进行,直到查找到或查找结束发现表中没有这样的结点。

(3)复杂度分析
最坏情况下,关键词比较次数为log2(n+1),且期望时间复杂度为O(log2n)

注:折半查找的前提条件是需要有序表顺序存储,对于静态查找表,一次排序后不再变化,折半查找能得到不错的效率。但对于需要频繁执行插入或删除操作的数据集来说,维护有序的排序会带来不小的工作量,那就不建议使用。——《大话数据结构》

(4)C++实现源码

//二分查找(折半查找),版本1
int BinarySearch1(int a[], int value, int n)
{int low, high, mid;low = 0;high = n-1;while(low<=high){mid = (low+high)/2;if(a[mid]==value)return mid;if(a[mid]>value)high = mid-1;if(a[mid]<value)low = mid+1;}return -1;
}//二分查找,递归版本
int BinarySearch2(int a[], int value, int low, int high)
{int mid = low+(high-low)/2;if(a[mid]==value)return mid;if(a[mid]>value)return BinarySearch2(a, value, low, mid-1);if(a[mid]<value)return BinarySearch2(a, value, mid+1, high);
}

三、插值查找

(1)说明
在介绍插值查找之前,首先考虑一个新问题,为什么上述算法一定要是折半,而不是折四分之一或者折更多呢?  
打个比方,在英文字典里面查“apple”,你下意识翻开字典是翻前面的书页还是后面的书页呢?如果再让你查“zoo”,你又怎么查?很显然,这里你绝对不会是从中间开始查起,而是有一定目的的往前或往后翻。  
同样的,比如要在取值范围1 ~ 10000 之间 100 个元素从小到大均匀分布的数组中查找5, 我们自然会考虑从数组下标较小的开始查找。

经过以上分析,折半查找这种查找方式,不是自适应的(也就是说是傻瓜式的)。二分查找中查找点计算如下:

mid=(low+high)/2, 即mid=low+1/2*(high-low)

通过类比,我们可以将查找的点改进为如下:

mid=low+(key-a[low])/(a[high]-a[low])*(high-low) 

也就是将上述的比例参数1/2改进为自适应的,根据关键字在整个有序表中所处的位置,让mid值的变化更靠近关键字key,这样也就间接地减少了比较次数。

(2)基本思想
基于二分查找算法,将查找点的选择改进为自适应选择,可以提高查找效率。当然,差值查找也属于有序查找。

注:对于表长较大,而关键字分布又比较均匀的查找表来说,插值查找算法的平均性能比折半查找要好的多。反之,数组中如果分布非常不均匀,那么插值查找未必是很合适的选择。

(3)复杂度分析
查找成功或者失败的时间复杂度均为O(log2(log2n))

(4)C++实现源码

//插值查找
int InsertionSearch(int a[], int value, int low, int high)
{int mid = low+(value-a[low])/(a[high]-a[low])*(high-low);if(a[mid]==value)return mid;if(a[mid]>value)return InsertionSearch(a, value, low, mid-1);if(a[mid]<value)return InsertionSearch(a, value, mid+1, high);
}

四、斐波那契查找

(1)说明
在介绍斐波那契查找算法之前,我们先介绍一下很它紧密相连并且大家都熟知的一个概念——黄金分割。  
黄金比例又称黄金分割,是指事物各部分间一定的数学比例关系,即将整体一分为二,较大部分与较小部分之比等于整体与较大部分之比,其比值约为1:0.618或1.618:1。  
0.618被公认为最具有审美意义的比例数字,这个数值的作用不仅仅体现在诸如绘画、雕塑、音乐、建筑等艺术领域,而且在管理、工程设计等方面也有着不可忽视的作用。因此被称为黄金分割。
  
斐波那契数列:1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89…….(从第三个数开始,后边每一个数都是前两个数的和)。然后我们会发现,随着斐波那契数列的递增,前后两个数的比值会越来越接近0.618,利用这个特性,我们就可以将黄金比例运用到查找技术中。
在这里插入图片描述
(2)基本思想
也是二分查找的一种提升算法,通过运用黄金比例的概念在数列中选择查找点进行查找,提高查找效率。同样地,斐波那契查找也属于一种有序查找算法。  
相对于折半查找,一般将待比较的key值与第mid=(low+high)/2位置的元素比较,比较结果分三种情况:

1)相等,mid位置的元素即为所求  
2)>,low=mid+1;
3)<,high=mid-1。

斐波那契查找与折半查找很相似,他是根据斐波那契序列的特点对有序表进行分割的。他要求开始表中记录的个数为某个斐波那契数小1,及n=F(k)-1; 开始将k值与第F(k-1)位置的记录进行比较(及mid=low+F(k-1)-1),比较结果也分为三种:

1)相等,mid位置的元素即为所求  
2)>,low=mid+1,k-=2  
(说明:low=mid+1说明待查找的元素在[mid+1,high]范围内,k-=2说明范围[mid+1,high]内的元素个数为n-(F(k-1))=Fk-1-F(k-1)=Fk-F(k-1)-1=F(k-2)-1个,所以可以递归的应用斐波那契查找。)  
3)<,high=mid-1,k-=1  
(说明:low=mid+1说明待查找的元素在[low,mid-1]范围内,k-=1说明范围[low,mid-1]内的元素个数为F(k-1)-1个,所以可以递归 的应用斐波那契查找。)

(3)复杂度分析
最坏情况下,时间复杂度为O(log2n),且其期望复杂度也为O(log2n)

(4)C++实现源码

// 斐波那契查找.cpp #include "stdafx.h"
#include <memory>
#include  <iostream>
using namespace std;const int max_size=20;//斐波那契数组的长度/*构造一个斐波那契数组*/ 
void Fibonacci(int * F)
{F[0]=0;F[1]=1;for(int i=2;i<max_size;++i)F[i]=F[i-1]+F[i-2];
}/*定义斐波那契查找法*/  
int FibonacciSearch(int *a, int n, int key)  //a为要查找的数组,n为要查找的数组长度,key为要查找的关键字
{int low=0;int high=n-1;int F[max_size];Fibonacci(F);//构造一个斐波那契数组F int k=0;while(n>F[k]-1)//计算n位于斐波那契数列的位置++k;int  * temp;//将数组a扩展到F[k]-1的长度temp=new int [F[k]-1];memcpy(temp,a,n*sizeof(int));for(int i=n;i<F[k]-1;++i)temp[i]=a[n-1];while(low<=high){int mid=low+F[k-1]-1;if(key<temp[mid]){high=mid-1;k-=1;}else if(key>temp[mid]){low=mid+1;k-=2;}else{if(mid<n)return mid; //若相等则说明mid即为查找到的位置elsereturn n-1; //若mid>=n则说明是扩展的数值,返回n-1}}  delete [] temp;return -1;
}int main()
{int a[] = {0,16,24,35,47,59,62,73,88,99};int key=100;int index=FibonacciSearch(a,sizeof(a)/sizeof(int),key);cout<<key<<" is located at:"<<index;return 0;
}

五、树表查找

5.1 最简单的树表查找算法——二叉树查找算法

(1)基本思想
二叉查找树是先对待查找的数据进行生成树,确保树的左分支的值小于右分支的值,然后在就行和每个节点的父节点比较大小,查找最适合的范围。 这个算法的查找效率很高,但是如果使用这种查找方法要首先创建树。

二叉查找树(BinarySearch Tree,也叫二叉搜索树,或称二叉排序树Binary Sort Tree)或者是一棵空树,或者是具有下列性质的二叉树:

1)若任意节点的左子树不空,则左子树上所有结点的值均小于它的根结点的值;  
2)若任意节点的右子树不空,则右子树上所有结点的值均大于它的根结点的值;  
3)任意节点的左、右子树也分别为二叉查找树。

二叉查找树性质:
对二叉查找树进行中序遍历,即可得到有序的数列。

(2)复杂度分析
它和二分查找一样,插入和查找的时间复杂度均为O(logn),但是在最坏的情况下仍然会有O(n)的时间复杂度。原因在于插入和删除元素的时候,树没有保持平衡(比如,我们查找上图(b)中的“93”,我们需要进行n次查找操作)。我们追求的是在最坏的情况下仍然有较好的时间复杂度,这就是平衡查找树设计的初衷。

下图为二叉树查找和顺序查找以及二分查找性能的对比图:
在这里插入图片描述
基于二叉查找树进行优化,进而可以得到其他的树表查找算法,如平衡树、红黑树等高效算法。

5.2 平衡查找树之2-3查找树(2-3 Tree)

(1)2-3查找树定义
和二叉树不一样,2-3树运行每个节点保存1个或者两个的值。对于普通的2节点(2-node),他保存1个key和左右两个自己点。对应3节点(3-node),保存两个Key,2-3查找树的定义如下:

1)为空  
2)对于2节点,该节点保存一个key及对应value,以及两个指向左右节点的节点,左节点也是一个2-3节点,所有的值都比key要小,右节点也是一个2-3节点,所有的值比key要大。  
3)对于3节点,该节点保存两个key及对应value,以及三个指向左中右的节点。左节点也是一个2-3节点,所有的值均比两个key中的最小的key还要小;中间节点也是一个2-3节点,中间节点的key值在两个跟节点key值之间;右节点也是一个2-3节点,节点的所有key值比两个key中的最大的key还要大。

在这里插入图片描述
(2)2-3查找树的性质

1)如果中序遍历2-3查找树,就可以得到排好序的序列;    
2)在一个完全平衡的2-3查找树中,根节点到每一个为空节点的距离都相同。
(这也是平衡树中“平衡”一词的概念,根节点到叶节点的最长距离对应于查找算法的最坏情况,而平衡树中根节点到叶节点的距离都一样,最坏情况也具有对数复杂度。)

在这里插入图片描述
(3)复杂度分析: 
 
2-3树的查找效率与树的高度息息相关

在最坏的情况下,也就是所有的节点都是2-node节点,查找效率为lgN
在最好的情况下,所有的节点都是3-node节点,查找效率为log3N约等于0.631lgN

距离来说,对于1百万个节点的2-3树,树的高度为12-20之间,对于10亿个节点的2-3树,树的高度为18-30之间。

对于插入来说,只需要常数次操作即可完成,因为他只需要修改与该节点关联的节点即可,不需要检查其他节点,所以效率和查找类似。下面是2-3查找树的效率:
在这里插入图片描述

5.3 平衡查找树之红黑树(Red-Black Tree)

2-3查找树能保证在插入元素之后能保持树的平衡状态,最坏情况下即所有的子节点都是2-node,树的高度为lgn,从而保证了最坏情况下的时间复杂度。但是2-3树实现起来比较复杂,于是就有了一种简单实现2-3树的数据结构,即红黑树(Red-Black Tree)。

(1)基本思想
红黑树的思想就是对2-3查找树进行编码,尤其是对2-3查找树中的3-nodes节点添加额外的信息。红黑树中将节点之间的链接分为两种不同类型,红色链接,他用来链接两个2-nodes节点来表示一个3-nodes节点。黑色链接用来链接普通的2-3节点。特别的,使用红色链接的两个2-nodes来表示一个3-nodes节点,并且向左倾斜,即一个2-node是另一个2-node的左子节点。这种做法的好处是查找的时候不用做任何修改,和普通的二叉查找树相同。
在这里插入图片描述
(2)红黑树的定义:  
红黑树是一种具有红色和黑色链接的平衡查找树,同时满足:

红色节点向左倾斜
一个节点不可能有两个红色链接
整个树完全黑色平衡,即从根节点到所以叶子结点的路径上,黑色链接的个数都相同

下图可以看到红黑树其实是2-3树的另外一种表现形式:如果我们将红色的连线水平绘制,那么他链接的两个2-node节点就是2-3树中的一个3-node节点了。
在这里插入图片描述
(3)红黑树的性质
整个树完全黑色平衡,即从根节点到所以叶子结点的路径上,黑色链接的个数都相同(2-3树的第2)性质,从根节点到叶子节点的距离都相等)。
  
(4)复杂度分析
最坏的情况就是,红黑树中除了最左侧路径全部是由3-node节点组成,即红黑相间的路径长度是全黑路径长度的2倍。
  
下图是一个典型的红黑树,从中可以看到最长的路径(红黑相间的路径)是最短路径的2倍:
在这里插入图片描述
红黑树的平均高度大约为logn

下图是红黑树在各种情况下的时间复杂度,可以看出红黑树是2-3查找树的一种实现,它能保证最坏情况下仍然具有对数的时间复杂度。
在这里插入图片描述
红黑树这种数据结构应用十分广泛,在多种编程语言中被用作符号表的实现,如:

Java中的java.util.TreeMap,java.util.TreeSet;C++ STL中的:map,multimap,multiset;.NET中的:SortedDictionary,SortedSet 等。

5.4 B树和B+树(B Tree/B+ Tree)

平衡查找树中的2-3树以及其实现红黑树。2-3树种,一个节点最多有2个key,而红黑树则使用染色的方式来标识这两个key。

维基百科对B树的定义为“在计算机科学中,B树(B-tree)是一种树状数据结构,它能够存储数据、对其进行排序并允许以O(log n)的时间复杂度运行进行查找、顺序读取、插入和删除的数据结构。B树,概括来说是一个节点可以拥有多于2个子节点的二叉查找树。与自平衡二叉查找树不同,B树为系统最优化大块数据的读和写操作。B-tree算法减少定位记录时所经历的中间过程,从而加快存取速度。普遍运用在数据库和文件系统。

(1)B树定义:  
B树可以看作是对2-3查找树的一种扩展,即他允许每个节点有M-1个子节点

1)根节点至少有两个子节点
2)每个节点有M-1个key,并且以升序排列
3)位于M-1和M key的子节点的值位于M-1 和M key对应的Value之间
4)其它节点至少有M/2个子节点

下图是一个M=4 阶的B树:
在这里插入图片描述
 可以看到B树是2-3树的一种扩展,他允许一个节点有多于2个的元素。B树的插入及平衡化操作和2-3树很相似。

(2)B+树定义:  
B+树是对B树的一种变形树,它与B树的差异在于:

1)有k个子结点的结点必然有k个关键码; 2)非叶结点仅具有索引作用,跟记录有关的信息均存放在叶结点中。
3)树的所有叶结点构成一个有序链表,可以按照关键码排序的次序遍历全部记录。

如下图,是一个B+树:
在这里插入图片描述
B和B+树的区别在于,B+树的非叶子结点只包含导航信息,不包含实际的值,所有的叶子结点和相连的节点使用链表相连,便于区间查找和遍历。

B+ 树的优点在于:

1)由于B+树在内部节点上不好含数据信息,因此在内存页中能够存放更多的key。
数据存放的更加紧密,具有更好的空间局部性。因此访问叶子几点上关联的数据也具有更好的缓存命中率。
2)B+树的叶子结点都是相链的,因此对整棵树的便利只需要一次线性遍历叶子结点即可。而且由于数据顺序排列并且相连,所以便于区间查找和搜索。而B树则需要进行每一层的递归遍历。相邻的元素可能在内存中不相邻,所以缓存命中性没有B+树好。

但是B树也有优点,其优点在于,由于B树的每一个节点都包含key和value,因此经常访问的元素可能离根节点更近,因此访问也更迅速。

下面是B 树和B+树的区别图:
在这里插入图片描述
B/B+树常用于文件系统和数据库系统中,它通过对每个节点存储个数的扩展,使得对连续的数据能够进行较快的定位和访问,能够有效减少查找时间,提高存储的空间局部性从而减少IO操作。它广泛用于文件系统及数据库中,如:

1)Windows:HPFS文件系统;
2)Mac:HFS,HFS+文件系统;
3)Linux:ResiserFS,XFS,Ext3FS,JFS文件系统;
4)数据库:ORACLE,MYSQL,SQLSERVER等中。

5.5 树表查找总结

二叉查找树平均查找性能不错,为O(logn),但是最坏情况会退化为O(n)。在二叉查找树的基础上进行优化,我们可以使用平衡查找树。平衡查找树中的2-3查找树,这种数据结构在插入之后能够进行自平衡操作,从而保证了树的高度在一定的范围内进而能够保证最坏情况下的时间复杂度。但是2-3查找树实现起来比较困难,红黑树是2-3树的一种简单高效的实现,他巧妙地使用颜色标记来替代2-3树中比较难处理的3-node节点问题。红黑树是一种比较高效的平衡查找树,应用非常广泛,很多编程语言的内部实现都或多或少的采用了红黑树。  
除此之外,2-3查找树的另一个扩展——B/B+平衡树,在文件系统和数据库系统中有着广泛的应用。

六、分块查找

分块查找又称索引顺序查找,它是顺序查找的一种改进方法。

(1)算法思想
将n个数据元素"按块有序"划分为m块(m ≤ n)。每一块中的结点不必有序,但块与块之间必须"按块有序";即第1块中任一元素的关键字都必须小于第2块中任一元素的关键字;而第2块中任一元素又都必须小于第3块中的任一元素,……

(2)算法流程
  step1 先选取各块中的最大关键字构成一个索引表;
  step2 查找分两个部分:先对索引表进行二分查找或顺序查找,以确定待查记录在哪一块中;然后,在已确定的块中用顺序法进行查找。

七、哈希查找

7.1 什么是哈希表(Hash)?

我们使用一个下标范围比较大的数组来存储元素。可以设计一个函数(哈希函数, 也叫做散列函数),使得每个元素的关键字都与一个函数值(即数组下标)相对应,于是用这个数组单元来存储这个元素;也可以简单的理解为,按照关键字为每一个元素"分类",然后将这个元素存储在相应"类"所对应的地方。但是,不能够保证每个元素的关键字与函数值是一一对应的,因此极有可能出现对于不同的元素,却计算出了相同的函数值,这样就产生了"冲突",换句话说,就是把不同的元素分在了相同的"类"之中。后面我们将看到一种解决"冲突"的简便做法。  
总的来说,"直接定址"与"解决冲突"是哈希表的两大特点。

7.2 什么是哈希函数?

哈希函数的规则是:通过某种转换关系,使关键字适度的分散到指定大小的的顺序结构中,越分散,则以后查找的时间复杂度越小,空间复杂度越高。

(1)算法思想
哈希的思路很简单,如果所有的键都是整数,那么就可以使用一个简单的无序数组来实现:将键作为索引,值即为其对应的值,这样就可以快速访问任意键的值。这是对于简单的键的情况,我们将其扩展到可以处理更加复杂的类型的键。

(2)算法流程

1)用给定的哈希函数构造哈希表;  
2)根据选择的冲突处理方法解决地址冲突(常见的解决冲突的方法:拉链法线性探法)  
3)在哈希表的基础上执行哈希查找。

哈希表是一个在时间和空间上做出权衡的经典例子。如果没有内存限制,那么可以直接将键作为数组的索引。那么所有的查找时间复杂度为O(1);如果没有时间限制,那么我们可以使用无序数组并进行顺序查找,这样只需要很少的内存。哈希表使用了适度的时间和空间来在这两个极端之间找到了平衡。只需要调整哈希函数算法即可在时间和空间上做出取舍。

(3)复杂度分析:  
单纯论查找复杂度:对于无冲突的Hash表而言,查找复杂度为O(1)(注意,在查找之前我们需要构建相应的Hash表)。

使用Hash,我们付出了什么?

我们在实际编程中存储一个大规模的数据,最先想到的存储结构可能就是map,也就是我们常说的KV pair,经常使用Python的博友可能更有这种体会。使用map的好处就是,我们在后续处理数据处理时,可以根据数据的key快速的查找到对应的value值。map的本质就是Hash表,那我们在获取了超高查找效率的基础上,我们付出了什么?

Hash是一种典型以空间换时间的算法,比如原来一个长度为100的数组,对其查找,只需要遍历且匹配相应记录即可,从空间复杂度上来看,假如数组存储的是byte类型数据,那么该数组占用100byte空间。现在我们采用Hash算法,我们前面说的Hash必须有一个规则,约束键与存储位置的关系,那么就需要一个固定长度的hash表,此时,仍然是100byte的数组,假设我们需要的100byte用来记录键与位置的关系,那么总的空间为200byte,而且用于记录规则的表大小会根据规则,大小可能是不定的。

Hash算法和其他查找算法的性能对比:
在这里插入图片描述

这篇关于数据结构之七大查找算法的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/445015

相关文章

C#数据结构之字符串(string)详解

《C#数据结构之字符串(string)详解》:本文主要介绍C#数据结构之字符串(string),具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录转义字符序列字符串的创建字符串的声明null字符串与空字符串重复单字符字符串的构造字符串的属性和常用方法属性常用方法总结摘

SpringBoot实现MD5加盐算法的示例代码

《SpringBoot实现MD5加盐算法的示例代码》加盐算法是一种用于增强密码安全性的技术,本文主要介绍了SpringBoot实现MD5加盐算法的示例代码,文中通过示例代码介绍的非常详细,对大家的学习... 目录一、什么是加盐算法二、如何实现加盐算法2.1 加盐算法代码实现2.2 注册页面中进行密码加盐2.

Java时间轮调度算法的代码实现

《Java时间轮调度算法的代码实现》时间轮是一种高效的定时调度算法,主要用于管理延时任务或周期性任务,它通过一个环形数组(时间轮)和指针来实现,将大量定时任务分摊到固定的时间槽中,极大地降低了时间复杂... 目录1、简述2、时间轮的原理3. 时间轮的实现步骤3.1 定义时间槽3.2 定义时间轮3.3 使用时

Windows系统下如何查找JDK的安装路径

《Windows系统下如何查找JDK的安装路径》:本文主要介绍Windows系统下如何查找JDK的安装路径,文中介绍了三种方法,分别是通过命令行检查、使用verbose选项查找jre目录、以及查看... 目录一、确认是否安装了JDK二、查找路径三、另外一种方式如果很久之前安装了JDK,或者在别人的电脑上,想

如何通过Golang的container/list实现LRU缓存算法

《如何通过Golang的container/list实现LRU缓存算法》文章介绍了Go语言中container/list包实现的双向链表,并探讨了如何使用链表实现LRU缓存,LRU缓存通过维护一个双向... 目录力扣:146. LRU 缓存主要结构 List 和 Element常用方法1. 初始化链表2.

golang字符串匹配算法解读

《golang字符串匹配算法解读》文章介绍了字符串匹配算法的原理,特别是Knuth-Morris-Pratt(KMP)算法,该算法通过构建模式串的前缀表来减少匹配时的不必要的字符比较,从而提高效率,在... 目录简介KMP实现代码总结简介字符串匹配算法主要用于在一个较长的文本串中查找一个较短的字符串(称为

通俗易懂的Java常见限流算法具体实现

《通俗易懂的Java常见限流算法具体实现》:本文主要介绍Java常见限流算法具体实现的相关资料,包括漏桶算法、令牌桶算法、Nginx限流和Redis+Lua限流的实现原理和具体步骤,并比较了它们的... 目录一、漏桶算法1.漏桶算法的思想和原理2.具体实现二、令牌桶算法1.令牌桶算法流程:2.具体实现2.1

Go语言中三种容器类型的数据结构详解

《Go语言中三种容器类型的数据结构详解》在Go语言中,有三种主要的容器类型用于存储和操作集合数据:本文主要介绍三者的使用与区别,感兴趣的小伙伴可以跟随小编一起学习一下... 目录基本概念1. 数组(Array)2. 切片(Slice)3. 映射(Map)对比总结注意事项基本概念在 Go 语言中,有三种主要

Python中的随机森林算法与实战

《Python中的随机森林算法与实战》本文详细介绍了随机森林算法,包括其原理、实现步骤、分类和回归案例,并讨论了其优点和缺点,通过面向对象编程实现了一个简单的随机森林模型,并应用于鸢尾花分类和波士顿房... 目录1、随机森林算法概述2、随机森林的原理3、实现步骤4、分类案例:使用随机森林预测鸢尾花品种4.1

不懂推荐算法也能设计推荐系统

本文以商业化应用推荐为例,告诉我们不懂推荐算法的产品,也能从产品侧出发, 设计出一款不错的推荐系统。 相信很多新手产品,看到算法二字,多是懵圈的。 什么排序算法、最短路径等都是相对传统的算法(注:传统是指科班出身的产品都会接触过)。但对于推荐算法,多数产品对着网上搜到的资源,都会无从下手。特别当某些推荐算法 和 “AI”扯上关系后,更是加大了理解的难度。 但,不了解推荐算法,就无法做推荐系