二分搜索「递归和迭代」在C程序中的实现

1. 二分搜索的基本概念

在计算机科学中,二分搜索,也称为折半搜索、对数搜索或二进制搜索,是一种在有序数组中查找某一特定元素的搜索算法。该算法每次比较中间位置元素与查找元素,如果中间位置元素大于查找元素,则在左半边继续查找;如果中间位置元素小于查找元素,则在右半边继续查找,直到在中间位置找到要查找的元素,或者确定要查找的元素不存在于数组中为止。

二分搜索算法的核心思想就是不断地分割有序数组,并通过每次比较中间位置元素与查找元素的大小关系,确定下一次查找的区间,直到找到要查找的元素或者确认该元素不存在于数组中为止。

2. 二分搜索的递归实现

2.1 递归实现的基本思路

二分搜索也可以使用递归的方式来实现。递归实现的基本思路是,将要查找的区间不断折半,然后通过递归不断地对左半边或右半边进行查找,直到找到要查找的元素或者确认该元素不存在于数组中为止。

因此,我们可以先将中间位置元素与查找元素进行比较,如果相等,则直接返回该位置;如果中间位置元素大于查找元素,则通过递归在左半边继续查找;如果中间位置元素小于查找元素,则通过递归在右半边继续查找。

简单来说,递归实现的二分搜索算法主要分为以下几个步骤:

比较中间位置元素与查找元素

如果找到了元素,直接返回其位置

如果中间位置元素大于查找元素,对左半边进行递归查找

如果中间位置元素小于查找元素,对右半边进行递归查找

如果找不到元素,返回-1

2.2 递归实现的代码

下面是二分搜索的递归实现的C++代码:

int binarySearchRecursive(int arr[], int low, int high, int target){

if(low <= high){

int mid = (low + high) / 2;

if(arr[mid] == target){

return mid;

}

else if(arr[mid] > target){

return binarySearchRecursive(arr, low, mid-1, target);

}

else{

return binarySearchRecursive(arr, mid+1, high, target);

}

}

return -1;

}

上述代码中,arr是要查找的数组,low是查找的左界限,high是查找的右界限,target是要查找的元素。

在每一轮递归中,先计算出中间位置mid,然后比较arr[mid]与target的大小关系,确定下一步的查找方向。

如果arr[mid]等于target,则直接返回mid;如果arr[mid]大于target,则在左半边继续查找(target存在的话);如果arr[mid]小于target, 则在右半边继续查找(target存在的话)。

如果最终找不到,则返回-1。

2.3 递归实现的测试

为了验证我们的递归实现是否正确,我们可以编写几个测试用例进行测试。

假设要查找的数组为{1, 2, 3, 4, 5, 6, 7, 8, 9},要查找的元素为6。

int main(){

int arr[] = {1, 2, 3, 4, 5, 6, 7, 8, 9};

int target = 6;

int result = binarySearchRecursive(arr, 0, 8, target);

if(result != -1){

cout << "Element found at index " << result << endl;

}

else{

cout << "Element not found in the array" << endl;

}

return 0;

}

以上代码输出应该为:Element found at index 5。

3. 二分搜索的迭代实现

3.1 迭代实现的基本思路

除了递归实现,二分搜索还可以使用迭代的方式来实现。迭代实现的基本思路是,使用循环不断地对要查找的区间进行折半,直到找到要查找的元素或者确认该元素不存在于数组中为止。

在每一轮循环中,先计算出中间位置mid,然后比较arr[mid]与target的大小关系,确定下一步的查找方向。

如果arr[mid]等于target,则直接返回mid;如果arr[mid]大于target,则在左半边继续查找(target存在的话);如果arr[mid]小于target,则在右半边继续查找(target存在的话)。

如果最终找不到,则返回-1。

3.2 迭代实现的代码

下面是二分搜索的迭代实现的C++代码:

int binarySearchIterative(int arr[], int low, int high, int target){

while(low <= high){

int mid = (low + high) / 2;

if(arr[mid] == target){

return mid;

}

else if(arr[mid] > target){

high = mid - 1;

}

else{

low = mid + 1;

}

}

return -1;

}

上述代码中,arr是要查找的数组,low是查找的左界限,high是查找的右界限,target是要查找的元素。

在每一轮循环中,先计算出中间位置mid,然后比较arr[mid]与target的大小关系,确定下一步的查找方向。

如果arr[mid]等于target,则直接返回mid;如果arr[mid]大于target,则在左半边继续查找(target存在的话);如果arr[mid]小于target,则在右半边继续查找(target存在的话)。

如果最终找不到,则返回-1。

3.3 迭代实现的测试

我们可以使用相同的测试用例对迭代实现进行测试。结果应该与递归实现得到的结果相同。

int main(){

int arr[] = {1, 2, 3, 4, 5, 6, 7, 8, 9};

int target = 6;

int result = binarySearchIterative(arr, 0, 8, target);

if(result != -1){

cout << "Element found at index " << result << endl;

}

else{

cout << "Element not found in the array" << endl;

}

return 0;

}

以上代码输出应该为:Element found at index 5。

4. 递归实现和迭代实现的比较

递归实现和迭代实现的本质相同,都是通过比较中间位置元素与查找元素的大小关系,确定下一步的查找方向,直到找到要查找的元素或者确认该元素不存在于数组中为止。

二者最大的差别在于实现方式不同。

递归实现相对于迭代实现的优点是代码简洁易懂,不需要手动维护查找区间;缺点是可能存在栈溢出问题,效率相对较低,占用内存较大。

迭代实现相对于递归实现的优点是代码更加高效,占用的内存空间更小;缺点是代码难以理解,需要手动维护查找区间。

选择递归实现或迭代实现取决于具体的情况,如果数据量较大,建议使用迭代实现;如果数据量较小,并考虑代码易读性的话,建议使用递归实现。

5. 总结

二分搜索是一种查找有序数组中特定元素的高效算法,其核心思想是不断将查找区间折半,通过与中间位置元素的比较不断缩小查找范围,直到找到要查找的元素或者确认该元素不存在于数组中为止。

二分搜索可以通过递归或迭代的方式来实现,两种实现方式都是在不断比较中间位置元素与查找元素的大小关系,然后确定下一步的查找方向。其本质相同,只是实现方式不同。

在选择实现方式时,需要根据具体情况综合考虑效率和易读性,权衡各种因素。

后端开发标签