查找算法总结:顺序查找,二分查找,分块查找,散列查找,二叉排序树查找

原创 2016年08月29日 20:56:32

查找算法包括:顺序查找,二分查找,分块查找,散列查找,二叉排序树查找,B树
B树用于查找磁盘数据,这里不进行分析

顺序查找

思想:从头到尾一个一个比较,简单,时间复杂度O(n)

java实现:

public static int seqSearch(List<Integer> arr, int key) {
        for (int i = 0; i < arr.size(); i++) {
            if (arr.get(i) == Integer.valueOf(key)) {
                return i;
            }
        }
        return -1;
    }

二分查找

二分查找要求,待查找的数组有序,且不能用于链表的查找

思想:分而治之,若要查找的key比当前的值小则在左半部分查找,否则在右半部分找,每次缩小一半查找范围。直到找到或者没找到,没找到的条件是起始位置大于终止位置。

时间复杂度:O(logn)

java实现:

//非递归实现
public static int binSearch(List<Integer> arr, int key, int low, int high) {
        int middle = (low + high) / 2;
        while (low < high) {
            if (arr.get(middle) < key) {
                low = middle + 1;
            } else if (arr.get(middle) > key) {
                high = middle - 1;
            } else {
                return middle;
            }
            middle = (low + high) / 2;
        }
        return -1;
    }

//递归实现

/**
     * 递归二分查找
     * @param arr
     * @param key
     * @param low
     * @param high
     * @return
     */
    public static int binSearchRecur(List<Integer> arr, int key, int low, int high) {

        if (low > high)
            return -1;
        int middle = (low + high) / 2;
        if (arr.get(middle) == key) {
            return middle;
        }
        if (arr.get(middle) < key) {
            return binSearchRecur(arr, key, middle + 1, high);
        } else {
            return binSearchRecur(arr, key, low, middle - 1);
        }
    }

单元测试

public class Search {
    public static void main(String[] args) {

        System.out.println("请输入数组:");
        List<Integer> arr = new ArrayList<Integer>();

        int key = 0;
        Scanner input = new Scanner(System.in);
        String strInput = input.nextLine();
        String[] inputs = strInput.split(" ");
        for (int j = 0; j < inputs.length; j++) {
            arr.add(Integer.valueOf(inputs[j]));
        }

        System.out.println("请输入要查找的数:");
        key = input.nextInt();


        System.out.println("顺序查找,找到的位置为:" + (seqSearch(arr, key)));

        System.out.println("二分查找,找到的位置为:" + binSearch(arr, key, 0, arr.size() - 1));
        System.out.println("递归二分查找,找到的位置为:" + binSearchRecur(arr, key, 0, arr.size() - 1));

    }

    public static int seqSearch(List<Integer> arr, int key) {
        for (int i = 0; i < arr.size(); i++) {
            if (arr.get(i) == Integer.valueOf(key)) {
                return i;
            }
        }
        return -1;
    }

    public static int binSearch(List<Integer> arr, int key, int low, int high) {
        int middle = (low + high) / 2;
        while (low < high) {
            if (arr.get(middle) < key) {
                low = middle + 1;
            } else if (arr.get(middle) > key) {
                high = middle - 1;
            } else {
                return middle;
            }
            //每次缩小一半范围
            middle = (low + high) / 2;
        }
        return -1;
    }

    /**
     * 递归二分查找
     * @param arr
     * @param key
     * @param low
     * @param high
     * @return
     */
    public static int binSearchRecur(List<Integer> arr, int key, int low, int high) {

        if (low > high)
            return -1;
        int middle = (low + high) / 2;
        if (arr.get(middle) == key) {
            return middle;
        }
        if (arr.get(middle) < key) {
            return binSearchRecur(arr, key, middle + 1, high);
        } else {
            return binSearchRecur(arr, key, low, middle - 1);
        }
    }
}

分块查找

这里写图片描述

分块查找思想:将表固定长度分成若干块,建立索引表记录块起始地址和该块内的最大值,索引表是有序的,可以使用二分查找和顺序查找,找到key所处的块,在在该块内查找。块内是无序的可以使用顺序查找。

