二分查找的理解与实现

二分查找的理解
对于二分查找,我们首先得明白以下几点:

  • 二分查找是一种查找算法
  • 被查找的序列是有序的
  • 如果查找的元素在集合中则返回元素的位置,否则返回NULL

下面我们举例说明二分查找的思想:
小明和小红玩游戏,小明手握一张写有数字3的纸片,让小红猜这个纸片上的数字,小明不断提示。这就类似于给定一个数组,里面有序地放着100个元素,分别是1~100,要求小红以二分查找的方式找到小明手里的数字是多少?
针对上面的问题,我们可以一个一个地猜,但是这种方式效率实在是太低。所以我们试试二分查找:

  1. 小红猜50-----------小明提示“大了”
  2. 小红猜25-----------小明提示“大了”
  3. 小红猜13-----------小明提示“大了”
  4. 小红猜7-------------小明提示“大了”
  5. 小红猜4-------------小明提示“大了”
  6. 小红猜2-------------小明提示“小了”
  7. 小红猜3-------------小明提示“回答正确”

这就是二分查找的整个过程,使用二分查找时,每次都排除一半的数字,逐渐地缩小查找范围,直到找到为止。

二分查找的完整实现

#include <stdio.h>
#include <stdlib.h>
#include <Windows.h>
 
#define MAXSIZE 10
#define NotFound 0

typedef int ElementType; 
typedef int Position;
typedef struct LNode *List;

struct LNode {
    ElementType Data[MAXSIZE];
    Position last; 
};
 
List ReadInput(); 
Position BinarySearch( List L, ElementType X );
 
int main()
{
    List L;
    ElementType X;
    Position P;
 
    L = ReadInput();
    scanf("%d", &X);
    P = BinarySearch( L, X );
    printf("%d\n", P);
 
	system("pause");
    return 0;
}
 
/*建立查找序列*/
List ReadInput() 
{    
	int i, n;
	List a;    //创建结构体。
	
	scanf("%d", &n);
	a = (List)malloc(n * sizeof(struct LNode));

	for ( i=1; i<=n; i++ )
	{
		scanf("%d", &(a->Data[i]));    //输入结构体Data的值
	}
	a->last = n;    //结构体成员last赋值
	
	return a;    //返回这个结构体,也就是查找序列。
}
 
/*经典二分查找*/
Position BinarySearch( List L, ElementType X ) {
	Position left, right, mid;
	
	left = 1, right = L->last;   
	while ( left <= right ) {    //这里必须是 <= ,否则“偶数个,正中间找到”会报错
		mid = (left + right) / 2;
		if ( L->Data[mid] == X ) 
			return mid;
		else if ( L->Data[mid] > X ) 
			right = mid - 1;
		else 
			left = mid + 1;
	}		
	return NotFound;
}

总结一下
一定要注意,二分查找针对的是一个有序的集合(排好序的数组)。每一次查找就可以排除一半的元素,也就是将查找范围缩小一半。那么对于一个包含N个元素的集合,整个查找过程比较次数大约为log以2为底的N次方。

发布了12 篇原创文章 · 获赞 7 · 访问量 216

猜你喜欢

转载自blog.csdn.net/weixin_42462651/article/details/105013310
今日推荐