对于一个有序数组,我们通常采用二分查找的方式来定位某一元素,请编写二分查找的算法,在数组中查找指定元素。
给定一个整数数组A及它的大小n,同时给定要查找的元素val,请返回它在数组中的位置(从0开始),若不存在该元素,返回-1。若该元素出现多次,请返回第一次出现的位置。
测试样例:
[1,3,5,7,9],5,3
返回:1
import java.util.*;
public class BinarySearch {
public int getPos(int[] A, int n, int val) {
// write code here
int low=0,higth=n,res=-1;
while (low != higth){
int mid = (low + higth)/2;
if (A[mid] > val){
higth = mid;
}else if (A[mid] < val){
low = mid;
if (res != -1){
break;
}
}else {
res = mid;
higth = mid;
}
}
return res;
}
} import java.util.*;
public class BinarySearch {
public int getPos(int[] A, int n, int val) {
int left = 0;
int right = n - 1;
int mid = 0;
while(left <= right){
mid = (left + right) / 2;
if(A[mid] > val){
right = mid - 1;
}else if(A[mid] < val){
left = mid + 1;
}else{
while(mid >= 0){
if(A[mid] != val){
return mid + 1;
}else{
mid --;
}
}
return mid + 1;
}
}
return -1;
}
} import java.util.*;
public class BinarySearch {
public int getPos(int[] A, int n, int val) {
int first = 0, last = n,mid;//n
while(first < last){
if(A[0]==val)
//经过观察,这种写法仅在第一个位置是val时输出错误,所以单独处理
return 0;
mid = first + (last-first)/2;
if(A[mid]<val){
first = mid + 1;
}
else if(A[mid]==val){
return mid;
}
else
last = mid;
}
return -1;
}
} import java.util.*;
public class BinarySearch
{
public int getPos(int[] A, int n, int val)
{
return getIndex(A,0,A.length-1,val);
}
private int getIndex(int [] arr,int left,int right,int target)
{
if(left>right)//说明递归查找完整个数组,还没有找到
{
return -1;
}
int midIndex=(left+right)/2;
int midValue=arr[midIndex];
if(target>midValue)//如果你要找的数比中间的数大,就去右边找
{
return getIndex(arr,midIndex+1,right,target);
}
else if(target<midValue)//如果你要找的数比中间的数小,就去左边找
{
return getIndex(arr,left,midIndex-1,target);
}
else
{
while(midIndex>left&&arr[midIndex-1]==target)
{
midIndex=midIndex-1;
return midIndex;
}
return midIndex;
}
}
}
找到第一个比val小的数,res++就是第一个val出现的下标了,如果不是则证明val不存在
public int getPos(int[] A, int n, int val) {
int left=0;
int right=n-1;
int m;
int res=-1;
while(left<=right){
m=(left+right)/2;
if(A[m]<val){
res=m;
left=m+1;
}else{
right=m-1;
}
}
res++;
if(res>=n||A[res]!=val) return -1;
else return res;
}
import java.util.*;
public class BinarySearch {
public int getPos(int[] a, int n, int value) {
// write code here
int middle;
int left = 0;
int right = n - 1;
while (left <= right) {
middle = (left + right) / 2;
if (a[middle] > value) {
right = middle - 1;
}
else if (a[middle] < value) {
left = middle + 1;
}
else {
//return middle;
//如果出现多次value,
//遍历一下数组a获得第一个value的数组下标返回即可
for (int i = 0; i < n; i++) {
if (a[i] == value) {
return i;
}
}
}
}
return -1;
}
}
import java.util.*;
public class BinarySearch {
public int getPos(int[] A, int n, int val) {
// write code here
int start=0;
int end=A.length;
int mid=(start+end)/2;
while(start<=end) {
if(A[mid]==val) {
return mid;
}
if(A[mid]<val) {
start=mid+1;
}else if(A[mid]>val){
end=mid-1;
}
mid=(start+end)/2;
}
return -1;
}
}
//指定值第一次出现
public class BinarySearch {
public int getPos(int[] A, int n, int val) {
int left = 0;
int right = n-1;
int center =(left+right)/2;
while(left<right){
if(A[center]>=val){//1、为什么这里取等放入
right = center;
}
else{//2、为什么不在这边放置等于的情况
left = center+1;
}
//3、center赋值位置放这和放循环开始处什么区别
//4、当取最后一次出现的位置,我这里一般改成(left+right+1)/2
//5、当取最后一次出现的位置,除了4处修改,对于1、2取等和right left赋值都有些许变化
center = (left+right)/2;
}
return A[center]==val?center:-1;
}
}
public class BinarySearch { public int getPos(int[] A, int n, int val) { // write code here
int start=0;
int end=A.length-1;
while(start+1<end){ int mid = (start+end)/2;
if(val==A[mid]){ end=mid;
}else if(val>A[mid]){ start=mid;
}else if(val<A[mid]){ end=mid;
}
}
if(A[start]==val){ return start;
}
if(A[end]==val){ return end;
}
return -1;
}
}
// Java 典型的 二分查找(递归做法)
public int getPos(int[] A, int n, int val) {
if (A == null || A.length <= 0)
return -1;
return getPos(A, 0, A.length-1, val);
}
private int getPos(int[] A, int low, int high, int val) {
if (low > high)
return -1;
int mid = (low + high) >> 1;
if (A[ mid ] == val && (mid == low || A[ mid - 1 ] != val))
return mid;
else if (A[ mid ] >= val)
return getPos(A, low, mid - 1, val);
else
return getPos(A, mid + 1, high, val);
}
// Java非递归 的二分查找
public int getPos(int[] A, int n, int val) {
if (A == null || A.length <= 0)
return -1;
int mid, low = 0, high = A.length - 1;
while (low <= high) {
mid = (low + high) >> 1;
if (A[ mid ] == val && (mid == low || A[ mid-1 ] != val))
return mid;
else if (A[ mid ] >= val)
high = mid - 1;
else low = mid + 1;
}
return -1;
} 注意这里当找到时不能直接返回,而是用一个标志位标志,然后再重新遍历一次数组找到第一次出现 的位置。
public class BinarySearch {
public int getPos(int[] A, int n, int val) {
if(n<=0)
return -1;
int res=getk(0,n-1,A,val);
return res;
}
public int getk(int start ,int end ,int[] a,int val)
{
int mid=(start+end)/2;
int num=a[mid];
if(num>val)
{
end=mid;
return getk(0,mid,a,val);
}
else if(num<val)
{
start=mid+1;
return getk(mid+1,end,a,val);
}
else
{
if(mid==0)
return mid;
for(int i=1;i<=mid;i++)
{
if(a[mid-i]==val)
return (mid-i);
else
return mid;
}
}
return -1;
}
}
package HaoWeiLai;
import java.util.*;
public class BinarySearch {
public int getPos(int[] A, int n, int val) {
int lo=0, hi=n;
int target =search(A, lo, hi, val);
if(target==n)
return -1;
return A[target] == val? target:-1;
}
public static int search(int[] A, int lo, int hi, int val){
int mid;
while(hi-lo>0){
mid = (lo+hi)>>1;
if(A[mid] < val){
lo = mid+1;
}else if ( val <=A[mid]){
hi = mid;
}
}
return lo;
}
}
import java.util.*;
public class BinarySearch {
public int getPos(int[] A, int n, int val) {
// write code here
int begin = 0;
int end = n-1;
int mid = (begin+end)/2;
while(begin<=end){
if(val>A[mid]){
begin = mid+1;
}else if (val == A[mid]){
if(mid>=1&&val==A[mid-1]){
end = mid-1;
}else {
return mid;
}
}else {
end = mid-1;
}
mid = (begin+end)/2;
}
return -1;
}
}
package com.ginto.practise010;
import java.util.Scanner;
public class BinarySearch {
public static void main(String[] args) {
Scanner scanner=new Scanner(System.in);
int[] A;
int n;
int val;
System.out.print("输入数组大小:");
n=scanner.nextInt();
A=new int[n];
System.out.print("输入数组元素:");
for(int i=0;i<n;i++){
A[i]=scanner.nextInt();
}
System.out.print("输入需要查找的元素:");
val=scanner.nextInt();
BinarySearch bs=new BinarySearch();
System.out.println(bs.getPos(A, n, val));
}
public int getPos(int[] A, int n, int val) {
int low=0;
int middle;
int high=A.length-1;
while(low<=high){
middle=low+((high-low)>>1);
if(A[middle]==val&&A[low]==A[middle]){
return low;
}else if(A[middle]==val){
return middle;
}else if(A[middle]>val){
high=middle-1;
}else{
low=middle+1;
}
}
return -1;
}
}
只考虑升序的解法如下,降序数组依次类推即可。
import java.util.*;
public class BinarySearch {
public int getPos(int[] A, int n, int val) {
// write code here
int low = 0;
int high = n;
int mid = 0;
while(low < high){
mid = (low + high)/2;
if(val <= A[mid]){
high = mid;
}else if(val > A[mid]){
low = mid+1;
}
}
if(val == A[low]){
return low;
}else{
return -1;
}
}
}