查找算法-尚硅谷数据结构与算法(Java)-19-线性-二分-插值

本文详细介绍了三种常见的数组查找算法:线性查找、二分查找及其优化——插值查找。线性查找适用于无序数组,而二分查找在有序数组中效率更高。插值查找则是对二分查找的一种改进,根据目标值自适应地计算中间位置,以提高查找速度。示例代码展示了每种查找算法的实现细节。

目录

:(1) 线性查找                                                                                        

:(2) 二分查找                                                                                        

:(3) 插值查找                                                                                        


:(1) 线性查找                                                                                        

package com.atguigu.search;
//线性查找
public class SeqSearch {

	public static void main(String[] args) {
		// 
		int arr[] = {1,9,11,-1,34,89};//无序数组
		int index = seqSearch(arr, 11);
		if(index == -1) {
			System.out.println("没有找到。");
		}else {
			System.out.println("找到,下标为:"+index);
		}
	}
	
	/**
	 * 这里实现的线性查找是找到一个满足条件的值,就返回
	 * @param arr
	 * @param value
	 * @return
	 */
	public static int seqSearch(int[] arr,int value) {
		//线性查找是注意对比,发现想通过值,返回下标
		for(int i=0;i<arr.length;i++) {
			if(arr[i] == value) {
				return i;
			}
		}
		return -1;
	}

}

:(2) 二分查找                                                                                        

package com.atguigu.search;

import java.util.ArrayList;
import java.util.List;

//二分查找,使用二分查找的前提是 该数组有序
public class BinarySearch {

	public static void main(String[] args) {
//		int arr[] = {1,8,10,89,1000,1000,1000,1234};
		int[] arr = new int[100];
		for(int i=0;i < 100;i++) {
			arr[i] = i+1;
		}
//		int resultIndex = binarySearch(arr, 0, arr.length-1, 1000);
//		System.out.println("resultIndex: "+resultIndex);
		List resultIndexList = binarySearch2(arr, 0, arr.length-1, 1);
		System.out.println("resultIndexList: "+resultIndexList);
		
	}
	
	//二分查找算法
	/**
	 * @param arr 数组
	 * @param left 左边的索引
	 * @param right 右边的索引
	 * @param findval 要查找的值
	 * @return 找到就返回下标,没有则返回 -1 
	 */
	public static int binarySearch(int[] arr,int left,int right,int findval) {
		//当left > right ,说明递归整个数组,没有找到
		if(left > right) {
			return-1;
		}
		int mid = (left + right)/2;//中间索引
		int midVal = arr[mid];
		if(findval > midVal) {//右递归
			return binarySearch(arr, mid + 1, right, findval);
		}else if(findval < midVal) {//左递归
			return binarySearch(arr, left, mid - 1, findval);
		}else {
			return mid;
		}
	}

	/* 当一个有序数组,含有多个相同值,如何找到所有的下标
	 * {1,8,10,89,1000,1000,1234} 中的 1000
	 * 
	 * 思路:
	 * 1.找到mid 索引值,不要马上返回
	 * 2.向mid 索引值的左边扫描,将所有满足 1000 ,的元素的下标,加入到集合ArrayList
	 * 3.向mid 索引值的右边扫描,将所有满足 1000 ,的元素的下标,加入到集合ArrayList
	 * 4.将ArrayList 返回
	 * */
	public static List<Integer> binarySearch2(int[] arr,int left,int right,int findval) {
		System.out.println("查找次数+1");
		//当left > right ,说明递归整个数组,没有找到
		if(left > right) {
			return new ArrayList<Integer>();
		}
		int mid = (left + right)/2;//中间索引
		int midVal = arr[mid];
		if(findval > midVal) {//右递归
			return binarySearch2(arr, mid + 1, right, findval);
		}else if(findval < midVal) {//左递归
			return binarySearch2(arr, left, mid - 1, findval);
		}else {
			//下标 放入集合
			List<Integer> resIndexList =  new ArrayList<Integer>();
			int temp = mid - 1;
			//左边扫描
			while(true) {
				if(temp < 0 || arr[temp] != findval) {
					break;
				}
				resIndexList.add(temp);
				temp -= 1;//temp 左移
			}
			resIndexList.add(mid);//左边扫描放入后,mid 下标放入
			
			//右边扫描
			temp = mid + 1;
			while(true) {
				if(temp > arr.length-1 || arr[temp] != findval) {
					break;
				}
				resIndexList.add(temp);
				temp += 1;//temp 右移
			}
			return resIndexList;
		}
	}
	
	
	
	
	
	
}

                                                                   

:(3) 插值查找                                                                                        

  • 二分查找算法的优化 ,关键 :自适应 mid.

package com.atguigu.search;
//插值查找算法
import java.util.Arrays;

public class InsertValueSearch {

	public static void main(String[] args) {
		int[] arr = new int[100];
		for(int i=0;i < 100;i++) {
			arr[i] = i+1;
		}
//		int arr[] = {1,8,10,89,1000,1000,1000,1234};

		int resIndex = insertValueSearch(arr, 0, arr.length-1, 1);
		System.out.println("resIndex: "+resIndex);

		int resIndex2 = binarySearch(arr, 0, arr.length-1, 1);
		System.out.println("resIndex2: "+resIndex2);

	}

	// 插值查找算法 ,要求:数组是有序的
	public static int insertValueSearch(int[] arr,int left,int right,int findval) {
		System.out.println("插值查找被调用~~~");
		if(left > right || findval<arr[0] || findval>arr[arr.length-1] ) {
			return -1;
		}
		//求出mid, 自适应的mid
		int mid = left + (right-left)*(findval-arr[left])/(arr[right]-arr[left]);
		int midVal = arr[mid];
		if(findval > midVal) {//右递归
			return insertValueSearch(arr, mid + 1, right, findval);
		}else if(findval < midVal) {//左递归
			return insertValueSearch(arr, left, mid - 1, findval);
		}else {
			return mid;
		}
	}
	//二分查找
	public static int binarySearch(int[] arr,int left,int right,int findval) {
		System.out.println("二分查找被调用~~~");
		//当left > right ,说明递归整个数组,没有找到
		if(left > right) {
			return-1;
		}
		int mid = (left + right)/2;//中间索引
		int midVal = arr[mid];
		if(findval > midVal) {//右递归
			return binarySearch(arr, mid + 1, right, findval);
		}else if(findval < midVal) {//左递归
			return binarySearch(arr, left, mid - 1, findval);
		}else {
			return mid;
		}
	}
	
}

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值