关闭

Java 查找算法

标签: 算法
12762人阅读 评论(0) 收藏 举报
分类:

这个问题有几个点要先确认

  • 必须是有序,如果无序的话就只能全遍历了
  • 查找算法跟数据结构相关,不同的数据结构适用于不同的查找算法
  • 查找算法与磁盘I/O有一定的关系,比如数据库在索引排序的时候,如果每次都从磁盘读取一个节点然后进行判断

数组

如果知道下标的话就方便了,查找的复杂度为1.
如果是针对值的查找,那么顺序遍历是O(n),

二分查找

使用二分查找的话可以减少时间复杂度为:O(logn)

/**
 * 二分查找又称折半查找,它是一种效率较高的查找方法。 
  【二分查找要求】:1.必须采用顺序存储结构 2.必须按关键字大小有序排列。
 * @author wzj
 *
 */
public class BinarySearch { 
    public static void main(String[] args) {
        int[] src = new int[] {1, 3, 5, 7, 8, 9}; 
        System.out.println(binarySearch(src, 3));
        System.out.println(binarySearch(src,3,0,src.length-1));
    }

    /**
     * * 二分查找算法 * *
     * 
     * @param srcArray
     *            有序数组 *
     * @param des
     *            查找元素 *
     * @return des的数组下标,没找到返回-1
     */ 
   public static int binarySearch(int[] srcArray, int des){ 

        int low = 0; 
        int high = srcArray.length-1; 
        while(low <= high) { 
            int middle = (low + high)/2; 
            if(des == srcArray[middle]) { 
                return middle; 
            }else if(des <srcArray[middle]) { 
                high = middle - 1; 
            }else { 
                low = middle + 1; 
            }
        }
        return -1;
   }

      /**  
     *二分查找特定整数在整型数组中的位置(递归)  
     *@paramdataset  
     *@paramdata  
     *@parambeginIndex  
     *@paramendIndex  
     *@returnindex  
     */
    public static int binarySearch(int[] dataset,int data,int beginIndex,int endIndex){  
       int midIndex = (beginIndex+endIndex)/2;  
       if(data <dataset[beginIndex]||data>dataset[endIndex]||beginIndex>endIndex){
           return -1;  
       }
       if(data <dataset[midIndex]){  
           return binarySearch(dataset,data,beginIndex,midIndex-1);  
       }else if(data>dataset[midIndex]){  
           return binarySearch(dataset,data,midIndex+1,endIndex);  
       }else {  
           return midIndex;  
       }  
   } 
}

但是插入因为会涉及当前节点后的所有值得移动,一次,其时间复杂度为O(n) + O(log n)

链表

只能从头节点遍历, 查找的复杂度是O(n)
插入或者是删除,因为只需要移动指针,时间复杂度为O(1) + O(n)

树的查找,主要是先序遍历,中序等遍历方式。
插入和删除,还是比较快
常用的会有如下的衍生方式:

二叉树

二叉树的构建:

class BinaryNode{
        int value;
        BinaryNode left;
        BinaryNode right;
        public BinaryNode(int value){
            this.value = value;
            this.left = null;
            this.right = null;
        }

        public void add(int value){
            if(value > this.value){
                if(this.right != null){
                    this.right.add(value);
                }else{
                    this.right = new BinaryNode(value);
                }
            }else{
                if(this.left != null){
                    this.left.add(value);
                }else{
                    this.left = new BinaryNode(value);
                }
            }
        }

        // 中序查找
        public BinaryNode get(int value){
            if(this.value == value){
                return this;
            }
            if(this.value > value){
                return this.left.get(value);
            }

            if(this.value < value){
                return this.right.get(value);
            }
            return null;
        }
    }

插入的复杂度本身并不高,只是简单的节点添加。但是因为寻找插入位置的查找操作的复杂度跟树的高度相关为logn,极差的情况下可能接近于线性查找。

平衡二叉树

平衡二叉树是尽量减少数高的二叉树,其算法中增加了左旋和右旋的操作。插入复杂度会高一些,但是会得到不错的查找性能。

B+Tree

学习自这里
这个就要说一下上面说的跟磁盘I/O相关的,因此为了减少磁盘I/O。可以利用磁盘的预读特性,一次提取大概相当于一页大小的节点到内存中。
先要说一下B-Tree.
一个平衡的m-way查找数,其要满足如下的条件:

  • 每节点中的数据量 < m
  • 每层节点数 <= m
  • 子数节点要完全大于、小于、或者在其之间。 也就是不能越过父节点的两个值
  • 叶子节点中的值的个数>=m/2
  • 非叶子节点中的值的个数=子节点个数-1
    如下图:
    这里写图片描述
    可以看出,三个子节点的有两个值,三个子节点中的数据分别对应了小于、之间、大于这个范围

