数据寻踪:从基础查找到高级检索技术

🌟 嗨,我是Lethehong🌟

🌍 立志在坚不欲说,成功在久不在速🌍

🚀 欢迎关注:👍点赞⬆️留言收藏🚀

🍀欢迎使用:小智初学计算机网页IT深度知识智能体

🍀欢迎使用:深探助手deepGuide网页deepseek智能体


目录

1.基本概念

查找表

静态查找表

动态查找表

关键字

查找

查找表的存储结构

2.顺序查找

基本思想

顺序查找算法

链表的顺序查找

3.折半查找

基本思想

折半查找过程示例

折半查找算法

4.二叉排序树

二叉排序树定义

构造二叉排序树

二叉排序树的查找

二叉排序树的插入

二叉排序树的删除

5.平衡二叉树

6.B-树

查找

插入

删除

7.哈希表

哈希表的概念

哈希函数

哈希表

冲突

哈希函数的构造

(1)直接定址法

(2)质数取余法

(3)平方取中法

(4)折叠法

解决冲突的方法

(1)开放定址法

(2)链地址法

(3)再哈希法

(4)溢出区法

哈希表查找及其分析

8. 总结 

基础架构

线性结构检索

树形结构演化

哈希映射革命

技术决策矩阵


1.基本概念

查找表

用于查找的数据元素集合称为查找表。查找表由同一类型的数据元素(或 记录)构成。

静态查找表

若只对查找表进行如下两种操作:
(1)在查找表中查看某个特定的数据元素是否在查找表中
(2)检索某个特定元素的各种属性,则称这类查找表为静态查找表。
静态查找表在查找过程中查找表本身不发生变化。对静态查找表进行的查找操作称为静态查找。

动态查找表

若在查找过程中可以将查找表中不存在的数据元素插入,或者从查找表中删除某个数据元素,则称这类查找表为动态查找表。动态查找表在查找过程中查找表可能会发生变化。对动态查找表进行的查找操作称为动态查找。

关键字

是数据元素中的某个数据项。唯一能标识数据元素(或记录)的关键字,即每个元素的关键字值互不相同,我们称这种关键字为主关键字;若查找表中某些元素的关键字值相同,称这种关键字为次关键字。例如,银行帐户中的帐号是主关键字,而姓名是次关键字。

查找

在数据元素集合中查找满足某种条件的数据元素的过程称为查找。最简单且 最常用的查找条件是“关键字值等于某个给定值”,在查找表搜索关键字等于给定值的数据元素(或记录)。若表中存在这样的记录,则称查找成功,此时的查找结果应给出找到记录的全部信息或指示找到记录的存储位置;若表中不存在关键字等于给定值的记录,则称查找不成功,此时查找的结果可以给出一个空记录或空指针。若按主关键字查找,查找结果是唯一的;若按次关键字查找,结果可能是多个记录,即结果可能不唯一。

查找表的存储结构

查找表是一种非常灵活的数据结构,对于不同的存储结构,其查找方法不同。为了提高查找速度,有时会采用一些特殊的存储结构。本章将介绍以线性结构、树型结构及哈希表结构为存储结构的各种查找算法。查找算法的时间效率查找过程的主要操作是关键字的比较,所以通常以“平均比较次数”来衡量查找算法的时间效率。

2.顺序查找

基本思想

顺序查找是一种最简单的查找方法。其基本思想是将查找表作为一个线性表,可以是顺序表,也可以是链表,依次用查找条件中给定的值与查找表中数据元素的关键字值进行比较,若某个记录的关键字值与给定值相等,则查找成功,返回该记录的存储位置,反之,若直到最后一个记录,其关键字值与给定值均不相等,则查找失败,返回查找失败标志。

顺序查找算法

下面是顺序表的类型定义:
#define MAX_NUM 100
//用于定义表的长度
typedef struct elemtype{
keytype key;
anytype otheritem;
}Se_List[MAX_NUM],Se_Item;
假设在查找表中,数据元素个数为 n(n<MAX_NUM),并分别存放在数组的下标变量a[1]~a[n]中。
下面我们给出顺序查找的 完整算法
int seq_search (Se_List a,keytype k)
{//在顺序表中查找关键字值等于 k 的记录,
//若查找成功,返回该记录的位置下标序号,否则返回 0
i=1;
while (i<=n && a[i].key != k) i++;
if (i<=n) retrun i;
else return 0;
}
改进算法:
int seq_search2 (Se_List a,keytype k)82
{ //设置了监视哨的顺序表查找,查找关键字值等于指定值 k 的记录,
//若查找成功,返回记录存放位置的下标值,否则返回 0
i=n ;
a[0].key=k ;
while ( a[i].key != k) i--;
return ( i ) ;
}

