九种查找算法-二分查找(折半查找)

本文介绍了一种高效的查找算法——二分查找,详细解释了其工作原理及实现过程,并提供了具体的代码示例。适用于已排序的静态查找表。

算法思路

  1. 确定查找范围low=0,high=N-1,计算中项mid=(low+high)/2。

  2. 若mid==x或low>=high,则结束查找;否则,向下继续。

  3. 若amid<x,说明待查找的元素值只可能在比中项元素大的范围内,则把mid+1的值赋给low,并重新计算mid,转去执行步骤2;若mid>x,说明待查找的元素值只可能在比中项元素小的范围内,则把mid-1的值赋给higt,并重新计算mid,转去执行步骤2。

说明

  • 查找元素必须是有序的,如果是无序的则要先进行排序操作。

  • 在做查找的过程中,如果 low 指针和 high 指针的中间位置在计算时位于两个关键字中间,即求得 mid 的位置不是整数,需要统一做取整操作。

折半查找的前提条件是需要有序表顺序存储,对于静态查找表,一次排序后不再变化,折半查找能得到不错的效率。但对于需要频繁执行插入或删除操作的数据集来说,维护有序的排序会带来不小的工作量,那就不建议使用。

                         ——《大话数据结构》

代码

#include <stdio.h>
#include <stdlib.h>
#define keyType int
typedef struct
{
	keyType key;//查找表中每个数据元素的值
}ElemType;

typedef struct
{
	ElemType *elem;//存放查找表中数据元素的数组
	int length;//记录查找表中数据的总数量
}SSTable;

//创建查询数据
void Create(SSTable **st,int length)
{
	(*st)=(SSTable*)malloc(sizeof(SSTable));
	(*st)->length=length;
	(*st)->elem =(ElemType*)malloc((length+1)*sizeof(ElemType));
	printf("输入表中的数据元素:\n");
	//根据查找表中数据元素的总长度,在存储时,从数组下标为 1 的空间开始存储数据
	for (int i=1; i<=length; i++)
	{
		scanf("%d",&((*st)->elem[i].key));
	}
}

//折半查找函数 key为要查找的元素
int Search_Bin(SSTable *str,keyType key)
{
	int low=1;//初始状态 low 指针指向第一个关键字
	int high=str->length;//high 指向最后一个关键字
	int mid;
	while (low<=high)
	{
		mid=(low+high)/2;//int 本身为整形,所以,mid 每次为取整的整数
		if(str->elem[mid].key==key)//如果 mid 指向的同要查找的相等,返回 mid 所指向的位置
		{
			return mid;
		}
        else if(str->elem[mid].key>key)//如果mid指向的关键字较大,则更新 high 指针的位置
		{
			high=mid-1;
		}
		//反之,则更新 low 指针的位置
		else
		{
			low=mid+1;
		}
	}
	return 0;
}

int main()
{
	SSTable *str;
	int num;
	printf("请输入创建数据元素的个数:\n");
	scanf("%d",&num);
	Create(&str, num);
	getchar();
	printf("请输入要查找的数据:\n");
	int key;
	scanf("%d",&key);
	int location=Search_Bin(str, key);
	if (location==0) {
		printf("没有查找到");
	}else{
		printf("要查找的%d的顺序为:%d",key,location);
	}
	return 0;
}

二分查找的原理

二分查找需要传入一个数组(升序)和需要在数组中查找的对应的值,首先对数组的首尾进行标记left,end,获取数组首尾的标记获取中间的数据middle,中间的数据与查找的进行对比,如果中间的数据等于查询的数据,直接返回下标,如果查询的数据大于中间的数据,需要将middle+1赋值给left,如果查询的数据小于中间的数据,则需要将middle-1赋值给end,重复操作,直到找到这个值。

使用条件

1.必须满足顺序储存结构
2.必须满足元素有序排列
3.必须满足储存结构中元素互异

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

大雄是个程序员

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值