目录

情境设置:

第一种方案:一一对比

函数递归:

函数递归有两个必要条件:

第二种方案一一对比的进阶版--函数递归

图解:

第三种方案:二分查找

二分查找主要的流程

图解

第四种方案二分查找进阶方案--函数递归

图解

总结:


情境设置:

从一组有序数组中1,2,3,4,5,6,7,8,9,10中找数字。

第一种方案:一一对比

Step1,将有序的数字放到数组中

Step2,设置循环,一个一个的与要找的数进行比较。

int main()
{int arr[] = {1,2,3,4,5,6,7,8,9,10};//将有序的数字放到数组中。int i = 0;//要查找的数字int n = 0;int sz = sizeof(arr) / sizeof(arr[0]);//求数组中元素个数scanf("%d", &i);for (n = 0; n < sz; n++){if (arr[n] == i){printf("找到了,下标为%d", n);break;}}//没找到的时候下标为sz-1if (n > sz-1)printf("找不到");return 0;
}

函数递归:

所谓递归,拆开理解,既存在递推,也存在回归,两个过程。

什么时候可以用函数递归呢?

在我看来,重复执行某一些相同或者类似的”动作“,可以考虑函数递归。

函数递归的中心思想就是大事化小。

个人理解:将我们重复执行的一些相同的或者类似的“动作”,写成函数,设置好限制条件,每一次递推进函数的时候,接近限制条件,最后不满足限制条件,结束递推,开始回归。回归到第一次调用我们函数的时候,递归才算结束。(有点像循环,但不一样)

函数递归有两个必要条件:

1.每一次递归之后,我们都要离递归结束的条件(限制条件)越来越近。

2.需要有一个限制条件,使我们的递归结束

第二种方案一一对比的进阶版--函数递归

我们来分析下:

重复动作:一个一个比较,我们一直在重复这个动作

限制条件的设置:我们什么时候会不比较了呢?要么是找到了,要么是没找到的时候。

我们来看代码

#include <stdio.h>
int search(int* pa,int k,int sz)//  pa是指针指向首元素(arr[0])的地址
{//sz 是最大下标 也就是 9//比较的是  当前进入函数pa所指向的地址,与&arr[9](arr[9]的地址)比较 //pa+sz 一直指向的是 arr[9]的地址,下面有详细说明 //限制条件:每一次递归进来,判断有没有越界if ( pa <= (pa+sz) )  //对10个元素一一找到(下标从0-9){//判断当前地址所指向的元素是不是与要找的k相同if (*pa != k)    //不是的话继续递归//pa+1-->每递归一次,pa指向后面一个元素的地址  //sz-1-->保证了每次递归之后 pa+sz 指向的都是arr[9]的地址//原因很简单,我们pa在递推过程中每次都向后一步,pa+sz也会后走,//为了让pa+sz指向&arr[9]保持不变,sz必须-1return 1 + search(pa + 1, k,sz-1);else //当找到了,就返回0return 0;}else  //返回值可以是任意自然数,下图有说明//不可以是负数,结合主函数中if(ret>sz)条件来看的return 0;
}
int main()
{int arr[] = { 1,2,3,4,5,6,7,8,9,10 };int sz = sizeof(arr) / sizeof(arr[0]) - 1;// sz-->数组的最大下标-->先求的是数组元素个数,再减一。int k = 0;scanf("%d", &k);int ret = search(arr,k,sz);//参数分别为 数组首元素的地址 要找的数 数组的最大下标//ret 表示找到元素的下标 ,如果serch返回的是大于sz(9)的数,那么就是没找到//因为最大下标为9if (ret > sz)printf("找不到");elseprintf("找到了,下标为%d", ret);return 0;
}

图解:

①②...表示每一次递推的顺序

紫色的1,2,3,4...是返回的值

这里是k > 10 的情况

红色线代表递推出去,紫色线代表回归。

为什么ret接收的是10呢?(可以打开监视测试一下),我们search函数进去了11次, ,回去的时候也是11次。回去的时候呢,有10次是return 1+search() , 1次是 结束函数递归的时候,return 0 ;

