查找算法总结
查找经常进行的操作:
(1)查找key是都存在于当前集合;
(2)在查找集合中插入key;
(3)在查找集合中删除key;
静态查找:在查询集合中,查找key是否存在。
动态查找:在查找过程中同时插入集合中不存在的元素;或者删除查找元素。
查找算法分类:
(1)静态查找算法:顺序查找,二分查找(折半查找),索引查找(分块查找);
(2)动态查找算法:二叉排序树;
(3)哈希查找算法
顺序查找(评价查找长度(n+1)/2)
1)算法实现
/*
* 顺序查找,返回key在数组中的位置
* nums[0]中不放数据
*/
public int orderSearch(int[] nums,int key){
int i=0;
nums[0]=key;//哨兵,省去查找过程中每一步都要检测是否整个集合查找完成
for(i=nums.length-1;nums[i]!=key;i--);
return i;
}
2)优化思路
从概率角度来讲,目前查找的元素越多代表可能将来被查找的可能性就比较大;考虑LRU和LFU思想。
二分查找(平均查找长度(logn+1))
1)算法描述
限制条件:适用于有序的序列结构,且顺序存储结构
每次key和当前集合中终点比较,相等返回;小于则在中点左侧查找;大于则在中点右侧查找。
2)算法实现
非递归
/*
* 二分查找非递归,返回key在数组中的位置
* nums[0]无效
*/
public int binarySearch(int[] nums,int key){
int start=1;
int end=nums.length-1;
int mid=0;
while(start<=end){
mid=(start+end)/2;
if(nums[mid]==key){
return mid;
}else {
if(nums[mid]>key){
end=mid-1;
}else {
start=mid+1;
}
}
}
return 0;
}
递归
/*
*二分查找递归,返回key在数组中的位置
* nums[0]无效
*/
public int binarySearchRecursion(int[] nums,int key,int start,int end){
if(start>end){
return 0;
}
int mid=(start+end)/2;
if(nums[mid]==key){
return mid;
}else {
if(nums[mid]>key){
return binarySearchRecursion(nums,key,start,mid-1);
}else {
return binarySearchRecursion(nums,key,mid+1,end);
}
}
}
索引查找(平均查找长度在顺序查找和二分查找之间)
算法描述:
为了减少查找时间,以增加空间复杂度为代价。为原有集合建立索引结构(有序),查找过程中,先在索引结构中查找,再在索引相应的集合块中查找。
将集合进行分块,每块建立相应的最大关键值和起始位置,这样构成相应的索引结构。用二分查找key可能在的索引块,然后在块内进行顺序查找。
二叉排序树查找
1)基本思路
改进二分查找中的缺陷(插入和删除过程需要移动大量的元素),用二叉排序树存储数据。二叉树的插入和删除的时间复杂度比较低,且支持二分查找。
2)具体实现
后续将贴出相应代码...
哈希查找
1)基本思路
将元素的key和value直接对应。将key经过哈希函数映射到某一地址。
2)哈希函数
直接定址;数字分析法;平方取中法;除留余数法;随机数法;
3)处理冲突方法
开放定址法;再哈希法;链地址法;