二分法及递归和迭代

一  二分法

二分法也为折半搜索,我一般叫对半查找,大致意思是将数组分为两半,比较中间元素和目标值,对比后决定是从左半部分还是右半部分查找,直到找到目标为止。

条件:数组得是有序的。

我们直接上例子

#include<stdio.h>
//定义二分查找函数
int binarySearch(int arr[],int left,int right,int target)
{
while(left<=right){
int mid =left+(right-left)/2;//防止溢出
if(arr[mid]==target){
return mid;//若为目标值直接返回
}
else if(arr[mid]<target)
{left=mid+1;若mid小于目标值将在右半边查找
}
else{
right=mid-1;//mid若大于目标值将在左边查找
}
return -1;//若没有找到目标值返回-1
}

要实现二分查找我们得先确定查找的范围,其次在查找范围内,计算索引mid,同时可能会有人询问为什么是mid=left+(right-left)/2,而不是mid=(left+right)/2,这里我们需要了解的是当其定义的数很大的时候它有可能超出了int可定义的范围(我们可以试试INT_MAX这个代码求出int的最大值为2147483647),当left=INT_MAX-1的时候它们相加会溢出,导致乱码,所以我们用的是我们这个例子,防止溢出。

二分查找的时间复杂度为O(log n),其中n为数组的长度,比起线性查找高效,但是它必须是有序的。

二 递归

递归需要函数直接或间接调用自身解决问题,它通常有两个主要部分:

基本情况:其终止的条件,阻止其无限递归。

递归情况:调用自身解决问题。

递归代码简洁,但是会导致大内存消耗和性能开销,它每次调用都会在调用栈上增加一层。

我们简单举一个递归例子

#include<stdio.h>
//递归求阶乘
int factorial(int n){
if(n<=1)
{return 1;//基本情况
}
else {
return n*factorial(n-1);//递归情况
}
}

三 迭代

迭代通过反复使用循环结构(for,while和do while循环)来解决问题,其通过控制循环变量来控制函数的执行。

其通常比递归高效,因为它不要额外的函数调用开销,但是它会比递归更复杂,更难理解和1维护。

举相同的例子,但用迭代。

#incude<stdio.h>
int factorial(int n)
{
int result=1;
for(int i=2;i<=n;i++)
{result*=i;
}
return result;
}

最后我们实现一下递归和迭代分别实现二分查找

递归

#include<stdio.h>
int erfenchazhao(int arr[],int left,int right,int target){
if(right>=letf){
int mid=left+(right-left)/2;
//目标在中间直接返回
if (arr[mid]==target)
return mid;
//目标值小于中间值,在左边查找
if(arr[mid]>target)
return erfenchazhao(arr,left,mid-1,target);
else
//否则目标在右边
return erfenchazhao(arr,mid+1,right,target);
}
//找不到
return -1;
}

迭代

include<stdio.h>
int erfenchazhao(int arr[],int left,int right,int target){
whlie(left<=right){
int mid=left+(right-left)/2;
//若目标值在中间
if(arr[mid]==target)
return mid;
//若目标值小于中间值则在左边查找
if(arr[mid]>target)
right=mid-1;
//否则在右边
else
left=mid+1;
}
//找不到返回-1
return -1;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值