折半查找(二分查找)Java实现

二分查找又称折半查找,优点是比较次数少,查找速度快,平均性能好;其缺点是要求待查表为有序表,且插入删除困难。因此,折半查找方法适用于不经常变动而查找频繁的有序列表。

package cn.edu.nwsuaf.cie.qhs.algorithm;

import java.util.Arrays;

/**
 * 
 * @author 静寞小森(沧海森林)
 * 折半查找(二分查找)在以下情况下使用:
 * 1.一般情况下,如果一个数组是有序的,那么为了提高查找速度,可以使用折半查找,时间复杂度可以从普通的O(N)降到O(log N);
 * 2.还有就是,如果一个数组并不是有序的,但是将在程序中大量用到查找,可以先进行排序,然后再使用折半查找,进行多次查找,效率也会比较高。
 */
public class BinarySearch<AnyType>{

	private final static int NOT_FOUND = -1;
	//使用泛型编程,此方法针对对象编程,所以不可以使用java的八种基本类型,否则报错,可以使用其对应的包装类,如int对应Integer等。
	public static<AnyType extends Comparable<? super AnyType>> 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<String>, 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<Student>{

	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;
	}
}

【运行结果截图】



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值