您的位置:首页 > 理论基础

算法之“二分法查找”初始认识

2013-08-04 09:41 281 查看


作为一个数学专业的学生,对于二分法应该说比较熟悉了,但是要翻译成C#语言还是有一定的难度,因为仅仅明白数学思想是远远不够的,我们必须得加上计算机相关知识才能完成。下来,我先大概的说说“二分法查找”这件事。
“二分法查找”是计算机中的一种查找方法,前提条件是要查找的集合必须是有序的,或是升序排列或是降序排列都可以;目的是,找到被查找目标的在集合中的位;核心思想是每次查找都排除一半的数。这种查找方法比较快,次数成对数函数减少。具体查找方法如下(假设集合按升序排列):
(1)找出原集合最中间位置上的数,并与目标进行比较进(2);
(2)如果中间数比目标大,则排除中间数以前的数(含中间数)缩减查找范围并进入(4);
(3)如果中间数比目标小,则排除中间数以后的数(含中间数)缩减查找范围并进入(4);
(4)继续(1)的步骤,知道找到目标位置。
一般是这种情况,当然还有比较特殊的时候,比如要查找的目标不在集合中,我们另当别论。
下面给出一个调用递归函数进行二分查找的例子:

static void Main(string[] args)
{
//准备一个至少两个元素的有序数组
int[] ary = new int[] { 1, 3, 5, 7, 11, 25, 30 };
//定义一个要查找的目标并初始化
int target = 8;
//调用递归函数Find
int result = Find(ary, target, 0, ary.Length - 1);
//向屏幕输出结果
Console.WriteLine(result);
}
//利用快捷方式“alt+shift+F10”生成要调用的函数,并且传入形式参数如数组,
//查找目标,初始索引和结束索引
private static int Find(int[] ary, int target, int startindex, int endindex)
{
//定义中值索引并初始化为初始索引和结束索引的均值
int middleindex = (startindex + endindex) / 2;
//定义中值并初始化为数组中索引为中值索引位置的上数
int middle = ary[middleindex];
//判断初始索引与结束索引的大小,若初始索引大于结束索引则说明数组中没有要查找的数
//并且返回-1
if (startindex > endindex)
{
return -1;
}
//判断目标与中值的大小,如果目标等于中值,并得到索引为middleindex位置上的数后返回该索引
if (target == middle)
{
middle = ary[middleindex];
return middleindex;
}
//如果目标小于中值,那么一定意味着中值(包含中值)以后的数都比目标大,故缩小查找范围
//将结束索引变为种植索引-1
if (target < middle)
{
endindex = middleindex - 1;
}
//如果目标大于中值,那么一定意味着中值(包含中值)以前的数都比目标大,故缩小查找范围
//将初始索引变为种植索引+1
if (target > middle)
{
startindex = middleindex + 1;
}
//返回新的查找范围继续查找
return Find(ary, target, startindex, endindex);
}
运行结果如下:


再给出一个直接用循环语句来完成的查找:
class Program
{
static void Main(string[] args)
{
int[] ary = new int[] {1,3,4,6,11,20,24};
int result = Find(ary,6);
Console.WriteLine(result);
}
private static int Find(int []ary,int target)
{
int startIndex = 0;
int endIndex = ary.Length - 1;
int targetIndex = -1;
//判断初始索引与结束索引的大小,若初始索引大于结束索引则说明数组中没有要查找的数
//并且返回-1
while (true)
{
//求中值索引
int MiddleIndex = (startIndex + endIndex) / 2;
//定义中值并初始化为数组中索引为中值索引位置的上数
int Middle = ary[MiddleIndex];
//如果初始索引大于等于结束索引就立刻结束程序
if (startIndex > endIndex)
{
break;
}
//判断目标与中值的大小,如果目标等于中值,并得到索引为middleindex位置上的数后返回该索引
if (target == Middle)
{
targetIndex = MiddleIndex;

break;
}
//如果目标小于中值,那么一定意味着中值(包含中值)以后的数都比目标大,故缩小查找范围
//将结束索引变为种植索引-1
else if (target < Middle)
{
endIndex = MiddleIndex - 1;
}
//如果目标大于中值,那么一定意味着中值(包含中值)以前的数都比目标大,故缩小查找范围
//将初始索引变为种植索引+1
else
{
startIndex = MiddleIndex + 1;
}
}
return targetIndex;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息