二分查找又称折半查找,优点是比较次数少,查找速度快,平均性能好;其缺点是要求待查表为有序表,且插入删除困难。因此,折半查找方法适用于不经常变动而查找频繁的有序列表。
package cn.edu.nwsuaf.cie.qhs.algorithm;
import java.util.Arrays;
/**
*
* @author 静寞小森(沧海森林)
* 折半查找(二分查找)在以下情况下使用:
* 1.一般情况下,如果一个数组是有序的,那么为了提高查找速度,可以使用折半查找,时间复杂度可以从普通的O(N)降到O(log N);
* 2.还有就是,如果一个数组并不是有序的,但是将在程序中大量用到查找,可以先进行排序,然后再使用折半查找,进行多次查找,效率也会比较高。
*/
public class BinarySearch{
private final static int NOT_FOUND = -1;
//使用泛型编程,此方法针对对象编程,所以不可以使用java的八种基本类型,否则报错,可以使用其对应的包装类,如int对应Integer等。
public static> int binarySearch(AnyType[] array, AnyType target){
int low = 0, high = array.length - 1;
while(low <= high){
int mid = ( low + high ) >> 1;//相当于(low+high)/2 但是要比后边的效率高
if(array[mid].compareTo(target) < 0)
low = mid + 1;
else if(array[mid].compareTo(target) > 0)
high = mid - 1;
else
return mid;
}
return NOT_FOUND;
}
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
//已经有序的,可以使用下面的方式,进行二分查找。
Integer[] intArray = new Integer[]{2,5,8,15,24,32,45,255,452};
Double[] doubleArray = new Double[]{2.0,5.0,8.0,15.0,24.0,32.0,45.0,255.0,452.0};
String[] stringArray = new String[]{"ab","bc","cd","de","ef","fg","gh","hi","ij"};
Student[] studentArray = new Student[]{new Student(1,"q"),new Student(2,"i"),new Student(3,"u"),
new Student(4,"h"),new Student(5,"a"),new Student(6,"i"),new Student(7,"s"),new Student(8,"e"),new Student(9,"n")};
int targetPos = BinarySearch.binarySearch(intArray, 255);
System.out.println("查找Integer数组中的数的位置为:"+targetPos);
targetPos = BinarySearch.binarySearch(doubleArray, 255.0);
System.out.println("查找Double数组中的数的位置为:"+targetPos);
//查看String的java源码其中String实现了Comparable接口,所以这里可以使用
//这是java源码中的一段代码:public final class String implements java.io.Serializable, Comparable, CharSequence
targetPos = BinarySearch.binarySearch(stringArray, "hi");
System.out.println("查找Double数组中的数的位置为:"+targetPos);
targetPos = BinarySearch.binarySearch(studentArray, new Student(8));
System.out.println("查找Student数组中的对象的内容为:"+studentArray[targetPos].toString());
//如果,还没有排序,即为乱序的话,可以通过java的Array的库方法sort进行排序。
Integer[] intArray2 = new Integer[]{2,5,24,45,32,452,255,8,15};
Arrays.sort(intArray2);
targetPos = BinarySearch.binarySearch(intArray2, 255);
System.out.println("先通过排序,然后查找Integer数组中的数的位置为:"+targetPos);
}
}
//为了说明问题,这里我们自定义一个类,但是为了好说明,这里我们使用了这种方式。
class Student implements Comparable{
int stuNo;
String stuName;
public Student(){}
public Student(int stuNo,String stuName) {
// TODO Auto-generated method stub
this.stuNo = stuNo;
this.stuName = stuName;
}
public Student(int stuNo){
this.stuNo = stuNo;
}
@Override
public int compareTo(Student student) {
// TODO Auto-generated method stub
int thisNo = this.stuNo;
int anotherNo = student.stuNo;
return (thisNo < anotherNo ? -1 : (thisNo == anotherNo ? 0 : 1));
}
public String toString(){
return "这是一个Student类,其中学号为:"+stuNo+";姓名为:"+stuName;
}
}