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

来源:互联网 发布:不将就mv知乎 编辑:程序博客网 时间:2024/06/03 11:27

分治算法--二分查找


分治算法的基本思想

  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