说明:元素必须时有序的,如果是无序的要先进行无序操作
基本思想:也称为折半查找,属于有序查找算法。每次取数组的中间值作为比较对象,如果小于a[mid] 则在数组的右边继续比较,如果大于a[mid] 则在数组的左边继续比较,如果等于a[mid] 则返回mid
时间复杂度:
- 最坏情况下,关键词比较次数为,且期望时间复杂度为O()
注意:折半查找的前提条件是需要有序表顺序存储,对于静态查找表,一次排序后不再变化,折半查找能得到不错的效率。
代码实现(递归和非递归实现):
package Common;
public class Common {
public static boolean less(Comparable a,Comparable b) {
return a.compareTo(b)<0;
}
public static void exch(Comparable[] a,int i,int j) {
Comparable temp=a[i];
a[i]=a[j];
a[j]=temp;
}
}
/* *1.二分查找只能查找顺序存储的数据 数据是有序的 *2.每次取数组的中间值作为比较对象 * 如果小于a[mid] 则在数组的右边继续比较 * 直到找到或者结束 * 如果大于a[mid] 则在数组的左边继续比较 *3.时间复杂度为O(logn) *4.静态表建议使用二分查找 * 若是动态表 不建议使用 * */
public class BinarySearch {
//非递归实现
public static int search(Comparable[] a,Comparable key) {
int low=0;
int high=a.length-1;
while (low<high) {
int mid=(low+high)/2;
if (Common.less(key, a[mid])) {
high=mid-1;
}
else if (Common.less(a[mid], key)) {
low=mid+1;
}
else {
return mid;
}
}
return 0;
}
//递归实现
public static int search(Comparable[] a,int low,int high,Comparable key) {
while (low<high) {
int mid=(low+high)/2;
if (Common.less(key, a[mid])) {
search(a, low, mid-1, key);
}
else if (Common.less(a[mid], key)) {
search(a, mid+1, high, key);
}
else {
return mid;
}
}
return 0;
}
public static void main(String[] args) {
Integer[] a= {1,3,4,5,6,8};
int low=0;
int high=a.length-1;
int i=search(a, 4);
System.out.println("非递归查找位置在"+(i+1));
System.out.println("===============");
int j=search(a, low, high, 4);
System.out.println("递归查找位置在"+(j+1));
}
}