经典算法之折半查找

经典算法之折半查找

活动地址:CSDN21天学习挑战赛

前言

再长的路,一步一步也能走完,再短的路,不迈开双脚也无法到达。

折半查找

一、什么是折半查找

折半查找也叫二分查找,它是一种效率较高的查找方法,但是,折半查找要求线性表必须采用顺序存储结构,而且表中元素按关键字有序排列。

二、折半查找过程

首先,假设表中的元素是按升序排列,将表中间位置记录的关键字与查找关键字比较,如果两者相等,则查找成功;否则利用中间位置记录将表分成前后两个字表,如果中间位置记录的关键字大于查找关键字,则进一步查找前一子表,否则进一步查找前一子表。否则进一步查找后一子表。重复以上过程直到满足条件的记录,使查找成功,或直到子表不存在为止,此时查找不成功。

三、折半查找思路

  • 输入

n个数的有序序列,以数组为例,默认升序,待查找元素key。

  • 输出
    查找成功:返回元素所在位置的编号。
    查找失败:返回-1或自定义失败的标识。
  • 算法说明
    算法的核心思想是不断缩小搜索的范围,每次取区间的中心来进行比较,会发生三种情况:
    1.与key相等:直接返回对应的位置(对于有重复元素的情况,会在其他子专栏中说明)。
    2.比key大:由于元素有序,要查找的元素一定在右侧(如有),于是搜索区间变为右一半。
    3.比key值小:由于元素有序,要查找的元素一定在右侧(如有),于是搜索区间变为有一半。
    于是,只要不断被的重复取中间值比较和指定新的搜索区间这两个步骤,直到区间的两个端点已经重合(代表搜索完成)或找到元素时为止。请添加图片描述

四、算法要求

1.必须采用顺序存储结构。
2.必须按关键字大小有序排列。

五、比较次数

计算公式:请添加图片描述
当顺序表有n个关键字时:
查找失败时,至少比较a次关键字;查找成功时,最多比较关键字次数是b。(a,b,n为正整数)

六、代码如下

#include<iostream>
using namespace std;
const int n = 10;
void sort(int arr[], int n);
void biserch(int arr[],int low, int high, int h);
int main()
{
	int arr[n] = {11,22,4,78,41,54,68,98,25,62};
	int m;	
	cout << "排序前的数据为:";
	for(m=0;m<n;m++)
	{ 
	 cout<< arr[m] <<" ";
	}
	cout << endl;
	int k = 0;
	sort(arr, n);
	cout << "排序后的数据为:";
	for(k=0;k<n;k++)
	cout<< arr[k] <<" ";
	int a=0;
	cout << endl;
	cout << "请输入要查找的元素:";
	cout << endl;
	cin >> a;
	biserch(arr, 0, 9,a);
	return 0; 
}
void sort(int arr[], int n)//该函数采用直接插入法排序
{
	int i,j,temp;
	for (i = 1; i < n; i++)
	{
		if (arr[i] <arr[i - 1])
		{	         
			temp = arr[i];
	for (j = i - 1; j>=0&&arr[j]>temp; j--)
		{
			arr[j + 1] = arr[j];
		}
		arr[j+1] = temp;
	}
	}
}
void biserch(int arr[], int low, int high, int h)//该函数采用折半查找法查找元素
{
	int mid = 0;//初始化中间的数为0
	while (low <= high)
	{	mid = (low + high) / 2;
	if (h < arr[mid])
	{
		high = mid - 1;
	}
	else if (h> arr[mid])
		low = mid + 1;
	else
	{
		cout << "找到的元素位置为:" << mid + 1 << endl;
		break;
	}
}
}

七、折半查找的优缺点

优点:比较次数少,查找速度快,平均性能好。
缺点:要求待查表为有序表,且插入,删除困难。

  • 5
    点赞
  • 30
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

神秘的老年人

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

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

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

打赏作者

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

抵扣说明:

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

余额充值