当前位置:   article > 正文

二分查找算法(递归+非递归)_治算法——二分查找法 递归 非递归

治算法——二分查找法 递归 非递归

二分查找是针对有序序列来说的,在有序序列中使用二分查找能大大提高查找效率。

二分算法步骤

前提:有序数组中查找关键词所在的位置

① 首先确定整个查找区间的中间位置 mid 

② 用待查关键字key值与中间位置的关键字值进行比较;

若相等,则查找成功

若大于,则在后(右)半个区域继续进行折半查找

若小于,则在前(左)半个区域继续进行折半查找

③ 对确定的缩小区域再按折半公式,重复上述步骤。

 

中间位置mid的表示:

(1)简单的写法

mid = (start + end) / 2

 但这种写法有个缺点:mid可能会溢出。

我们可以举一个简单的例子来证明这一事实。

比如,当start = 1000  ,end = INT_MAX。INT_MAXint数据类型可以存储的上限。这时start + end的和就溢出了。

(2)保险的写法

mid = start + (end - start) / 2

这样的写的好处大概有两个:

第一 :不会产生溢出

第二 :从通用性考虑,适用于对指针或者迭代器的操作。如果start和end同时是指针或者同时是迭代器时无法编译通过,因为俩指针或者俩迭代器运算不支持相加运算,只支持相减运算。

为什么指针和迭代器运算不支持相加运算,只支持相减运算?

我发现网上很少提及这个问题的原因。本人认为原因是这样的:两个迭代器相加,或者两个指针相加后所表示的位置对于vector容器就越界了,失去的意义。但是相减就可以,位置还在容器之中。

(3)(2)的另一种写法

mid = start + ((end - start) >> 1)

 这种写法和(2)一样。

“>>”:表示向右移。value >> num:即value的二进制数整体向右移num位,表示在十进制上就是value除以2的num次方,value >> 1就是value 除以2。

“<<”:表示左移。value << num,就是指value的二进制形式整体向左移动num位,表示在十进制上就是value乘以2的num次方,value << 1就是value乘以2。

故(end - start) >> 1,即为(end - start) / 2。

 

二分查找算法

非递归写法:

  1. /**
  2. *Copyright (c) 2019 Young Fan.All Right Reserved.
  3. *Author: Young Fan
  4. *Date: 2019.04.26
  5. *IDE: Visual Studio 2017
  6. *Description:
  7. */
  8. #include <iostream>
  9. using namespace std;
  10. int binarySearch(int numbers[], int length, int target) {
  11. int length_ptr = sizeof(numbers) / sizeof(int);
  12. cout << length_ptr << endl;//输出为1,sizeof会把从主函数中传进来的字符数组当作是指针来处理。
  13. //指针的大小又是由机器来决定,32位编译器指针变量的大小为4字节,64位编译器指针变量的大小为4字节
  14. if (length == 0)
  15. return -1;
  16. int start = 0, end = length - 1;
  17. while (start <= end) {
  18. int mid = start + (end - start) / 2;
  19. if (numbers[mid] == target)
  20. return mid; //查找到了则返回数据数组的下标
  21. else if (numbers[mid] > target)
  22. end = mid - 1;
  23. else
  24. start = mid + 1;
  25. }
  26. return -1;
  27. }
  28. int main()
  29. {
  30. int numbers[] = { 1, 2, 3, 4, 5, 6, 7}; //有序的
  31. int length = sizeof(numbers) / sizeof(int); //n得7
  32. cout << "length = " << length << endl;
  33. int a = binarySearch(numbers, length, 7); //返回数据数组的下标
  34. cout << a << endl;
  35. return 0;
  36. }

递归写法:

  1. int binarySearch(int[] a, int start, int end, int target) {
  2. if(start > end)
  3. return -1;
  4. int mid = start + (end - start) / 2;
  5. if(a[mid] == target)
  6. return mid;
  7. else if(a[mid] > target)
  8. return binarySearch(a, start, mid-1, target);
  9. else
  10. return binarySearch(a, mid+1, end, target);
  11. }

 

 

 

 

本文内容由网友自发贡献,转载请注明出处:https://www.wpsshop.cn/w/码创造者/article/detail/896640
推荐阅读
相关标签
  

闽ICP备14008679号