四种查找算法(Java)

一、线性查找算法【easy】

package search;

public class SeqSearch
{
	public static void main(String[] args)
	{
		int[] arr = {1, 3, 9, 8, 7, -1, 2};  //没有顺序的数组
		int index = seqSearch(arr, 7);
		if(index == -1)
			System.out.println("没有找到值 " + 7);
		else
			System.out.println("值为 " + 7 + "的下标为 " + 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.1思路

 

2.2代码实现

package search;

public class BinarySearch
{
	//注意:使用二分查找的前提是该数组是有序的
	public static void main(String[] args)
	{
		int[] arr = {1, 8, 10, 89, 1000, 1024, 2048};
		
		int findVal = 1024;
		
		int resIndex = binarySearch(arr, findVal, 0, arr.length - 1);
		if(resIndex == -1)
		{
			System.out.println("数组中未找到值 : " + findVal);
		}
		else
			System.out.println("resIndex: " + resIndex);
		
	}

	/**
	 * 二分查找算法
	 * @param arr 数组
	 * @param findVal 要查找的值
	 * @param l 左边的索引
	 * @param r 右边的索引
	 * @return 如果找到就返回下标,如果没有找到,就返回-1
	 */
	public static int binarySearch(int[] arr, int findVal, int l, int r)
	{
		if(l > r)
			return -1;
		int mid = (l + r) / 2;
		
		if(findVal > arr[mid])
			return binarySearch(arr, findVal, mid + 1, r);
		else
			if(findVal < arr[mid])
			return binarySearch(arr, findVal, l, mid - 1);
		else
		return mid;
	}
}

2.3二分查找算法功能完善 

当一个有序数组中,有多个相同的数值时,如何将所有的数值都查到。

如:[1, 9 , 88, 582, 1000, 1000, 1000, 99999]

思路:

1、在找到mid索引值,不要马上返回

2、向mid索引值的左边扫描,将所有满足1000的元素的下标,加入到集合ArrayList

3、 向mid索引值的右边扫描,将所有满足1000的元素的下标,加入到集合ArrayList

4、将ArrayList返回

package 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, 1024, 2048};
		
		int findVal = 1000;
		
		List<Integer> resIndex = binarySearch2(arr, findVal, 0, arr.length - 1);
		if(resIndex == null)
		{
			System.out.println("数组中未找到值 : " + findVal);
		}
		else
			System.out.println("resIndex: " + resIndex);
		
	}
	
	public static List<Integer> binarySearch2(int[] arr, int findVal, int l, int r)
	{
		if(l > r)
			return new ArrayList<Integer>();
		int mid = (l + r) / 2;
		
		if(findVal > arr[mid])
			return binarySearch2(arr, findVal, mid + 1, r);
		else
			if(findVal < arr[mid])
			return binarySearch2(arr, findVal, l, mid - 1);
		else
		{
			/**
			 * 1、在找到mid索引值,不要马上返回
			 * 2、向mid索引值的左边扫描,将所有满足1000的元素的下标,加入到集合ArrayList
			 * 3、 向mid索引值的右边扫描,将所有满足1000的元素的下标,加入到集合ArrayList
			 * 4、将ArrayList返回
			 */
			List<Integer> resIndexlist = new ArrayList<Integer>();
			//向mid索引的左边扫描,将所有满足1000的元素的下标,加入到集合ArrayList中
			int temp = mid - 1;
			while(true)
			{
				if(temp < 0 || arr[temp] != findVal)
				{
					break;
				}
				//否则,将temp放入到resIndexlist
				resIndexlist.add(temp);
				temp = temp - 1; //左移
			}
			resIndexlist.add(mid);
			//向mid索引的右边扫描,将所有满足1000的元素的下标,加入到集合ArrayList中
			temp = mid + 1;
			while(true)
			{
				if(temp > arr.length-1 || arr[temp] != findVal)
				{
					break;
				}
				//否则,将temp放入到resIndexlist
				resIndexlist.add(temp);
				temp = temp + 1; //左移
			}
			return resIndexlist;
		}
	}
}

三、插值查找算法 

3.1工作原理 

 

3.2代码实现

package 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;
		}
		System.out.println(Arrays.toString(arr));
		
		int index = insertValueSearch(arr, 0, arr.length - 1, 1);
		System.out.println("index: " + index);
	}
	
	//编写插值算法
	//插值查找算法,也是要求数组是有序的
	/**
	 * 
	 * @param arr
	 * @param left
	 * @param right
	 * @param findVal
	 * @return 如果找到,就返回相应的下标,如果没有找到,返回 -1
	 */
	public static int insertValueSearch(int[] arr, int left, int right, int findVal)
	{
		//注意:findVal < arr[0] 和 findVal > arr[arr.length - 1]必须有,否则得到的mid可能越界
		if(left > right || findVal < arr[0] || findVal > arr[arr.length - 1])
		{
			return -1;
		}
		
		//求出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;
		}
	}

}

 

 

四、斐波那契数列 

猜你喜欢

转载自blog.csdn.net/gjs935219/article/details/105765690