步骤:
1.创建索引表。
2.在索引表内查找,在块内查找。

设表共n个结点,分b块,s=n/b

(分块查找索引表)平均查找长度=Log2(n/s+1)+s/2

(顺序查找索引表)平均查找长度=(S2+2S+n)/(2S)

优点:
  ①在表中插入或删除一个记录时,只要找到该记录所属的块,就在该块内进行插入和删除运算。
  ②因块内记录的存放是任意的,所以插入或删除比较容易,无须移动大量记录。
  分块查找的主要代价是增加一个辅助数组的存储空间和将初始表分块排序的运算。
分块查找算法的效率介于顺序查找和二分查找之间。
若表中有10000个结点,则应把它分成100个块,每块中含100个结点。用顺序查找确定块,分块查找平均需要做100次比较,而顺序查找平均需做5000次比较,二分查找最多需14次比较。

散列查找

[ 什么是散列表查找 ]
散列技术是在记录的存储位置和它的关键字之间建立一个确定的对应关系f,使得每个关键字key对应一个存储位置f(key)
这个对应关系f()称为散列函数或哈希函数。
采用散列技术将记录存储在一块连续的存储空间中,这块连续存储空间称为散列表或哈希表,那么关键字对应的记录存储位置我们称为散列地址。

[ 散列技术的优缺点 ]
使用散列技术,对于查找来书,简化了比较过程,效率会大大提高
但是散列技术不适合一个关键字对应多条记录的情况,如通过“男”查找班级里所有男生。
散列技术需要解决的另一个问题就是冲突:如k1 != k2, 但是f(k1) == f(k2), 这种现象我们称为冲突,并把k1和k2称为散列函数的同义词。

[ 散列函数构造方法 ]
1. 直接定址法:
2. 数字分析法:
3. 平方取中法:
4. 折叠法:
5. 除留余数法:
6. 随机数法:

[ 处理散列冲突的方法 ]
1. 开放地址法:
2. 再散列函数法:
3. 链地址法:
4. 公共溢出区法:

[ 散列表查找实现 ]
具体程序请查看HashMap,HashSet,Hashtable
当从HashSet集合中查找某个对象时,Java系统首先调用对象的hashCode()方法获得该对象的哈希码,然后根据哈希码找到对应的存储区域,最后取得该存储区域内的每个元素与该对象进行equals方法比较,这样就不用遍历集合中的所有元素就可以得到结论,可见HashSet集合具有很好的对象检索性能。
http://blog.chinaunix.net/uid-26981819-id-4462638.html 源码分析

[ 散列表查找性能分析 ]
如果没有冲突,散列查找是所有查找中效率最高的,因为它的时间复杂度为O(1), 可惜没有冲突的散列只是一种理想情况。

参考:http://java-mzd.iteye.com/blog/827523
参考:equals和hashcode http://www.cnblogs.com/dolphin0520/p/3681042.html
hashmap源码分析 http://blog.chinaunix.net/uid-26981819-id-4462638.html

二叉查找树查找

二叉查找树又叫二叉排序树,是满足 左子节点<根节点<右子节点 的二叉树。
因此查找使用递归很容易实现,难点主要是创建二叉树和维护二叉排序树的规则,这个以后详解。

思想:从根节点开始比较,比节点小则查找左子树,比节点大则查找右子树,相等返回。递归进行。

查找算法递归实现:

结点类型:

static class node{
int value;
node leftChild;
node rightChild;
}
递归查找:

public static node BSTSearch(node head,int key){
        if(key==head.value){
            return head;
        }else if(key < head.value){
            return BSTSearch(head.leftChild,key);
        }else {
            return BSTSearch(head.rightChild, key);
        }
    }

非递归实现:主要循环判断是否相等。

public static node BSTSearch(node head,int key){
        while(head.value !=key){
            if(key<head.value){
                head = head.leftChild;
            }else{
                head = head.rightChild;
            }
            if(head == null){
                break;
            }
        }
        return head;
    }
