二分查找算法的递归实现

还有一个典型的递归例子是对已排序数组的二分查找算法。博e百娱乐城

现在有一个已经排序好的数组,要在这个数组中查找一个元素,以确定它是否在这个数组中,很一般的想法是顺序检查每个元素,看它是否与待查找元素相同。这个方法很容易想到,但它的效率不能让人满意,它的复杂度是O(n)的。现在我们来看看递归在这里能不能更有效。

还是考虑上面的两个条件:

  • 第一:这个问题是否可以分解为形式相同但规模更小的问题?
  • 第二:如果存在这样一种分解,那么这种分解是否存在一种简单情境?

考虑条件一:我们可以这样想,如果想把问题的规模缩小,我们应该做什么?

可以的做法是:我们先确定数组中的某些元素与待查元素不同,然后再在剩下的元素中查找,这样就缩小了问题的规模。那么如何确定数组中的某些元素与待查元素不同呢? 考虑到我们的数组是已经排序的,我们可以通过比较数组的中值元素和待查元素来确定待查元素是在数组的前半段还是后半段。这样我们就得到了一种把问题规模缩小的方法。

接着考虑条件二:简单情境是什么呢?

容易发现,如果中值元素和待查元素相等,就可以确定待查元素是否在数组中了,这是一种简单情境,那么它是不是唯一的简单情境呢? 考虑元素始终不与中值元素相等,那么我们最终可能得到了一个无法再分的小规模的数组,它只有一个元素,那么我们就可以通过比较这个元素和待查元素来确定最后的结果。这也是一种简单情境。

好了,基于以上的分析,我们发现这个问题可以用递归来解决,二分法的代码如下:

01 #include "stdio.h"
02 #include "stdlib.h"
03  
04 void selectionSort(int data[], int count);
05 int binary_search(int *a, int n, int key);
06  
07 void main()
08 {
09     int i, key, rs;
10     int arr[10];
11     int count;
12  
13     printf("排序前数组为:");
14     srand((int)time(0));
15     for(i=0; i < 10; i++)
16     {
17         arr[i] = rand()%100;
18         printf("%d ",arr[i]);
19     }
20  
21     count = sizeof(arr)/sizeof(arr[0]);
22     selectionSort(arr, count);
23  
24     printf("\n排序后数组为:");
25     for(i=0; i < 10; i++)
26     {
27         printf("%d ", arr[i]);
28     }
29  
30     printf("\n请输入要查找的数字:");
31     scanf("%d",&key);
32  
33     rs = binary_search(arr, 10, key);
34     printf("%d ", rs);
35 }
36  
37 void selectionSort(int data[], int count)
38 {
39     int i, j, min, temp;
40     for(i = 0; i < count; i ++) {
41         /*find the minimum*/
42         min = i;
43         for(j = i + 1; j < count; j ++)
44             if(data[j] < data[min])
45                 min = j;
46         temp = data[i];
47         data[i] = data[min];
48         data[min] = temp;
49     }
50 }
51  
52 int binary_search(int *data, int n, int key)
53 {
54     int mid;
55     if(n == 1){
56         return (data[0] == key);
57     }else{
58         mid = n/2;
59         printf("mid=%d\n", data[mid]);
60         if(data[mid-1] == key)
61             return 1;
62         else if(data[mid-1] > key)
63         {
64             printf("key %d 比 data[mid-1] %d 小,取前半段 \n", key, data[mid-1]);
65             return binary_search(&data[0], mid, key);
66         }
67         else
68         {
69             printf("key %d 比 data[mid-1] %d 大,取后半段 \n", key, data[mid-1]);
70             return binary_search(&data[mid], n - mid, key);
71         }
72     }
73 }

程序运行结果:

view source

print?

1 排序前数组为:53 27 26 99 20 17 15 25 23 63
2 排序后数组为:15 17 20 23 25 26 27 53 63 99
3 请输入要查找的数字:20
4 mid=26
5 key 20 比 data[mid-1] 25 小,取前半段
6 mid=20
7 key 20 比 data[mid-1] 17 大,取后半段
8 mid=23
9 1

这个算法的复杂度是O(logn)的,显然要优于先前提到的朴素的顺序查找法。

时间: 2024-11-03 03:44:52

二分查找算法的递归实现的相关文章

二分查找算法(递归与非递归两种方式)