链表的顺序查找

链表的顺序查找是指将查找表作为线性表并以链式存储结构存储,用顺序查找方法查找与指定关键字值相等的记录。链表的类型定义如下所示:
typedef struct node {
keytype key;
//结点的关键字类型
anytype otheritem; //结点的其他成分
struct node *next; //指向链表结点的指针
}Link_Node,*Link;
将查找表中的数据元素用这种结构的结点表示,并以指向头结点的指针标识。对链表实现顺寻查找就是在有头结点的链式查找表中查找关键字值等于给定值的记录,若查找成功,返回指向相应结点的指针,否则返回空指针。
Link_Node
*link_search (Link h , keytype k)
{//link 为带头结点链表的头指针,查找关键字值等于 k 的记录,
//查找成功,返回指向找到的结点的指针,查找失败返回空指针
p=h->next;
while ((p!=NULL) && (p->key!=k)) p=p->next;
return p;
}
顺序查找算法简单,对表的结构无任何要求;但是执行效率较低,尤其当 n 较大时,不宜采用这种查找方法。利用比较次数的平均值作为衡量标准(平均查找长度:ASL)
ASL(Average Search Length)定义:

其中 Pi 是查找第 i 个元素的概率, 如果查找是等概率的,则有 Pi
=1/n(i=1,2,...n),Ci 是查找第 i 个元素时和关键字比较的次数,假设从后往前找,则 Ci = n-i+1,从前往后找,则有 Ci=i(i=1,2,...n)有:

即:在等概率情况下,顺序查找法的平均查找长度为(n+1)/2。
说明: 顺序查找算法简单,对表的结构无任何要求;但是执行效率较低,尤其当 n较大时,不宜采用这种查找方法。

3.折半查找

基本思想

折半查找要求查找表用顺序存储结构存放且各数据元素按关键字有序(升序或隆序)排列,也就是说折半查找只适用于对有序顺序表进行查找。折半查找的基本思想是:首先以整个查找表作为查找范围,用查找条件中给定值 k与中间位置结点的关键字比较,若相等,则查找成功,否则,根据比较结果缩小查找范围,如果 k 的值小于关键字的值,根据查找表的有序性可知查找的数据元素只有可能在表的前半部分,即在左半部分子表中,所以继续对左子表进行折半查找;若 k 的值大于中间结点的关键字值,则可以判定查找的数据元素只有可能在表的后半部分,即在右半部分子表中,所以应该继续对右子表进行折半查找。每进行一次折半查找,要么查找成功,结束查找,要么将查找范围缩小一半,如此重复,直到查找成功或查找范围缩小为空即查找失败为止。

折半查找过程示例

假设待查有序(升序)顺序表中数据元素的关键字序列为(8,18,27,42,47,50,56,68,95,120),用折半查找方法查找关键字值为 27 和 59 的数据元素。

折半查找算法

假设查找表存放在数组 a 的 a[1]~a[n]中,且升序,查找关键字值为 k。
折半查找的主要步骤为:
(1)置初始查找范围:low=1,high=n;
(2)求查找范围中间项:mid=(low+high)/2
(3)将指定的关键字值 k 与中间项 a[mid].key 比较
若相等,查找成功,找到的数据元素为此时 mid 指向的位置;
若小于,查找范围的低端数据元素指针 low 不变,高端数据元素指针 high 更新为mid-1;
若大于,查找范围的高端数据元素指针 high 不变,低端数据元素指针 low 更新为mid+1;
(4)重复步骤(2)、(3)直到查找成功或查找范围空(low>high),即查找失败为止。
(5)如果查找成功,返回找到元素的存放位置,即当前的中间项位置指针 mid;否则返回查找失败标志。
折半查找的完整算法如下:
int bin_search (Se_List a, keytype k)
{
low=1; high=n;
//置初始查找范围的低、高端指针
while (low<=high)
{ mid=(low+high)/2;
//计算中间项位置
if (k==a[mid].key) break;
//找到,结束循环
else if (k< a[mid].key) high=mid-1;
//给定值 k 小
else
low=mid+1;
//给定值 k 大
}
if (low<=high) return mid ; //查找成功
else return 0 ;
//查找失败
}

4.二叉排序树

二叉排序树定义