B+Tree
与上面的差别是:

  • 所有关键字都在叶子节点
  • 父节点存储的都是到子节点的指针
  • 会有两个入口,一个是根节点,另外一个是从最小叶子节点开始的指针
    这里写图片描述

查找跟二叉树比较像,因为插入的时候已经是相当于二分算法了,所以只需要,递归找到就可以了。

Hash表

为了解决一些不容易排序,或者查找的对象。 比如图像,视频等等。
在Java的HashMap中有使用。
是一个链表的数组
- 对key进行进行散列函数,求Hash值,找到其对应的链表。
- 剩下的解决hash冲突的问题
- 解决hash冲突,可以在命中链表之后顺序比较
- 这里顺便再说一下一致性hash. 预置很多节点,选择最近的节点存入,可以解决增加节点数据转移的问题。

2
0
查看评论

各种查找的实现Java

使用Java实现各种查找,顺序查找,快速查找,有序顺序查找,二分查找,一致对半查找,斐波那契查找,插值查找。
  • liangxiamoyi
  • liangxiamoyi
  • 2016-08-11 18:58
  • 1343

常见查找算法(Java实现)

查找的性能分析: 对于查找算法而言,常用“其关键字和给定值进行过比较的记录个数的平均值”作为衡量查找算法的依据。 定义:为了确定记录在查找表中的位置,需要和给定的值进行比较的关键字个数的期望值称为查找算法在查找成功时的平均查找长度。 对于含有n个记录的表。查找成功时的平均查找长度为ASL=∑i...
  • wqc_CSDN
  • wqc_CSDN
  • 2016-09-29 17:33
  • 4036

顺序查找和二分法查找(java代码)

顺序查找和二分法查找
  • XiangTianZaiJie500
  • XiangTianZaiJie500
  • 2017-01-22 16:17
  • 1774

java实现二叉查找树(插入、删除、遍历、查找)

二叉查找树的构建,查询,删除,遍历等
  • chen_zhang_yu
  • chen_zhang_yu
  • 2016-09-02 21:27
  • 2913

Java查找算法--线性查找

原文地址:http://blog.csdn.net/u014494703/article/details/51276361 常见的三大线性查找: 线性查找二分查找(折半查找)分块查找 线性查找思路:  在待查数据中进行顺序性轮询查找,当存在待查的数据时返回当前数据索引位置,...
  • tanga842428
  • tanga842428
  • 2016-09-20 19:53
  • 1628

java查找算法(一)--顺序查找

对给定数组(字符串)顺序进行查找元素是否存在。public class SeqSearch { public static void main(String args[]){ int [] array={32,5,67,6,1,7}; ...
  • y999666
  • y999666
  • 2016-03-21 14:08
  • 1676

Java排序与查找

参考博客地址 http://blog.csdn.net/pzhtpf/article/details/7560294
  • googlevsbing
  • googlevsbing
  • 2016-02-26 10:41
  • 492

java 查找字符串所在的位置

使用了 String 类的 indexOf() 方法在字符串中查找子字符串出现的位置,如过存在返回字符串出现的位置(第一位为0),如果不存在返回 -1。方便判断和截取字符串! 语法:stringObject.indexOf(searchvalue,fromindex) 参数   ...
  • csdn9_14
  • csdn9_14
  • 2016-12-15 16:45
  • 9192

java实现常见查找算法

查找 查找(Searching)就是根据给定的某个值,在查找表中确定一个其关键字等于给定值的数据元素(或记录)。 在互联网上查找信息是我们的家常便饭。所有这些需要被查的数据所在的集合,我们给它一个统称叫查找表。 查找表(Search Table)是由同一类型的数据元素(或记录)构成的集合。 关...
  • smile_from_2015
  • smile_from_2015
  • 2017-06-15 22:04
  • 1950

[Java]各种基础的查找和排序算法总结

查找方法: 1.顺序查找。 按数组的顺序从前往后一直比较,直到找到目标值返回。 优点:对数组的结构没有特定的要求,算法简单。 缺点:当数组个数n较大时,效率低下。 时间复杂度:最大时间复杂度是O(n),最小时间复杂度是O(1),平均时间复杂度是O(n/2). /** * 顺序查找算法 ...
  • qq284565035
  • qq284565035
  • 2014-12-02 16:30
  • 1837
    个人资料
    • 访问:1134080次
    • 积分:7048
    • 等级:
    • 排名:第3880名
    • 原创:129篇
    • 转载:4篇
    • 译文:1篇
    • 评论:47条
    博客专栏
    文章分类
    最新评论