分治算法--1. 二分查找

分治算法--二分查找


分治算法的基本思想

  1. :把问题划分成子问题
  2. :递归的求解子问题
  3. :把子问题的解合并成问题的解

二分查找基本概念

在计算机科学中,二分查找又称为折半搜索二分搜索,是一种在有序数组中查找某一特定元素的算法。搜素过程从数组的中间元素开始,如果中间元素正好是要查找的元素,则搜素过程结束;如果某一特定元素大于或者小于中间元素,则在数组大于或小于中间元素的那一半中查找,而且跟开始一样从中间元素开始比较。如果在某一步骤数组为空,则代表找不到。这种搜索算法每一次比较都使搜索范围缩小一半。
时间复杂度:O(lgN),折半搜索每次都把搜索区域减少一半。
空间复杂度:O(1)。

分治步骤

  1. :验证中间元素
  2. :递归查询一个子串
  3. :Trivial

C语言实现

1.递归实现

int binary_search_in_recursion(const int arr[], int left, int right, int target)
{
    if (left > right) 
            return -1;

    int mid = (left + right) / 2;
    if (target == arr[mid])
            return mid;
    else if (target < arr[mid])
            return binary_search_in_recursion(arr, left, right - 1, target);
    else 
            return binary_search_in_recursion(arr, left + 1, right, target);
}

2.非递归实现

int binary_search_not_recursion(const int arr[], int left, int right, int target)
{
    while (left <= right)
    {
            int mid = (left + right) / 2;
            if (target == arr[mid])
                    return mid;
            else if (target > arr[mid])
                    left = mid + 1;
            else
                    right = mid - 1;
    }

    return -1;
}

3.旋转过后的排序数组的二分查找

int binary_search_for_rotated_array(const int arr[], int left, int right, int target)
{
    while (left <= right)
    {
            int mid = (left + right) / 2;
            if (target == arr[mid])
                    return mid;
            if (target < arr[mid])
            {
                    if (arr[mid] < arr[right])               // target < arr[mid] < arr[right]
                            right = mid - 1;
                    else
                    {
                            if (target < arr[left])          // target < arr[left] < arr[mid]
                                    left = mid + 1;
                            else                             // target > arr[left] && target < arr[mid]
                                    right = mid - 1;
                    }
            }
            else 
            {
                    if (arr[left] < arr[mid])               // arr[left] < arr[mid] < target
                            left = mid + 1;
                    else
                    {
                            if (arr[right] < target)        // arr[mid] < arr[right] < target
                                    right = mid - 1;
                            else
                                    left = mid + 1;         // target > arr[mid] && target < arr[right]
                    }
            }
    }

    return -1;
}

参考

【1】:http://zh.wikipedia.org/wiki/%E6%8A%98%E5%8D%8A%E6%90%9C%E7%B4%A2%E7%AE%97%E6%B3%95
【2】:http://www.cnblogs.com/ider/archive/2012/04/01/binary_search.html
【3】:http://xpgc.vicp.net/course/ada4ia09/TechDoc/ch02/ia-02-02-divide-and-comquer.pdf

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值