二叉排序树是一棵二叉树,它或者为空,或者具有如下性质:1> 任一非终端结点若有左孩子,则该结点的关键字值大于其左孩子结点的关键字值;2>任一非终端结点若有右孩子,则该结点的关键字值小于其右孩子结点的关键字值。是一种常用的动态查找表,上面首先给出了它的非递归形式。
二叉排序树也可以用递归的形式定义,即二叉排序树是一棵树,它或者为空,或者具有如下性质:1> 若它的左子树非空,则其左子树所有结点的关键字值均小于其根结点的关键字值;2> 若它的右子树非空,则其右子树所有结点的关键字值均大于其根结点的关键字值;3> 它的左右子树都是二叉排序树。

构造二叉排序树

一个无序序列可以通过构造一棵二叉排序树,然后再对这棵二叉树进行中序遍历,即可以变成有序序列。构造树的过程即为对无序序列进行排序的过程。
特别说明: 结点个数和取值都相同的表构成的二叉排序树树形可能不相同。其树形由结点的输入顺序决定。如下例:
如果查询序列为{45,24,53,12,37,90},则对应的二叉排序树为:

平均查找长度为:ASL =(1+2*2+3*3)/6 =14/6
如果查询序列为{12,24,37,45,53,90},则对应的二叉排序树为:

平均查找长度为:ASL =(1+2+3+4+5+6)/6 =21/6
记忆:当二叉排序树为单支树时,ASL=n/2,其它情况平均得 ASL=1+4log2n

二叉排序树的查找

从二叉排序树的结构定义中可看到,一棵非空二叉排序树中根结点的关键字值大于其左子树上所有结点的关键字值,而小于其右子树上所有结点的关键字值,所以在二叉排序树中查找一个关键字值为 k 的结点的基本思想是:用给定值 k 与根结点关键字值比较,如果 k 小于根结点的值,则要找的结点只可能在左子树中,所以继续在左子树中查找,否则将继续在右子树中查找,依此方法,查找下去,至直查 找成功或查找失败为止。二叉排序树查找的过程描述如下:
1> 若二叉树为空树,则查找失败,
2> 将给定值 k 与根结点的关键字值比较,若相等,则查找成功,
3> 若根结点的关键字值小于给定值 k,则在左子树中继续搜索,否则,在右子树中继续查找。
假定二叉排序树的链式存储结构的类型定义如下:
typedef struct node {
keytype key;
anytype otheritem;
struct node *lchild;
struct node *rchild;
}Bin_Sort_Tree_Node,*Bin_Sort_Tree;
二叉排序树查找过程的描述是一个递归过程,若用链式存储结构存储,其查找操作
的递归算法如下所示:
Bin_Sort_Tree_Node *bt_search(Bin_Sort_Tree bt , keytype k)
{
//在根指针为 bt 的二叉排序树上查找一个关键字值为 k 的结点,
//若查找成功返回指向该结点的指针,否则返回空指针
if ( (bt ==NULL ) || ( bt -> key == k )) return bt;
else if (k< bt -> key) return bt_search ( bt -> lchild , k ); //在
左子树中搜索
else return bt_search ( bt -> rchild , k );
//在右
子树中搜索
}

二叉排序树的插入

在一棵二叉排序树中插入一个结点可以用一个递归的过程实现,即:若二叉排序树为空,则新结点作为二叉排序树的根结点;否则,若给定结点的关键字值小于根结点关键字值,则插入在左子树上;若给定结点的关键字值大于根结点的值,则插入在右子树上。
下面是二叉排序树插入操作的递归算法。
void bt_insert1(Bin_Sort_Tree *bt , Bin_Sort_Tree_Node *pn)
{ //在以 bt 为根的二叉排序树上插入一个由指针 pn 指向的新的结点
if ( *bt ==NULL) *bt = pn ;
else if ( *bt -> key > pn->key ) bt_insert1( &(*bt -> lchild) , pn ) ;
else if ( *bt -> key < pn -> key )
bt_insert1 ( &(*bt -> rchild) ,
pn) ;
}
利用二叉排序树的插入算法,可以很容易地实现创建二叉排序树的操作,其基本思想为:由一棵空二叉树开始,经过一系列的查找插入操作生成一棵二叉排序树。例如,由结点关键字序列 (62, 15, 68, 46, 65, 12 , 57 , 79, 35)构造二叉排序树的过程为:从空二叉树开始,依次将每个结点插入到二叉排序树中,在插入每个结点时都是从根结点开始搜索插入位置,找到插入位置后,将新结点作为叶子结点插入,经过 9 次的查找和插入操作,建成由这 9 个结点组成的二叉排序树。
创建二叉排序树的算法如下:
Bin_Sort_Tree_Node *bt_bulid (Bin_Sort_Tree a , int n)
{
//在数组 a 的 a[1]~a[n]单元中存放着将要构成二叉排序树的 n 个结点内容
bt = NULL ;
for ( i =1; i <= n;i++)
{
p = (Bin_Sort_Tree_Node *)malloc (sizeof (Bin_Sort_Tree_Node));
p ->key =a[i].key;
p -> otheritem= a[i].otheritem;
p -> lchild = NULL;
p -> rchild = NULL; //创建结点
bt_insert1( &bt , p); // 插入
}
return ( bt) ;
}

