查找Java实现

查找算法

1、线性查找
1)基本原理:
(1)挨个查找,找到返回下标;找不到返回 -1。

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)递归:基本原理
(1)必须是有序序列才能进行二分查找;
(2)比较arr[mid]和value的大小,若arr[mid] > mid,则向左递归查找;若arr[mid] < value,则向右递归查找;
(3)直到 left > right,则返回 -1。

public static int binarySearch(int arr[], int left, int right, int value){
	if(left > right){
		return -1;
	}
	int mid = (left + right) / 2;
	if(arr[mid] > value){
		return binarySearch(arr, left, mid - 1, value);
	}else if(arr[mid] < value){
		return binarySearch(arr, mid + 1, right, value);
	}else{
		return mid;
	}
}

// 找出所有value值
public static ArrayList<Integer> binarySearch1(int arr[], int left, int right, int value){
	if(left > right){
		return new ArrayList<Integer>();
	}
	int mid = (left + right) / 2;
	if(arr[mid] > value){
		return binarySearch1(arr, left, mid - 1, value)
	}else if(arr[mid] < value){
		return binarySearch(arr, mid + 1, right, value);
	}else{
		ArrayList<Integer> indexArray = new ArrayList<Integer>();
		int tmp = mid - 1;
		while(true){
			if(arr[mid] != value || tmp < 0){
				break;
			}
			indexArray.add(tmp);
			tmp--;
		}
		indexArray.add(mid);
		tmp = mid + 1;
		while(true){
			if(arr[tmp] != value || tmp > arr.length - 1){
				break;
			}
			indexArray.add(tmp);
			tmp++;
		}
		return indexArray;
	}
}

2)非递归

3、插值查找
1)基本原理
(1)优化了二分查找的mid值,即为 mid = left + (right - left) * (value - arr[left]) / (arr[right] - arr[left]);
(2)插值查找时候要注意越界条件,即left > right || value > arr[arr.length - 1] || value < arr[0];

public static int insertValueSearch(int arr[], int left, int right, int value){
	if(left > right || value > arr[arr.length - 1] || value < arr[0]){
		return -1;
	}
	int mid = left + (right - left) * (value - arr[left]) / (arr[right] - arr[left]);
	if(value < arr[mid]){
		return inserValueSearch(arr, left, mid - 1, value);
	}else if(value > arr[mid]){
		return insetValueSearch(arr, mid + 1, right, value);
	}else{
		return mid;
	}
}

4、斐波那契查找
1)基本原理
(1)设斐波那契数列 f(k)(斐波那契数列为{1,1,2,3,5,8,13,……}),把待查找的有序表长度补长为 f(k),补的为最后一个元素的数值;如:把{0,3,5,7,9,11}补长为长度为8(8为斐波那契数列的元素)的有序表{0,3,5,7,9,11,11,11};
(2)把补长后的长度为 f(k) 的有序表(其左右边界下标为 low,high)拆分成 f(k - 1)和 f(k - 2)长度的两段,则中间位置的下标 mid = low + f(k - 1) - 1;
(3)如果查找值value < 中间值,则向左边即长度为 f(k - 1) 的那段查找,把长度为 f(k-1) 的有序表(其左右边界下标为 low,mid - 1)拆分成 f(k - 2)和 f(k - 3)长度的两段,则此时新的中间位置的下标 mid = low + f(k - 2) - 1;
(4)如果查找值value > 中间值,则向右边即长度为 f(k - 2) 的那段查找,把长度为 f(k-2) 的有序表(其左右边界下标为 mid + 1,high)拆分成 f(k - 3)和 f(k - 4)长度的两段,则此时新的中间位置的下标 mid = low(= mid + 1的新low) + f(k - 3) - 1;
(5)如果查找值value = 中间值,则返回下标,注意:比较mid与原始有序表的右边界,若大于右边界,则说明找到的是补长的那部分元素,即为原有序表最后一个位置的元素。

public static int[] fib(int maxSize){
	int f[] = new int[maxSize];
	f[0] = 1;
	f[1] = 1;
	for(int i = 2; i < maxSize; i++){
		f[i] = f[i - 1] + f[i - 2];
	}
	return f;
}
public static int fibSearch(int arr[], int value){
	int low = 0;
	int high = arr.length - 1;
	int k = 0;
	int f[] = fib(20);
	while(high > f[k] - 1){
		k++;
	}
	int tmp[] = Arrays.copyOf(arr, f[k]);
	for(int i = high + 1; i < f[k]; i++){
		tmp[i] = tmp[high];
	}
	while(low <= high){
		mid = low + f[k - 1] - 1;
		if(value < tmp[mid]){
			high = mid - 1;
			k--;
		}else if(value > tmp[mid]){
			low = mid + 1;
			k -= 2;
		}else{
			if(mid <= high){
				return mid;
			}else{
				return high;
			}
		}
	}
	return -1;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值