查找算法之分块查找
查找算法之分块查找
前言
查找算法是一种用于在数据集合中查找特定元素的算法。在计算机科学中,查找算法通常被用于在数组、链表、树等数据结构中查找目标元素的位置或者判断目标元素是否存在。
查找算法的目标是在尽可能短的时间内找到目标元素,以提高程序的效率和性能。常见的查找算法包括但不限于二分查找、哈希表查找、线性查找、二叉查找树等。
一、查找算法预备知识
查找算法分类
1)静态查找和动态查找;
注:静态或者动态都是针对查找表而言的。动态表指查找表中有删除和插入操作的表。
2)无序查找和有序查找。
无序查找:被查找数列有序无序均可;
有序查找:被查找数列必须为有序数列。
平均查找长度(Average Search Length,ASL)
需和指定key进行比较的关键字的个数的期望值,称为查找算法在查找成功时的平均查找长度。
对于含有n个数据元素的查找表,查找成功的平均查找长度为:ASL = Pi*Ci
的和。
Pi:查找表中第i个数据元素的概率。
Ci:找到第i个数据元素时已经比较过的次数。
二、分块查找
分块查找
(Blocking Search)又称为索引顺序查找法,在此查找法中,除了原表本身以外还需要建立一个“索引表”,即将原表分成一块一块,每一块选取其最大的记录作为关键字项,块中的起始下标为块的指针项。索引表按照关键字有序,即块与块之间有序,块内元素无序。查找时先确定待查找的记录在哪一块,再在具体某个块内使用顺序查找法查找其具体位置。故其性能介于顺序查找法和折半查找法之间。
算法步骤
- 首先确定待查记录所在的块(子表)
- 然后在块中进行顺序查找确定记录的最终位置
public class BlockSearch {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
//原表
int a[] = {9, 22, 12, 14, 35, 42, 44, 38, 48, 60, 58, 47, 78, 80, 77, 82};
//分块获得对应的索引表,这里是一个以索引结点为元素的对象数组
BlockTable[] arr = {
new BlockTable(22, 0, 3),//最大关键字为22 起始下标为0,3的块
new BlockTable(44, 4, 7),
new BlockTable(60, 8, 11),
new BlockTable(82, 12, 15)
};
//打印原表
System.out.print("原表元素如下:");
for (int i = 0; i < a.length; i++) {
System.out.print(a[i] + " ");
}
System.out.println();
//待查关键字
while (true) {
System.out.print("请输入你所要查询的关键字:");
int key = input.nextInt();
//调用分块查找算法,并输出查找的结果
int result = BlockSearch(a, arr, key);
System.out.print("查询结果为:" + result);
System.out.println();
}
}
private static int BlockSearch(int a[], BlockTable[] arr, int key) {
int left = 0, right = arr.length - 1;
//利用折半查找法查找元素所在的块
while (left <= right) {
int mid = (left + right) >>> 1;
if (arr[mid].key >= key) {
right = mid - 1;
} else {
left = mid + 1;
}
}
//循环结束,元素所在的块为right+1 取对应左区间下标作为循环的开始点
int i = arr[right + 1].low;
//在块内进行顺序查找确定记录的最终位置
while (i <= arr[right + 1].high && a[i] != key) {
i++;
}
//如果下标在块的范围之内,说明查找成功,佛否则失败
if (i <= arr[right + 1].high) {
return i;
} else {
return -1;
}
}
}
//索引表结点
class BlockTable {
int key;
int low;
int high;
BlockTable(int key, int low, int high) {
this.key = key;
this.low = low;
this.high = high;
}
}
三、总结
3.1 查找性能
时间、空间复杂度均不超过O(n)
3.2 适用场景
适用于静态查找表
:即查找表不经常发生变化,适合建立分块索引。
适用于有序表
:由于分块查找是基于有序表的,因此适用于有序表的查找。
数据量较大
:当数据量较大时,分块查找可以将数据分块处理,提高查找效率。
查找频繁
:如果需要频繁进行查找操作,分块查找可以提供较快的查找速度。
总的来说,分块查找结合了顺序查找和折半查找的优点,适用于静态、有序、数据量大且需要频繁查找的情况。它能够有效地减少查找时间,提高查找效率。
3.3 优缺点
优点:
在表中插入和删除元素时,只需要找到对应的块,就可以在块内进行插入和删除运算
块内无序,插入和删除都较为容易,无需进行大量移动
适合线性表既要快速查找又要经常动态变化的场景
缺点:
需要增加一个存储索引表的内存空间
需要对初始索引表按照其最大关键字(或最小关键字)进行排序运算
参考链接:
Java基本查找算法–分块查找
开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!
更多推荐
所有评论(0)