版权声明:本文为博主原创文章,未经博主允许不得转载。

三大查找算法总结:二分查找,分块查找和哈希表查找。

终于下定决心把查找和排序好好整一整,今天就弄了一个对分查找,也成为对半查找。原理十分简单,话不多说,直接上源代码。未完待续,持续更新中。。。 1、对半查找,要求输入有序序列。 // sort.cp...
  • XIAXIA__
  • XIAXIA__
  • 2013年06月22日 22:06
  • 2696

java实现顺序查找、二分查找、哈希表查找、二叉排序树查找

java实现顺序查找、二分查找、哈希表查找、二叉排序树查找
  • Rebirth_Love
  • Rebirth_Love
  • 2016年05月04日 16:43
  • 1933

二分查找不一定比顺序查找到的效率高

看到数据结构B-树的时候,听到老师的一句话在对于某一个结点内部的向量查找来说,这个结点是KB量级的几百个关键字组成,这个时候顺序查找是比二分查找的效率更高的。 具体的我还没搞清楚,因为之前对于算法复杂...
  • u010796650
  • u010796650
  • 2016年07月17日 23:02
  • 912

算法-查找-线性表的查找(顺序查找,二分查找,分块查找)

这里介绍几种基于线性表的查找方法: 顺序查找 二分查找 分块查找 查找的定义是:给定一个值K,在含有n个结点的表中找出关键字等于给定值K的结点。若找到,则查找成功,返回该结点的信息或该结点在表中的位置...
  • ahafg
  • ahafg
  • 2015年11月10日 11:57
  • 1699

在二分搜索应用于未排序的数组时加入部分检测程序—编程珠玑第五章习题5

在二分搜索应用于未排序的数组时加入部分检测程序—编程珠玑第五章习题5        大家都知道二分搜索算法应该用在已经排序好的数组中,但是有时候会犯一些错误,一个常见的错误就是把二分搜索应用...
  • chenglinhust
  • chenglinhust
  • 2012年08月16日 16:43
  • 2153

ZOJ题目分类

简单题 #1001 -____-b  A+B。 #1110 Dick and Jane 胡乱枚举收缩一下情况就可以了。 #1115 a[i+1] = a[i] 的全部数位上的加起来,直到剩下一个...
  • Wss0130
  • Wss0130
  • 2012年08月18日 09:54
  • 9054

线性表的查找(顺序查找,二分查找,分块查找)

1.顺序查找 #include #include #define MAXSIZE 10 int a[MAXSIZE]={1,3,6,8,5,21,11,44,0,22}; typedef str...
  • liguohanhaha
  • liguohanhaha
  • 2016年02月03日 15:03
  • 862

查找算法系列之简单查找:顺序查找、二分查找、分块查找

近期总结了各大排序算法的原理 ,并对其进行了实现,想着一并把查找算法总结了,今天就着手开始总结查找算法。 废话不多说,这篇文章从最简单的查找算法开始讲起,之后会补充复杂的二叉搜索树查找(BST)和B树...
  • u010025211
  • u010025211
  • 2015年06月25日 13:20
  • 4160

查找算法总结:顺序查找,二分查找,分块查找,散列查找,二叉排序树查找

查找算法包括:顺序查找,二分查找,分块查找,散列查找,二叉排序树查找,B树 B树用于查找磁盘数据,这里不进行分析顺序查找思想:从头到尾一个一个比较,简单,时间复杂度O(n)java实现:public...
  • Houson_c
  • Houson_c
  • 2016年08月29日 20:56
  • 897

//写一个生成10个100以内随机数数据,再进行冒泡排序,顺序,//二分查找法找到一个值得位置,如果没有则为-1,有则返回数组位置

//写一个生成10个100以内随机数数据,再进行冒泡排序,顺序 public static void main(String[] args) { int[] arr=new int[10]; f...
  • u011163023
  • u011163023
  • 2016年03月10日 17:32
  • 2179
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:查找算法总结:顺序查找,二分查找,分块查找,散列查找,二叉排序树查找
举报原因:
原因补充:

(最多只允许输入30个字)