持续输出面试题之算法--线性表的查找

310 阅读1分钟

开篇介绍

大家好,我是Java最全面试题库的提裤姐,今天这篇是数据结构与算法的第七篇,主要介绍查找中的线性表的查找;在后续,会沿着第一篇开篇的知识线路一直总结下去,做到日更!如果我能做到百日百更,希望你也可以跟着百日百刷,一百天养成一个好习惯。

顺序查找

1.定义: 顺序查找是按照序列原有顺序对数组进行遍历比较查询的基本查找算法

2.原理: 通过遍历数组来寻找值

3.代码实现:

 public static int ordersearch(int[] arry, int des) {
        int i = 0;
        for (; i <= arry.length - 1; i++) {
            if (des == arry[i])
                return i;
        }
        return -1;
    }

二分查找

1.定义: 分查找也称折半查找(Binary Search),它是一种效率较高的查找方法。但是,折半查找要求线性表必须采用顺序存储结构,而且表中元素按关键字有序排列

2.原理: 首先,假设表中元素是按升序排列,将表中间位置记录的关键字与查找关键字比较,如果两者相等,则查找成功;否则利用中间位置记录将表分成前、后两个子表,如果中间位置记录的关键字大于查找关键字,则进一步查找前一子表,否则进一步查找后一子表。重复以上过程,直到找到满足条件的记录,使查找成功,或直到子表不存在为止,此时查找不成功。

二分查找.png

3.代码实现:

public static int binarySearch(Integer[] srcArray, int des) {
    //定义初始最小、最大索引
    int start = 0;
    int end = srcArray.length - 1;
    //确保不会出现重复查找,越界
    while (start <= end) {
        //计算出中间索引值
        int middle = (end + start)>>>1 ;//防止溢出
        if (des == srcArray[middle]) {
            return middle;
        //判断下限
        } else if (des < srcArray[middle]) {
            end = middle - 1;
        //判断上限
        } else {
            start = middle + 1;
        }
    }
    //若没有,则返回-1
    return -1;
}

分块查找

1.定义: 分块查找是折半查找和顺序查找的一种改进方法,分块查找由于只要求索引表是有序的,对块内节点没有排序要求,因此特别适合于节点动态变化的情况。

2.原理: 分块查找要求把一个大的线性表分解成若干块,每块中的节点可以任意存放,但块与块之间必须排序。假设是按关键码值非递减的,那么这种块与块之间必须满足已排序要求,实际上就是对于任意的i,第i块中的所有节点的关键码值都必须小于第i+1块中的所有节点的关键码值。此外,还要建立一个索引表,把每块中的最大关键码值作为索引表的关键码值,按块的顺序存放到一个辅助数组中,显然这个辅助数组是按关键码值费递减排序的。查找时,首先在索引表中进行查找,确定要找的节点所在的块。由于索引表是排序的,因此,对索引表的查找可以采用顺序查找或折半查找;然后,在相应的块中采用顺序查找,即可找到对应的节点。 分块查找.png

3.代码实现:

//index代表索引数组,st2代表待查找数组,keytype代表要查找的元素,m代表每块大小
	public static int blocksearch(int[] index,int[]st2,int keytype,int m){
		int i=shunxusearch(index,keytype);    //shunxunsearch函数返回值为带查找元素在第几块
		System.out.println("在第"+i+"块");
		if(i>=0){
		int j=m*i;   //j为第i块的第一个元素下标
		int curlen=(i+1)*m;    
		for(;j<curlen;j++){
			if(st2[j]==keytype)
				return j;
		}
		}
		return -1;
		
	}
	public static int shunxusearch(int[]index,int keytype){
		if(index[0]>keytype){   //如果第一块中最大元素大于待查找元素
			return 0;    //返回0.即待查找元素在第0块
		}
		int i=1;
		while((index[i-1]<keytype)&&(index[i]>keytype))
			return i;
		return -1;