二叉排序树的删除

下面分四种情况讨论一下如何确保从二叉树中删除一个结点后,不会影响二叉排序树的性质:
① 若要删除的结点为叶子结点,可以直接进行删除。
② 若要删除结点有右子树,但无左子树,可用其右子树的根结点取代要删除结点的位置。
③ 若要删除结点有左子树,但无右子树,可用其左子树的根结点取代要删除结点的位置,与步骤 2>类似。
④ 若要删除结点的左右子树均非空,则首先找到要删除结点的右子树中关键字值最小的结点(即右子树中最左结点),利用上面的方法将该结点从右子树中删除,并用它取代要删除结点的位置,这样处理的结果一定能够保证删除结点后二叉树的性质不变。

5.平衡二叉树

平衡二叉树的特点为:左、右子树深度之差的绝对值不大于 1。
构造二叉平衡(查找)树的方法是:在插入过程中,采用平衡旋转技术。基本思想是:在构造二叉排序树的过程中,每当插入一个结点时,首先检查是否因插入而破坏了树的平衡性,如果是因插入结点而破坏了树的平衡性,则找出其中最小不平衡子树,在保持排序树特性的前提下,调整最小不平衡子树中各结点之间的连接关系,以达到新的平衡。 通常将这样得到的平衡二叉排序树简称为 AVL 树。所谓最小不平衡子树,是指以离插入结点最近、且平衡因子绝对值大于 1 的结点作根结点的子树。因此,平衡二叉树上所有结点的平衡因子可能是-1,0,1。
采用平衡旋转技术生成平衡二叉树的过程如下所示:
举例:设一组记录的关键字按以下次序进行插入:4、5、7,2、1、3、6。构造过程为:
假设深度为 h 的二叉平衡树上所含结点数的最小值为 Nh,则 Nh = Nh-1 + Nh-2 + 1,可以证明:h≈log(n)

6.B-树

B-树是一种平衡的多路查找树,其特点如下:
1> 在 m 阶的 B-树上,每个非终端结点可能含有:n 个关键字 Ki(1≤i≤n) n<m;n 个指向记录的指针 Di(1≤i≤n),以及 n+1 个指向子树的指针 Ai(0≤i≤n);
2> 非叶结点中的多个关键字均自小至大有序排列,即:K1< K2 < … < Kn;且 Ai-1所指子树上所有关键字均小于 Ki;Ai 所指子树上所有关键字均大于 Ki;
3> 树中所有叶子结点均不带信息,且在树中的同一层次上;根结点或为叶子结点,或至少有两棵子树;其余非叶结点至少有m/2棵子树,至多有 m 棵子树。
B-树结构的 C 语言描述如下:
#define m 3
// B-树的阶,暂设为 3
typedef struct BTNode {
int keynum;
// 结点中关键字个数, 即结点的大小
struct BTNode *parent; // 指向双亲结点的指针
KeyType
key[m+1];
// 关键字(0 号单元不用)
struct BTNode *ptr[m+1];
// 子树指针向量
Record
*recptr[m+1];
// 记录指针向量
} BTNode, *BTree;
// B-树结点和 B-树的类型

查找

