二分查找
一、概述
二分查找法查找是建立在数组有序的基础上的,每次查找都会将查找的范围缩小一半,所以复杂度是 O(logn)。如何每次缩小一半呢,无非是加几个标记:
low = 当前检查范围的最小值
mid = 当前正检测的值
high = 当前检查范围的最大值
算法要注意的一点是,要考虑数组中有重复元素的情况!
二、算法
1. 查找第一个值等于给定值的元素
public function findFirstValueInArray(s:Array, value:int):int
{
var low:int = 0;
var height:int = s.length - 1;
var mid:int;
while(low <= height)
{
mid = Math.floor((low + height) / 2);
if(s[mid] < value)
{
low = mid + 1;
}else if(s[mid] > value)
{
height = mid - 1;
}else
{
if(mid == 0 || s[mid - 1] != value)
{
return mid;
}else
{
height = mid - 1;
}
}
}
return -1;
}
2. 查找最后一个值等于给定值的元素
public function findLastValueInArray(s:Array, value:int):int
{
var low:int = 0;
var height:int = s.length - 1;
var mid:int;
while(low <= height)
{
mid = Math.floor((low + height) / 2);
if(s[mid] < value)
{
low = mid + 1;
}else if(s[mid] > value)
{
height = mid - 1;
}else
{
if(mid == s.length - 1 || s[mid + 1] != value)
{
return mid;
}else
{
low = mid + 1;
}
}
}
return -1;
}
3. 查找第一个大于等于给定值的元素
public function findGreatEqualValueInArray(s:Array, value:Number):int
{
var low:int = 0;
var high:int = s.length - 1;
var mid:int;
var max:int = -1;
while(low <= high)
{
mid = Math.floor((low + high) / 2);
if(s[mid] < value)//在大区里面找
{
low = mid + 1;
//high不变
}else if(s[mid] > value)//在小区里面找
{
max = mid;
high = mid - 1; //因为我要找的就是比它大的值,所以不用 -1
//low 不变
}else
{
//假如找到等同的值
if(mid == 0 || s[mid - 1] != value)
{
return mid;
}else//如果它之前还有相同的值
{
high = mid - 1;
}
}
}
return max;
}
4. 查找最后一个小于等于给定值的元素
public function findLessEqualValueInArray(s:Array, value:int):int
{
var low:int = 0;
var high:int = s.length - 1;
var mid:int;
var min:int = -1;
while(low <= high)
{
mid = Math.floor((low + high) / 2);
if(s[mid] < value)//在大区里面找
{
min = mid;
low = mid + 1;
//high不变
}else if(s[mid] > value)//在小区里面找
{
high = mid - 1; //因为我要找的就是比它大的值,所以不用 -1
//low 不变
}else
{
//假如找到等同的值
if(mid == s.length - 1 || s[mid + 1] != value)
{
return mid;
}else//如果它之前还有相同的值
{
low = mid + 1;
}
}
}
return min;
}