C语言数据结构中二分查找递归非递归实现并分析

yizhihongxing

C语言数据结构中二分查找递归及非递归实现

二分查找基本原理

二分查找(Binary Search)是一种基于比较目标值和中间元素的教科书式算法。每次查找都将查找范围缩小一半,直到找到目标值为止,或发现查找范围已经为空。

二分查找前提条件

在使用二分查找之前,我们需要满足以下两个前提条件:

  • 数组必须是有序的。
  • 数组需要支持随机访问,也就是支持索引。

二分查找的两种方法

在C语言中,我们通常使用两种方式实现二分查找:递归和非递归。

递归方法实现二分查找

递归实现二分查找通常需要定义一个辅助函数,如下所示:

#include <stdio.h>

int binaryRecursiveSearch(int *arr, int low, int high, int target) {
    if (low > high) {
        return -1;
    }
    int middle = (low + high) / 2;
    if (arr[middle] == target) {
        return middle;
    }
    if (arr[middle] > target) {
        return binaryRecursiveSearch(arr, low, middle - 1, target);
    } else {
        return binaryRecursiveSearch(arr, middle + 1, high, target);
    }
}

int main() {
    int arr[] = {1, 3, 5, 7, 9, 11, 13};
    int length = sizeof(arr) / sizeof(int);
    int target = 11;
    int index = binaryRecursiveSearch(arr, 0, length - 1, target);
    printf("Target %d is located at %d.\n", target, index);
    return 0;
}

在上述代码中,binaryRecursiveSearch 函数是一个递归函数,接收四个参数:

  • arr表示要查找的数组;
  • low表示数组范围的最小索引;
  • high表示数组范围的最大索引;
  • target表示要查找的目标元素。

首先,函数会计算出数组范围的中间索引,并将其保存在 middle 变量中。接着,如果 arr[middle] == target,则说明目标元素就是这个中间元素,直接返回 middle。如果 arr[middle] > target,则说明目标元素在数组范围的左半部分,于是递归调用 binaryRecursiveSearch(arr, low, middle - 1, target);否则,目标元素就在数组范围的右半部分,递归调用 binaryRecursiveSearch(arr, middle + 1, high, target)。如果递归到数组范围为空,即 low > high,则返回 -1 表示未找到目标元素。

我们可以将上述函数调用一个示例,如下所示:

int arr[] = {1, 3, 5, 7, 9, 11, 13};
int length = sizeof(arr) / sizeof(int);
int target = 11;
int index = binaryRecursiveSearch(arr, 0, length - 1, target);
printf("Target %d is located at %d.\n", target, index);

在上述代码中,我们先定义一个有序的数组 arr,然后计算出数组的长度 length 和要查找的目标元素 target。最后,我们调用递归函数 binaryRecursiveSearch(arr, 0, length - 1, target),找到目标元素在数组中的索引。

非递归方法实现二分查找

非递归方式实现二分查找相较于递归方式略显繁琐,但却可以避免函数调用栈大小不断增长的问题,同时也可以节省时间。

非递归方式实现二分查找示例代码如下:

#include <stdio.h>

int binaryIterativeSearch(int *arr, int size, int target) {
    int left = 0;
    int right = size - 1;
    while (left <= right) {
        int middle = (left + right) / 2;
        if (arr[middle] == target) {
            return middle;
        } else if (arr[middle] > target) {
            right = middle - 1;
        } else {
            left = middle + 1;
        }
    }
    return -1;
}

int main() {
    int arr[] = {1, 3, 5, 7, 9, 11, 13};
    int length = sizeof(arr) / sizeof(int);
    int target = 11;
    int index = binaryIterativeSearch(arr, length, target);
    printf("Target %d is located at %d.\n", target, index);
    return 0;
}

在上述代码中,我们定义了一个名为 binaryIterativeSearch 的函数。与递归方式不同,迭代式查找需要三个参数:

  • arr 表示要查找的数组;
  • size 表示数组的长度;
  • target 表示要查找的目标元素。

函数中,我们首先定义了两个变量 leftright,分别用于表示数组的最小索引和最大索引。通过不断缩小范围,最终找到目标元素或返回 -1 表示未找到。具体实现如下:

  • 每次找到中间元素 middle = (left + right) / 2
  • 如果 arr[middle] == target,直接返回 middle
  • 如果 arr[middle] > target,说明要查找的元素在数组的左半部分,于是右边界 right 变成了 middle - 1
  • 如果 arr[middle] < target,说明要查找的元素在数组的右半部分,于是左边界 left 变成了 middle + 1
  • 不断缩小范围,直到找到或未找到。

我们可以通过一个示例代码来演示非递归方式实现二分查找:

int arr[] = {1, 3, 5, 7, 9, 11, 13};
int length = sizeof(arr) / sizeof(int);
int target = 11;
int index = binaryIterativeSearch(arr, length, target);
printf("Target %d is located at %d.\n", target, index);

在上述代码中,我们先定义一个有序的数组 arr,然后计算出数组的长度 length 和要查找的目标元素 target。最后,我们调用非递归函数 binaryIterativeSearch(arr, length, target),找到目标元素在数组中的索引。