所谓递归,一去一回。从哪里进来的,回哪里去,每一次回归,都是回到 return 1+ search(pa+1,k,sz-1)的地方

第三种方案:二分查找

一一对法,太过繁琐,每一次都需要比较很多的值才能确定有没有我们要找的数字。

我想大家应该有玩过猜数字的游戏吧。1-100之间的数字,让你去猜,你为了缩小范围先猜50,在看看大了还是小了,在缩小一半,以此类推。

这就是我们的二分查找。

二分查找主要的流程

知左(右)下标,求中间下标,在比较。比较一次,没找到,看k(要找的数)是在中间数的左边还是右边,调整左下标或者右下标,再求中间下标,再比较。一直重复这个动作。直到有一次,我们左下标大于右下标,结束,或者找到k也会结束。

int mid_search(int arr[],int sz,int k)
{//最左边的下标int left = 0;//最右边的下标int right = sz - 1;//循环的限制条件  //在每一次找不到的时候,left或者right会发生改变,直到不满足条件为止,跳出循环while (left <= right){//求中间元素的下标int mid = left + (right - left) / 2;//用中间元素与k进行比较 //中间值大,则说明k在中间值的左边//调整我们的最右边的下标if (arr[mid] > k)right = mid - 1;//中间值小,则说明k在中间值的右边//调整我们最左边的下标else if (arr[mid] < k)left = mid + 1;//找到了就会返回中间元素的下标elsereturn mid;}//如果没找到,我们的 left 将会大于 right 跳出循环//返回一个szreturn sz;
}
int main()
{int arr[] = {1,2,3,4,5,6,7,8,9,10 };int sz = sizeof(arr) / sizeof(arr[0]);//求出数组中元素的个数int k = 0;scanf("%d", &k);//函数参数分别为 数组首元素地址,元素个数,要找的数int ret = mid_search(arr,sz,k);//ret 表示找到元素的下标。因为数组下标从0开始,最大下标为[sz-1]//所以当没找到,返回sz,是可以判断找不到的if (ret>sz-1)printf("找不到");elseprintf("找到了,下标为%d",ret);return 0;
}

图解

图片带你深入理解二分查找

下标,标记的时候是从矩形左侧的边开始标记的。也就是说,要从矩形左边从0开始数。

第四种方案二分查找进阶方案--函数递归

int mid_search(int left, int right,int* pa,int  k)
{int mid = left + (right - left) / 2; //找中间的数的下标  if (left <= right){//中间元素比k要小if (*(pa + mid ) < k) {left = mid + 1;return mid_search(left, right, pa, k);}//中间元素比k要大else if (*(pa + mid ) > k)  {right = mid - 1;return mid_search(left, right, pa, k);}//找到了elsereturn mid;}//找不到//返回一个大于sz-1的数,超过最大下标[sz-1],这里sz = 10(sz元素总个数)return 10;
}
int main()
{int arr[] = { 1,2,3,4,5,6,7,8,9,10 };int k = 0;int left = 0;int right = sizeof(arr) / sizeof(arr[0]) - 1;//最大下标scanf("%d", &k);int ret = mid_search(left,right,arr,k);//参数为左下标,右下标,首元素地址,要查找的数if (ret>right)printf("找不到");elseprintf("找到了,下标为%d", ret);return 0;
}

图解

如何返回?看下面图理解

总结:

我们讲了从有序数组中查找数字的4种方法。

一一对比和进阶版,二分查找和进阶版

让我们更深入了解函数递归。

函数递归,既有递推,又有回归。回归的时候,从哪里来回哪里去。

