线性查找与二分查找
一:线性查找
一:线性查找介绍:
线性查找不需要待查找的数据是已经排序好的数据,并且先行查找是从第一个数据开始查找,当查到数据的时候就返回数据的下标值。并停止查找
二:代码:
/*
线性查找
*/
public class SeqSearch {
public static void main(String[] args) {
int[] array = {1,5,2,4,3,6};
int i = seqSearch(array, 8);
if (i!=-1){
System.out.println(i);
System.out.println(array[i]);
}else {
System.out.println("没找到");
}
}
public static int seqSearch(int[] array,int value){
//线性查找就是遍历数组,找到数据返回下标值
for (int i = 0; i < array.length; i++) {
if (array[i] == value){
return i;
}
}
return -1;
}
}
二:二分查找
一:二分查找介绍:
二分查找要求待查找的数据是一组已经排序的数据。当进行查找时,会先得到这组数据的中间值,判断与待查找的值的大小,如果比待查找数据小,则证明待查数据在中间值的右边,反之在中间值的左边。
二:二分查找法思路
- 首先确定数组的中间的下标(mid = (left+right)/2)
- 然后让需要查找的数据value与array[mid]进行比较。
- 如果value>array[mid],说明要查找的数据在mid的右边,因此需要递归的向右进行查找。
- 如果value<array[mid],说明要查找的数据在mid的左边,因此需要递归的向左进行查找。
- 如果value = array[mid],说明找到了。返回mid
这时有个问题就是递归什么时候停止??
- 正常在找到数据的时候就会停止递归
- 当要找数据并不在数组中,也需要停止递归,这时要加上判断条件:left>right就退出递归。
三:代码:
public static void main(String[] args) {
int[] array = {1,4,7,9,12,31,};
int i = binarySearch(array, 31, 0, array.length - 1);
System.out.println(i);
}
public static int binarySearch(int[] array,int value,int left,int right){
if (left>right){
return -1;
}
int mid =(left+right)/2;
if (value<array[mid]){
return binarySearch(array,value,left,mid-1);
}else if (value>array[mid]){
return binarySearch(array,value,mid+1,right);
}else {
return mid;
}
}
四:二分查找法不使用递归实现
思路与上面一致,只不过是使用循环代替了递归来实现而已
代码;
package 二分查找法;
public class BinarySearch {
public static void main(String[] args) {
int[] array = {1,4,5,7,9,10};
int i = binarySearch(array, 10);
System.out.println(i);
System.out.println(array[i]);
}
/**
*
* @param array 带查找的数组,默认是升序
* @param target 目标数据
* @return 返回下标值
*/
public static int binarySearch(int[] array,int target){
if (array==null||array.length==0){
return -1;
}
int right = array.length - 1;
int left = 0;
int mid;
while (left<=right){ //证明这时是可以进行查找的
mid = (left + right)/2;
//判断
if (array[mid] == target){
return mid; //找到数据
}else if (array[mid]<target){//在右边
left = mid + 1;
}else if (array[mid]>target){ //在左边
right = mid - 1;
}
}
return -1;
}
}
五:思考题
当有一个数组中有多个重复的值,如何将所有的数据都查到?
思路分析:
- 在找到mid索引值的时候,不要着急的返回值
- 向mid索引值的左边扫描,将所有满足待查找数据的下标值,加入到集合list中。
- 向mid索引值的右边扫面,将所有满足待查找数据的下标值,加入到集合list中。
- 将list集合返回
public static void main(String[] args) {
int[] array = {1,4,7,9,9,9,12,31,31,};
List<Integer> list = binarySearchs(array, 31, 0, array.length - 1);
System.out.println(list);
}
public static List<Integer> binarySearchs(int[] array,int value,int left,int right){
if (left>right){
return null;
}
int mid =(left+right)/2;
if (value<array[mid]){
return binarySearchs(array,value,left,mid-1);
}else if (value>array[mid]){
return binarySearchs(array,value,mid+1,right);
}else {
/*
这时如果找到数据,那么就要在mid的左边或者右边在去寻找,有没有相同的数据
*/
List<Integer> list = new ArrayList<>();
//左边
int temp = mid - 1;
while (true){
if (temp<0||array[temp]!=value){
break;
}
list.add(temp);
temp--;
}
list.add(mid);
temp = mid + 1;
while (true){
if (temp>array.length-1||array[temp]!=value){
break;
}
list.add(temp);
temp++;
}
return list;
}
}