📜  为什么二元搜索优于三元搜索?

📅  最后修改于: 2021-04-29 12:16:53             🧑  作者: Mango

以下是从此处获取的C++中的简单递归二进制搜索函数。

// A recursive binary search function. It returns location of x in
// given array arr[l..r] is present, otherwise -1
int binarySearch(int arr[], int l, int r, int x)
{
   if (r >= l)
   {
        int mid = l + (r - l)/2;
   
        // If the element is present at the middle itself
        if (arr[mid] == x)  return mid;
   
        // If element is smaller than mid, then it can only be present
        // in left subarray
        if (arr[mid] > x) return binarySearch(arr, l, mid-1, x);
   
        // Else the element can only be present in right subarray
        return binarySearch(arr, mid+1, r, x);
   }
   
   // We reach here when element is not present in array
   return -1;
} 

以下是一个简单的递归三元搜索函数:

C
// A recursive ternary search function. It returns location of x in
// given array arr[l..r] is present, otherwise -1
int ternarySearch(int arr[], int l, int r, int x)
{
   if (r >= l)
   {
        int mid1 = l + (r - l)/3;
        int mid2 = mid1 + (r - l)/3;
  
        // If x is present at the mid1
        if (arr[mid1] == x)  return mid1;
  
        // If x is present at the mid2
        if (arr[mid2] == x)  return mid2;
  
        // If x is present in left one-third
        if (arr[mid1] > x) return ternarySearch(arr, l, mid1-1, x);
  
        // If x is present in right one-third
        if (arr[mid2] < x) return ternarySearch(arr, mid2+1, r, x);
  
        // If x is present in middle one-third
        return ternarySearch(arr, mid1+1, mid2-1, x);
   }
   // We reach here when element is not present in array
   return -1;
}


Java
import java.io.*;
  
class GFG
{
public static void main (String[] args) 
{
      
// A recursive ternary search function. 
// It returns location of x in given array
// arr[l..r] is present, otherwise -1
static int ternarySearch(int arr[], int l, 
                         int r, int x)
{
   if (r >= l)
   {
        int mid1 = l + (r - l) / 3;
        int mid2 = mid1 + (r - l) / 3;
    
        // If x is present at the mid1
        if (arr[mid1] == x)  return mid1;
    
        // If x is present at the mid2
        if (arr[mid2] == x)  return mid2;
    
        // If x is present in left one-third
        if (arr[mid1] > x) 
            return ternarySearch(arr, l, mid1 - 1, x);
    
        // If x is present in right one-third
        if (arr[mid2] < x) 
            return ternarySearch(arr, mid2 + 1, r, x);
    
        // If x is present in middle one-third
        return ternarySearch(arr, mid1 + 1, 
                                  mid2 - 1, x);
   }
     
   // We reach here when element is
   // not present in array
   return -1;
}
}


Python3
# A recursive ternary search function. It returns location of x in
# given array arr[l..r] is present, otherwise -1
def ternarySearch(arr, l, r, x):
    if (r >= l):
        mid1 = l + (r - l)//3
        mid2 = mid1 + (r - l)//3
   
        # If x is present at the mid1
        if arr[mid1] == x:
            return mid1
   
        # If x is present at the mid2
        if arr[mid2] == x:
            return mid2
   
        # If x is present in left one-third
        if arr[mid1] > x:
            return ternarySearch(arr, l, mid1-1, x)
   
        # If x is present in right one-third
        if arr[mid2] < x:
            return ternarySearch(arr, mid2+1, r, x)
   
        # If x is present in middle one-third
        return ternarySearch(arr, mid1+1, mid2-1, x)
     
    # We reach here when element is not present in array
    return -1
     
# This code is contributed by ankush_953


PHP
= $l)
    {
        $mid1 = $l + ($r - $l) / 3;
        $mid2 = $mid1 + ($r - l) / 3;
  
        // If x is present at the mid1
        if ($arr[mid1] == $x) 
            return $mid1;
  
        // If x is present 
        // at the mid2
        if ($arr[$mid2] == $x) 
            return $mid2;
  
        // If x is present in 
        // left one-third
        if ($arr[$mid1] > $x) 
            return ternarySearch($arr, $l, 
                                 $mid1 - 1, $x);
  
        // If x is present in right one-third
        if ($arr[$mid2] < $x) 
            return ternarySearch($arr, $mid2 + 1, 
                                         $r, $x);
  
        // If x is present in
        // middle one-third
        return ternarySearch($arr, $mid1 + 1, 
                             $mid2 - 1, $x);
}
  
// We reach here when element
// is not present in array
return -1;
}
  
// This code is contributed by anuj_67
?>


在最坏的情况下,以上两个中的哪个比较少?
从第一眼看,似乎三元搜索进行的比较次数较少,因为它进行Log 3 n递归调用,但是二进制搜索进行Log 2 n递归调用。让我们仔细看看。
以下是在二进制搜索的最坏情况下用于计数比较的递归公式。

T(n) = T(n/2) + 2,  T(1) = 1

以下是在三元搜索的最坏情况下用于计数比较的递归公式。

T(n) = T(n/3) + 4, T(1) = 1

在二进制搜索中,在最坏的情况下有2Log 2 n +1个比较。在三元搜索中,最坏的情况下有4Log 3 n +1个比较。

Time Complexity for Binary search = 2clog2n + O(1)
Time Complexity for Ternary search = 4clog3n + O(1)

因此,三元搜索和二元搜索的比较简化了表达式2Log 3 n和Log 2 n的比较。 2Log 3 n的值可以写为(2 / Log 2 3)* Log 2 n。由于(2 / Log 2 3)的值大于1,因此在最坏的情况下,三元搜索比二元搜索执行更多的比较。

锻炼:
为什么合并排序将输入数组分为两半,为什么不分为三部分或更多部分?