算法与数据结构 (七) 查找 数组的优化方向: 二分查找和哈希查找,

一 查找

查找生活中的例子很多,拿快递驿站来说,我们怎么才能更快的找到自己的快递。如果一点顺序都没有,查找的时间复杂度为O(n)。第一种想到的就是给每个快递一个编号,然后按照编号放好,这样我们只要使用先看中间,就每次可以淘汰一半的快递(也就是二分查找的思路)代价是O(lgn)。很明显生活中不是这样,生活中如果快递比较少,按照手机尾号分类,就是一种hash算法,这样查找的效率提高很多。

二 二分查找的简单实现

这里另外写了一个方法 也就是找到所有符合条件的key,基本思路就是找到左边界和右边界。

public class ErFen {
    public static void main(String[] args) {
        int arr[] = {1, 2, 3, 4, 4,4,5, 69, 88, 555};
        System.out.println(find(arr,4));
        System.out.println(Arrays.toString(findAll(arr, 4)));
    }

    public static int[] findAll(int[] arr, int key) {
        int begin = 0;
        int end = arr.length - 1;
        int mid = (begin + end) / 2;
        int left = -1;
        int right = -1;
        while (true) {
            if(arr[mid]==key&&(mid==0||arr[mid]>arr[mid-1])){
                left = mid;
                break;
            }else if(arr[mid]>=key){
                end = mid - 1;
            }else{
                begin = mid + 1;
            }
            if (begin > end) {
                break;

            }
            mid = (begin + end) / 2;
        }
        if(left==-1)
            return new int[]{-1 , -1};
          begin = 0;
          end = arr.length - 1;
          mid = (begin + end) / 2;
        while (true) {
            if(arr[mid]==key&&(mid==arr.length-1||arr[mid]<arr[mid+1])){
                right = mid;
                break;
            }else if(arr[mid]<=key){
                begin = mid + 1;
            }else{
                end = mid - 1;
            }

            mid = (begin + end) / 2;
        }
        return new int[]{left, right};

    }
    public static int find(int[] arr, int key) {
        int begin = 0;
        int end = arr.length - 1;
        int mid = (begin + end) / 2;
        while (true) {
            if(arr[mid]==key)
                return mid;
            else if(arr[mid]<key)
                begin = mid + 1;
            else
                end = mid - 1;
            if (begin > end) {
                break;

            }
            mid = (begin + end) / 2;
        }
        return -1;
    }
}

 三  哈希函数的相关问题

hash函数可以看作是一种分类的思想,既然分类就涉及到一类的元素怎么处理,一种是开放地址法  比如放快递的时候 ,尾号以75已经有快递了,就放在74上。另一种就是hashmap中采用的,也就是拉链法,把一个分类的组织起来,也就是经典的桶结构。

其次是常见应用:

1.字符串哈希(hashmap)
       在数据存储领域,主要是数据的索引和对容器的结构化支持,比如哈希表。
2.加密哈希
       用于数据/用户核查和验证。一个强大的加密哈希函数很难从结果再得到原始数据。加密哈希函数用于哈希用户的密码,用来代替密码本身存在某个服务器撒很难过。加密哈希函数也被视为不可逆的压缩功能,能够代表一个信号标识的大量数据,可以非常有用的判断当前的数据是否已经被篡改(比如MD5),也可以作为一个数据标志使用,以证明了通过其他手段加密文件的真实性。

3.布隆过滤器
       

猜你喜欢

转载自www.cnblogs.com/caijiwdq/p/11071060.html