从根结点出发,沿指针搜索结点和在结点内进行顺序(或折半)查找 两个过程交叉进行。若查找成功,则返回指向被查关键字所在结点的指针和关键字在结点中的位置;若查找不成功,则返回插入位置。假设返回的是如下所述结构的记录:
typedef struct {
BTNode *pt;
// 指向找到的结点
int i;
// 1..m,在结点中的关键字序号
int tag;
// 1:查找成功,0:查找失败
} Result;
// 在 B-树的查找结果类型
则下列算法简要地描述了 B-树的查找操作的实现。
result SearchBTree(BTree T, KeyType K)
{ // 在 m 阶 B-树 T 上查找关键字 K,返回结果(pt,i,tag)
p=T; q=NULL; found=FALSE; i=0;
// 初始化,p 指向待查结点,q 指向 p 的双亲
while (p && !found) {
n=p->keynum;
i=Search(p, K);
// 在 p->key[1..keynum]中查找 i ,
// p->key[i]<=K<p->key[i+1]
if (i>0 && p->key[i]==K) found=TRUE;
//找到待查关键字
else { q=p;
p=p->ptr[i]; }
}
if (found) return (p,i,1); // 查找成功
else return (q,i,0); // 查找不成功,返回 K 的插入位置信息
}

插入

在查找不成功之后,需进行插入。显然,关键字插入的位置必定在最下层 的非叶结点,有下列几种情况:
① 插入后,该结点的关键字个数 n<m,不修改指针;
② 插入后,该结点的关键字个数 n=m,则需进行“结点分裂”,令 s = m/2,在原结点中保留(A0,K1,…,Ks-1,As-1);建新结点(As,Ks+1,…,Kn,An);将(Ks,p)插入双亲结点;
③ 若双亲为空,则建新的根结点。

删除

和插入的考虑相反,首先必须找到待删关键字所在结点,并且要求删除之后,结点中关键字的个数不能小于 m/2 -1,否则,要从其左(或右)兄弟结点“借调”关键字,若其左和右兄弟结点均无关键字可借(结点中只有最少量的关键字),则必须进行结点的“合并”。

7.哈希表

哈希表的概念

前面介绍的静态查找表和动态查找表的特点是:为了从查找表中找到关键字值等于某个值的记录,都要经过一系列的关键字比较,以确定待查记录的存储位置或查找失败,查找所需时间总是与比较次数有关。
如果将记录的存储位置与它的关键字之间建立一个确定的关系 H,使每个关键字和一个唯一的存储位置对应,在查找时,只需要根据对应关系计算出给定的关键字值 k 对应的值 H(k),就可以得到记录的存储位置,这就是本节将要介绍的哈希表查找方法的基本思想。

哈希函数

我们将记录的关键字值与记录的存储位置对应起来的关系 H 称为哈希函数,H(k)的结果称为哈希地址。

哈希表

是根据哈希函数建立的表,其基本思想是:以记录的关键字值为自变量,根据哈希函数,计算出对应的哈希地址,并在此存储该记录的内容。当对记录进行查找时,再根据给定的关键字值,用同一个哈希函数计算出给定关键字值对应的存储地址,随后进行访问。所以哈希表即是一种存储形式,又是一种查找方法,通常将这种查找方法称为哈希查找。

冲突

有时可能会出现不同的关键字值其哈希函数计算的哈希地址相同的情况,然而同一个存储位置不可能存储两个记录,我们将这种情况称为冲突,具有相同函数值的关键字值称为同义词。在实际应用中冲突是不可能完全避免的,人们通过实践总结出了多种减少冲突及解决冲突的方法。下面我们将简要地介绍一下。

哈希函数的构造

建立哈希表,关键是构造哈希函数。其原则是尽可能地使任意一组关键字的哈希地址均匀地分布在整个地址空间中,即用任意关键字作为哈希函数的自变量其计算结果随机分布,以便减少冲突的发生可能性。
常用的哈希函数的构造方法有:
(1)直接定址法
取关键字或关键字的某个线性函数为哈希地址。即H(key)=key 或 H(key)=a* key+b其中 a,b 为常数,调整 a 与 b 的值可以使哈希地址取值范围与存储空间范围一致。
(2)质数取余法
取关键字被某个不大于哈希表表长 n 的质数 m 整除后所得余数为哈希地址。即H(key)=key % m (m<n,设其中 n 为哈希表长)。质数取余法计算简单,适用范围大,但是整数 m 的选择很重要,如果选择不当,会产生较多同义词,使哈希表中有较多的冲突。
(3)平方取中法
取关键字平方后的中间几位为哈希地址。由于平方后的中间几位数与原关键字的每一位数字都相关,只要原关键字的分布是随机的,以平方后的中间几位数作为哈希地址一定也是随机分布。
(4)折叠法
把关键字折叠成位数相同的几部分,然后取这几部分的叠加作为哈希地址。在关键字位数较多,且每一位上数字的分布基本均匀时,采用折叠法,得到的哈希地址比较均匀。

解决冲突的方法

