[算法天天见](四)二分查找

一、概述

二分查找法查找是建立在数组有序的基础上的,每次查找都会将查找的范围缩小一半,所以复杂度是 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;
		}

猜你喜欢

转载自blog.csdn.net/kakaxi2222/article/details/83624718
今日推荐