从有序数组中查找数字的4种方法/二分查找/二分查找的函数递归/一一对比/一一对比的递归相关推荐

  1. php 从数组里删除元素,PHP从数组中删除元素的四种方法实例

    PHP从数组中删除元素的四种方法实例 一.总结 一句话总结:unset(),array_splice(),array_diff(),array_diff_key() 二.PHP从数组中删除元素的四种方 ...

  2. python去重复排序_Python实现删除排序数组中重复项的两种方法示例

    本文实例讲述了Python实现删除排序数组中重复项的两种方法.分享给大家供大家参考,具体如下: 对于给定的有序数组nums,移除数组中存在的重复数字,确保每个数字只出现一次并返回新数组的长度 注意:不 ...

  3. 求栈中元素个数算法_Algorithm 大家都会的去除有序数组中重复元素的三种算法...

    问题描述 给定一个有序数组,要删除数组重复出现的元素,使得每个元素之出现一次,然后返回移除重复数组后的新长度: 示例: 给定数组 nums = [1,2,4,4],删除重复出现的元素后,原数组变成 n ...

  4. java删除数组中重复元素的几种方法

    Java操控数组,删除数组中所有的重复元素,使其数组元素全部唯一,有以下几种方法: 1,使用set(最好想到),set本身就是不重复的集合: package Array_test;import jav ...

  5. 关于iOS去除数组中重复数据的几种方法

    在工作工程中我们不必要会遇到,在数组中有重复数据的时候,如何去除重复的数据呢? 第一种:利用NSDictionary的AllKeys(AllValues)方法 代码: NSArray *dataArr ...

  6. Js中去除数组中重复元素的几种方法

    方法1: 1 Array.prototype.method1=function(){ 2 var arr=[]; 3 for(var i=0;i<this.length;i++){ 4 if(a ...

  7. 数组中交换元素的几种方法总结

    在完成关于数组的大量算法中,基本都会涉及到元素交换,比如排序中是最常见的,一般的方法是新建一个临时变量,然后完成交换,如果给定的数组中元素是有范围的,其实还有其他方法也可以完成交换.下面就来总结一下这 ...

  8. python实现二分查找算法_两种方法实现Python二分查找算法

    一. arr=[1,3,6,9,10,20,30] def findnumber(l,h,number): mid=(l+h)//2 if arr[mid]==number: print(" ...

  9. php数组遍历相同的元素覆盖_php获取数组中重复数据的两种方法

    搜索热词 代码如下: PHP function FetchRepeatMemberInArray($array) { // 获取去掉重复数据的数组 $unique_arr = array_unique ...

  10. php 如何清空数组_PHP从数组中删除元素的四种方法实例

    删除一个元素,且保持原有索引不变 使用 unset 函数,示例如下: $array = array(0 => "a", 1 => "b", 2 =& ...

最新文章

  1. pd.read_csv读取txt时整型变成浮点型问题解决
  2. 《Oracle从入门到精通》读书笔记第八章 管理表空间和数据文件之二
  3. php调用C代码的方法详解和zend_parse_parameters函数详解
  4. 探索适用于Apache Spark的Spline Data Tracker和可视化工具(第2部分)
  5. SRM 698 div1 RepeatString
  6. emd实现信息隐藏_EMD算法原理与实现
  7. 阿里巴巴的页面不能被抓取吗_符合百度抓取的高质量内容(72小时秒收录)
  8. python logging打印终端_想知道Python如何在终端上打印表格吗?两行代码告诉你!
  9. ExtJS用户带验证码登录页面
  10. Android已有的原生Camera框架中加入自己的API的实现方案。
  11. solr的索引库配置
  12. 全新UI四方聚合支付系统源码/新增USDT提现/最新更新安全升级修复XSS漏洞补单漏洞
  13. WPF 最简方法使用自己定制的 WPF 框架
  14. 十种QQ在线客服代码
  15. uni实现前端分页功能
  16. 正余弦转化之诱导公式:“奇变偶不变、符号看象限”
  17. 正阅读微信小说分销系统-视频教程-5.订单明细
  18. Android中的占位符
  19. sql网上书店项目的实现
  20. npm install报错的一天

热门文章

  1. 第二次作业:微博案例分析
  2. mysql中的alter_MySQL中Alter用法
  3. linux直接点击iso安装win10,iso安装win10,win10iso直接解压安装
  4. matlab股票5日移动均线,一分钟,看懂五日均线图!
  5. 2010上机二 中国象棋马走日
  6. 人生如何尽兴呢? 举头天外望,无我这般人「陆九渊」,“惟天下至诚,为能尽其性”...
  7. 页面崩溃原因分析及解决
  8. arcgis自动完成面怎么用_ArcGIS 自动生成线或者面
  9. leetcode寻找重复数
  10. Python 用10行代码教你画出太阳花