首先说说二分查找法. 二分查找法是对一组有序的数字中进行查找,传递相应的数据,进行比较查找到与原数据相同的数据,查找到了返回1,失败返回对应的数组下标. 采用非递归方式完成二分查找法.java代码如下所示. /* * 非递归二分查找算法 * 参数:整型数组,需要比较的数. */ public static int binarySearch(Integer[]srcArray,int des){ //第一个位置. int low=0; //最高位置.数组长度-1,因为下标是从0开始的. int h

二分查找算法的递归、循环实现及其缺陷

关于二分查找法 在学习算法的过程中,我们除了要了解某个算法的基本原理.实现方式,更重要的一个环节是分析算法的复杂度.在时间复杂度和空间复杂度之间,我们又会更注重时间复杂度,往往用牺牲空间换时间的方法提高时间效率. 时间复杂度按优劣排差不多集中在: O(1), O(log n), O(n), O(n log n), O(n2), O(nk), O(2n) 二分查找法主要是解决在"一堆数中找出指定的数"这类问题,而想要应用二分查找法,这"一堆数"必须有一下特征: 存储在

二分查找算法(递归,循环)

二分查找算法是在有序数组中用到的较为频繁的一种算法,在未接触二分查找算法时,最通用的一种做法是,对数组进行遍历,跟每个元素进行比较,其时间为O(n).但二分查找算法则更优,因为其查找时间为O(lgn),譬如数组{1, 2, 3, 4, 5, 6, 7, 8, 9},查找元素6,用二分查找的算法执行的话,其顺序为:    1.第一步查找中间元素,即5,由于5<6,则6必然在5之后的数组元素中,那么就在{6, 7, 8, 9}中查找,    2.寻找{6, 7, 8, 9}的中位数,为7,7>6,

Python——递归、二分查找算法

递归函数 1. 递归 (1)什么是递归:在函数中调用自身函数(2)最大递归深度:默认997/998--是Python从内存角度出发做的限制 n = 0 def story(): global n n+= 1 print(n) story() #997/998 story() (3)修改最大深度:最好不要改--递归次数太多,则不适合用递归解决问题 import sys sys.setrecursionlimit(2000) #1997/1998 2. 递归的优点 会让代码变简单 3. 递归的缺点

算法_001_二分查找算法

 二分查找算法是在有序数组中用到的较为频繁的一种算法,在未接触二分查找算法时,最通用的一种做法是,对数组进行遍历,跟每个元素进行比较,其时间为O(n).但二分查找算法则更优,因为其查找时间为O(lgn),譬如数组{1, 2, 3, 4, 5, 6, 7, 8, 9},查找元素6,用二分查找的算法执行的话,其顺序为:     1.第一步查找中间元素,即5,由于5<6,则6必然在5之后的数组元素中,那么就在{6, 7, 8, 9}中查找,    2.寻找{6, 7, 8, 9}的中位数,为7,7>

Java学习之二分查找算法

好久没写算法了.只记得递归方法..结果测试下爆栈了. 思路就是取范围的中间点,判断是不是要找的值,是就输出,不是就与范围的两个临界值比较大小,不断更新临界值直到找到为止,给定的集合一定是有序的. 自己写的代码: 1 package com.gh; 2 3 import java.util.Arrays; 4 /** 5 * 二分查找算法实现 6 * @author ganhang 7 * 8 */ 9 public class Search { 10 public static void mai

二分查找算法java实现

今天看了一下JDK里面的二分法是实现,觉得有点小问题.二分法的实现有多种今天就给大家分享两种.一种是递归方式的,一种是非递归方式的.先来看看一些基础的东西. 1.算法概念. 二分查找算法也称为折半搜索.二分搜索,是一种在有序数组中查找某一特定元素的搜索算法.请注意这种算法是建立在有序数组基础上的. 2.算法思想. ①搜素过程从数组的中间元素开始,如果中间元素正好是要查找的元素,则搜素过程结束: ②如果某一特定元素大于或者小于中间元素,则在数组大于或小于中间元素的那一半中查找,而且跟开始一样从中间

二分查找算法

提到查找算法,最经典的就是二分查找算法了.在二分查找时要在有序的数据里查找目标target,先取中间元素与target比较, 当target小于中间元素的时候,则搜索数组的前半部分,target大于中间元素时,则取数组的后半部分.重复整个搜索的过程 将左半部分与有半部分当作子数组继续查找,直到找到元素或到子数组的大小为0停止. 原理上很简单却有较多细节,尤其是数据边界的取值是否会越界,while循环的条件. java code: public class BinarySearchDemo { p

python函数:递归函数及二分查找算法

本文和大家分享的主要是python的递归函数及二分查找算法相关内容,一起来看看吧,希望对大家学习python有所帮助. 一.递归的定义 def story(): s = """ 从前有个山,山里有座庙,庙里老和尚讲故事, 讲的什么呢? """ print(s) story() story() 老和尚讲故事 递归的定义 -- 在一个函数里再调用这个函数本身.这种魔性的使用函数的方式就叫做 递归 . 递归的最大深度:997 1.python递归最大层