常用的处理冲突的方法有:
(1)开放定址法
当发生冲突时,在冲突位置的前后附近寻找可以存放记录的空闲单元。用此法解决冲突,要产生一个探测序列,沿着此序列去寻找可以存放记录的空闲单元。最简单的探测序列产生方法是进行线性探测,即当发生冲突时,从发生冲突的存储位置的下一个存储位置开始依次顺序探测空闲单元。
(2)链地址法
将所有关键字是同义词的记录链接成一个线性链表,将其链头链接在由哈希函数确定的哈希地址所指示的存储单元中。
(3)再哈希法
当发生冲突时,用另一个哈希函数再计算另一个哈希地址,如果再发生冲突,再使用另一个哈希函数,直至不发生冲突为止。这种方法要求预先要设置一个哈希函数的序列。
(4)溢出区法
除基本的存储区外(称为基本表),另外建立一个公共溢出区(称为溢出表),当发生冲突时,记录可以存入这个公共溢出区。

哈希表查找及其分析

哈希表的查找过程与哈希表的构造过程基本一致,对于给定的关键字值 k,按照建表时设定的哈希函数求得哈希地址;若哈希地址所指位置已有记录,并且其关键字值不等于给定值 k, 则根据建表时设定的冲突处理方法求得同义词的下一地址,直到求得的哈希地址所指位置为空闲或其中记录的关键字值等于给定值 k 为止;如果求得的哈希地址对应的内存空间为空闲,则查找失败;如果求得的哈希地址对应的内存空间中的记录关键字值等于给定值 k,则查找成功。
上述查找过程可以描述如下:
(1)计算出给定关键字值对应的哈希地址 addr=H(k);
(2)while( (addr 中不空)&&(addr 中关键字值!=k))按冲突处理方法求得下一地址 addr;
(3)如果 (addr 中为空),则查找失败,返回失败信息;
(4)否则查找成功,并返回地址 addr;
在处理冲突方法相同的哈希表中,其平均查找时间,还依赖于哈希表的装填因子,哈希表的装填因子为:

装填因子越小,表中填入的记录就越少,发生冲突的可能性就会小,反之,表中已填入的记录越多,再填充记录时,发生冲突的可能性就越大,则查找时进行关键字的比较次数就越多。

8. 总结 

本文系统构建了数据结构中的查找技术体系,以存储结构与操作特性为双主线,完整呈现从基础遍历到高阶检索的核心逻辑:

基础架构

查找表分为静态型(仅查询/检索)与动态型(支持增删),通过主关键字(唯一标识)与次关键字(允许多值)实现元素定位。效率评估以**平均查找长度(ASL)**为核心指标,量化比较次数的数学期望值,建立时间复杂度分析框架。

线性结构检索

  • 顺序查找:时间复杂度O(n),ASL=(n+1)/2,通过设置监视哨消除越界检测,适配顺序表/链表结构

  • 折半查找:针对有序顺序表,采用二分分治策略实现O(log n)效率,通过low/high指针动态收缩区间,构建经典对数级检索模型

树形结构演化

  • 二叉排序树:动态维护有序结构,中序遍历得有序序列,ASL与树高正相关,插入顺序直接影响平衡性

  • 平衡二叉树(AVL):引入平衡因子概念,通过四种旋转操作(LL/RR/LR/RL)维持左右子树高度差≤1,确保ASL稳定在O(log n)

  • B-树:多路平衡结构,通过结点分裂/合并机制维持层级平衡,实现海量数据的高效磁盘存取,特别适用于数据库索引场景

哈希映射革命

突破传统比较检索范式,通过哈希函数直接建立关键字与存储地址的映射关系,理想时间复杂度达O(1)。关键技术包含:

  • 构造策略:直接定址法、质数取余法、平方取中法、折叠法四大经典方法

  • 冲突解决:开放定址法(线性探测)、链地址法、再哈希法、溢出区法四维方案

  • 性能调控装填因子α 决定存储密度与冲突概率的平衡关系,指导空间效率优化

技术决策矩阵

  • 静态环境:折半查找效率最优

  • 动态维护:AVL树实现内存级高效平衡,B-树适配外存大规模数据

  • 极速检索:哈希表在低冲突时性能最佳,但牺牲数据有序性特征

  • 复杂度演进:从线性结构的O(n)到树结构的O(log n),最终突破至哈希的理想O(1),体现检索技术的阶跃式发展

该体系完整揭示了不同存储形态下的检索机理,为构建高并发、低延迟的数据系统提供理论基石与工程实践指南。

评论 45
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Lethehong

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值