查找算法-分块查找,哈希查找
分块查找
先选取各块中的最大关键字构成一个索引表;
查找分两个部分:先对索引表进行二分查找或顺序查找,以确定待查记录在哪一块中;然后,在已确定的块中用顺序法进行查找。
时间复杂度为O(log2m+N/m),m为分块的数量,N为主表元素的数量,N/m 就是每块内元素的数量。
举例:例如学号这个问题,一般来说学号的前几位代表年级和学院,例如19030111,19030123,18023123,18023555......,19代表19级,030代表计科院,18代表18级,023代表机电院,我们可以选取学号前5位为最大关键字,按照前五位将以学号为键值的数据分块存储,当我们需要一个学号对应的信息时,我们首先对最大键值二分查找,查出此学号对应的数据块,然后对数据块顺序查找。
优缺点:分块查找的特点其实显而易见,那就是分块查找拥有顺序查找和二分查找的双重优势,即顺序查找不需要有序,二分查找的速度快。分块查找由于只需要索引表有序,所以特别适合用于在动态变化的数据元素序列中查找。但是如何分块比较复杂。如果分块过于稀疏,则可能导致每一块的内容过多,在顺序查找时效率很低;如果分块过密,则又会导致块数很多,无论是插入还是删除数据,都会频繁地进行二分查找;如果块数特别多,则基本上和直接二分查找的动态插入数据类似,这样分块查找就没有意义了。
代码:就是将二分查找和顺序查找拼接,这里不再赘述。
哈希查找
通过计算一个关于键值的函数,将所需查询的数据映射到表中一个位置来访问记录,这加快了查找速度。这个映射函数称做散列函数,存放记录的数组称做散列表。
算法流程:
1. 用给定的哈希函数构造哈希表;
package search; public class hash { static int hash_1(int arrLeng,int value) { return value % arrLeng; } public static int hash_search(int [] hashArr,int value) { int length = hashArr.length; int hashAdd = hash_1(length,value); while (hashArr[hashAdd] != value) { hashAdd = (hashAdd + 1) % length; if (hashArr[hashAdd] == -1 || hashAdd == hash_1(length,value)) { return -1; } } return hashAdd; } public static void main(String[] args) { int[] hashArr = new int[] {77,44,-1,-1,26,93,17,-1,-1,31,54}; int hashAdd = hash_search(hashArr,77); if(hashAdd == -1) { System.out.println("fail"); } else { System.out.println("index = " + hashAdd); } } }
实现方法:可以自己编写,也可以直接调用Java的hashmap实现。
import java.util.HashMap; public class RunoobTest { public static void main(String[] args) { // 创建 HashMap 对象 Sites HashMap<Integer, String> Sites = new HashMap<Integer, String>(); // 添加键值对 Sites.put(1, "Google"); Sites.put(2, "Runoob"); Sites.put(3, "Taobao"); Sites.put(4, "Zhihu"); System.out.println(Sites.get(3)); } }