一文搞懂C、Java与Python二分查找算法区别

31 阅读1分钟

C语言版本

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <memory.h>

// 标准非递归版本,传递左右区间指针
int binary_search1(int *arr, int len, int item)
{
  int left = 0;
  int right = len - 1;
  int mid_index;
  int middle;
  while (left <= right)
  {
    mid_index = (left + right) / 2;
    middle = arr[mid_index];
    if (item > middle)
    {
      left = mid_index + 1;
    }
    else
    {
      right = mid_index - 1;
    }
  }
  if (left < len && arr[left] == item)
    return left;
  return -1;
}

// 递归实现,移动左右区间指针
int binary_search2(int *arr, int item, int left, int right)
{
  int mid_index = (left + right) / 2;
  int middle = arr[mid_index];
  if (middle == item)
  {
    if (arr[left] == item)
      return left;
    return mid_index;
  }
  if (left >= right)
    return -1;

  if (item > middle)
    return binary_search2(arr, item, mid_index + 1, right);
  else
    return binary_search2(arr, item, left, mid_index - 1);
}

java语言版本

import java.util.*;

// 标准非递归版本,传递左右区间指针
class BinarySearch {
  int search1(int[] arr, int target) {
    int left = 0;
    int right = arr.length - 1;
    int midIndex, mid;
    // left是左侧,right是最右侧。搜索区间长度小于1时停止
    while (left <= right) {
      midIndex = (left + right) / 2;
      mid = arr[midIndex];
      // 中间项等于目标项则返回下标
      if (target > mid) {
        // 大于中间项折半查找右侧
        left = midIndex + 1;
      } else {
        // 小于中间项折半查找左侧
        right = midIndex - 1;
      }
    }
    //  此时left是最左侧目标项
    if (left < arr.length && arr[left] == target) {
      return left;
    }

    return -1;
  }

  // 递归实现,移动左右区间指针
  int search2(int[] arr, int target, int left, int right) {
    right = right == -1 ? arr.length - 1 : right;
    int midIndex = (left + right) / 2;
    int mid = arr[midIndex];
    // 中间值等于查找项说明找到了,则返回中间项下标
    if (target == mid) {
      // 如果有重复项,返回第一个位置
      if (arr[left] == target) {
        return left;
      }
      return midIndex;
    }
    // 如果左侧与右侧相同,表面查找完毕,返回-1
    if (left >= right) {
      return -1;
    }
    if (target > mid) {
      // 折半右侧部分开始递归查找
      return this.search2(arr, target, midIndex + 1, right);
    } else {
      // 折半左侧部分开始递归查找
      return this.search2(arr, target, left, midIndex - 1);
    }
  }
}

python语言版本

"""
 * Copyright © https://github.com/jarry All rights reserved.
 * @author: jarryli@gmail.com
 * @version: 1.0
"""
import time

# 标准非递归版本,传递左右区间指针
def binary_search1(arr, item):
    left = 0
    right = len(arr) - 1

    while left <= right:
        mid_index = int((left + right) / 2)
        middle = arr[mid_index]
        if item > middle:
            left = mid_index + 1
        else:
            right = mid_index - 1

    if left < len(arr) and arr[left] == item:
        return left
    return -1

# 递归实现,移动左右区间指针
def binary_search2(arr, item, left = 0, right = None):
    right = len(arr) - 1 if right == None else right
    mid_index = int((left + right) / 2)
    middle = arr[mid_index]
    if middle == item:
        if arr[left] == item:
            return left
        return mid_index

    if left >= right:
        return -1

    if item > middle:
        return binary_search2(arr, item, mid_index + 1, right)
    else:
        return binary_search2(arr, item, left, mid_index - 1)

#  二分搜索递归查找,记录下右侧位置
def binary_search3(arr, item, right = 0):
    length = len(arr)
    if (length <= 1 and item != arr[0]):
        return -1
    mid_index = int((length - 1) / 2)
    mid = arr[mid_index]
    if (item == mid):
        return right + mid_index
    elif (item > mid):
        return binary_search3(arr[mid_index:], item, right + mid_index + 1)
    else:
        return binary_search3(arr[0:mid_index], item, right)

其他更多语言版本,敬请关注:

github.com/microwind/a…

github.com/microwind/a…