总结

本文演示了C语言数据结构中二分查找的递归和非递归两种实现方式,并且讲解了二分查找的基本原理和前提条件,希望对读者掌握二分查找有所帮助。

示例说明

  1. 递归实现二分查找

在示例中,定义一个有序的数组 arr,然后计算出数组的长度 length 和要查找的目标元素 target。最后,调用递归函数 binaryRecursiveSearch(arr, 0, length - 1, target),找到目标元素在数组中的索引。

  1. 非递归实现二分查找

在示例中,定义一个有序的数组 arr,然后计算出数组的长度 length 和要查找的目标元素 target。最后,调用非递归函数 binaryIterativeSearch(arr, length, target),找到目标元素在数组中的索引。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:C语言数据结构中二分查找递归非递归实现并分析 - Python技术站

(0)
上一篇 2023年6月27日
下一篇 2023年6月27日

相关文章

  • CAD怎么快测量两个图块间的间距?

    当使用CAD软件时,可以使用以下步骤快速测量两个图块之间的间距: 打开CAD软件并加载所需的图纸。 使用绘图工具选择一个图块的边界。 在CAD软件的命令行中输入“DIST”命令,然后按下回车键。 在CAD软件的图形界面中,选择第二个图块的边界。 在CAD软件的命令行中,将显示两个图块之间的距离。 以下是两个示例说明: 示例1:假设你有一个CAD图纸,其中包含…

    other 2023年8月5日
    00
  • iOS12描述文件无法下载怎么回事 iOS12描述文件跳不出来的解决方法

    下面是关于iOS12描述文件无法下载的解决方法的完整攻略。 什么是iOS12描述文件 iOS描述文件是用于iOS设备上的开发和测试的一组信息,用于描述和配置iOS设备上的应用程序。在编写和测试iOS应用程序时,您需要将它们部署到iOS设备上,并且在安装应用程序之前需要安装适当的配置文件。 iOS12描述文件是针对iOS12版本的配置文件。与其他版本的配置文件…

    other 2023年6月27日
    00
  • Linux dirname命令的具体使用

    Linux dirname命令的具体使用攻略 Linux dirname命令用来返回指定路径参数中的目录部分。具体来说,dirname会忽略指定路径参数的最后一个路径名并返回其上一级目录的路径(如果路径名参数只包含一个路径名则返回当前目录的路径名)。 命令格式 dirname [OPTION] PATH 参数说明 PATH:要处理的路径名。如果PATH参数不…

    other 2023年6月27日
    00
  • 模仿combox(select)控件,不用为美化select烦恼了。

    下面我将详细讲解如何模仿combox(select)控件,不用为美化select烦恼的完整攻略。 一、前言 在前端开发中,常常会遇到需要美化select控件的情况,而原生的select控件却难以满足我们的需求。本篇攻略将教你如何使用HTML、CSS和JavaScript制作一个类似于combox(select)控件的效果,同时保留原生select的所有功能。…

    other 2023年6月26日
    00
  • meta标签设置(移动端)

    什么是meta标签? meta标签是HTML文档中的一种特殊标签,用于提供有关文档的元数据信息。在移动端网页开发中,meta标签可以用于设置网页的视口(viewport)、缩放比例、主题颜色等信息。 meta标签设置(移动端) 以下是在移动端网页开发中常用的meta标签设置: 设置视口(viewport) 视口是指用户在浏览器中看到的网页区域。在移动设备上,…

    other 2023年5月7日
    00
  • SSAS aggregation 的作用及其使用

    SSAS Aggregation 的作用及其使用 在使用SQL Server分析服务(SSAS)构建数据立方体时,为了提高查询性能,我们需要使用聚合(Aggregation)技术。 什么是SSAS Aggregation 聚合是SSAS中的高级功能,用于存储和预计算SUM、COUNT、AVG等聚合函数在维度属性上的值集合。这样,当用户查询数据时,SSAS可以…

    其他 2023年3月28日
    00
  • guava的两种本地缓存策略

    guava的两种本地缓存策略 Guava是一个基于Java的开源库,提供了一些常用的工具类,其中包括了本地缓存的实现。Guava缓存可以快速地添加逐出策略、提供统计信息和异步加载等功能,可用于提高应用程序的性能。 在Guava缓存中,有两种本地缓存策略:基于大小的缓存和基于时间的缓存。 基于大小的缓存 基于大小的缓存指使用缓存条目的数量或缓存的总大小作为驱逐…

    其他 2023年3月28日
    00
  • 求32位机器上unsigned int的最大值及int的最大值的解决方法

    求32位机器上unsigned int的最大值及int的最大值的解决方法 在32位机器上,unsigned int的最大值可以通过以下步骤求得: 确定机器上整数类型的位数:32位机器上,整数类型的位数为32位。 计算unsigned int的最大值:由于unsigned int是无符号整数类型,它的取值范围是从0到2^32-1。因此,unsigned int…

    other 2023年7月28日
    00
合作推广
合作推广
分享本页
返回顶部