已知一个按非降次序排列的一的元素表a1,a2,a3....,an,要求判定给定元素在元素表中是否出现,如出现找出给定元素的位置,这个问题就可以用到 分治法中的二分检索法来做
算法:
procedure BINSRCH(A,n,x,j)
// 一个非降序排列的元素数组A(1:n),n>=1,判断x是否出现。若出现,置j,使得x=A(j),若不出现,j=0 //
integer low,high,mid,j,n;
low <-- 1 ;high <-- n
while low <= high do
mid <--| _(low + high) / 2_ |
case
:x < A(mid):high <-- mid - 1
:x > A(mid):low <-- mid + 1
: else :j <-- mid; return
endcase
j <-- 0
end BINSRCH
// 一个非降序排列的元素数组A(1:n),n>=1,判断x是否出现。若出现,置j,使得x=A(j),若不出现,j=0 //
integer low,high,mid,j,n;
low <-- 1 ;high <-- n
while low <= high do
mid <--| _(low + high) / 2_ |
case
:x < A(mid):high <-- mid - 1
:x > A(mid):low <-- mid + 1
: else :j <-- mid; return
endcase
j <-- 0
end BINSRCH
时间复杂度
成功的检索 不成功的检索
最好:o(1) 平均:o(logn) 最坏o(logn) 最好平均最坏:o(logn)
实现例子(C#) BINSRCH.cs
using
System;
using System.Text;
namespace cn.blogs
{
/// <summary>
/// 用分治法进行二分检索
/// 任意给定10个整数,选取一检索元,分成功和不成功两种情况进行二分检索
/// </summary>
public class BINSRCH
{
static void Main()
{
int [] a = new int []{ 10 , 20 , 30 , 40 , 50 , 60 , 70 , 80 , 90 , 100 };
int x = 0 ;
try
{
Console.WriteLine( " 请填入你要查找的一个数字 " );
x = int .Parse(Console.ReadLine());
}
catch
{
Console.WriteLine( " 请填数字 " );
}
if (bin(a, 10 , x) == - 1 )
{
Console.WriteLine( " 没有找到你要的数字 " );
}
else
{
Console.WriteLine( " 用二分检索查找出位置为 " + (bin(a, 10 , x) + 1 ));
Console.WriteLine( " 用递归二分算法查找出位置为 " + (binD(a, 10 , x, 0 , 9 ) + 1 ));
Console.WriteLine( " 用三分检索查找出位置为 " + (triplesrch(a, 10 , x) + 1 ));
Console.WriteLine( " 用递归三分检索查找出位置为 " + (triplesrchD(a, 10 , x, 0 , 9 ) + 1 ));
}
}
private static int bin( int [] A, int n, int x)
{ // 二分检索算法
int low,high,mid;
low = 0 ;
high = n - 1 ;
while (low <= high)
{
mid = (low + high) / 2 ;
if (x < A[mid])
{
high = mid - 1 ;
}
else if (x > A[mid])
{
low = mid + 1 ;
}
else
{
return mid;
}
}
return - 1 ;
}
private static int binD( int [] A, int n, int x, int low, int high)
{ // 递归二分检索算法
int mid;
while (low <= high)
{
mid = (low + high) / 2 ;
if (x < A[mid])
{
high = mid - 1 ;
return (binD(A, n, x, low, high));
}
else if (x > A[mid])
{
low = mid + 1 ;
return (binD(A, n, x, low, high));
}
else
{
return mid;
}
}
return - 1 ;
}
private static int triplesrch( int [] A, int n, int x)
{ // 三分检索算法
int low, high, mid1,mid2;
low = 0 ;
high = n - 1 ;
while (low <= high)
{
mid1 = low + (high - low) / 3 ;
mid2 = low + 2 * (high - low) / 3 ;
if (x < A[mid1])
{
high = mid1 - 1 ;
}
else if (x > A[mid2])
{
low = mid2 + 1 ;
}
else if (x > A[mid1] && x < A[mid2])
{
low = mid1 + 1 ;
high = mid2 - 1 ;
}
else if (x == A[mid1])
{
return mid1;
}
else if (x == A[mid2])
{
return mid2;
}
}
return - 1 ;
}
private static int triplesrchD( int [] A, int n, int x, int low, int high)
{ // 递归三分检索算法
int mid1, mid2;
while (low <= high)
{
mid1 = low + (high - low) / 3 ;
mid2 = low + 2 * (high - low) / 3 ;
if (x < A[mid1])
{
high = mid1 - 1 ;
return triplesrchD(A, n, x, low, high);
}
else if (x > A[mid2])
{
low = mid2 + 1 ;
return triplesrchD(A, n, x, low, high);
}
else if (x > A[mid1] && x < A[mid2])
{
low = mid1 + 1 ;
high = mid2 - 1 ;
return triplesrchD(A, n, x, low, high);
}
else if (x == A[mid1])
{
return mid1;
}
else if (x == A[mid2])
{
return mid2;
}
}
return - 1 ;
}
}
}
using System.Text;
namespace cn.blogs
{
/// <summary>
/// 用分治法进行二分检索
/// 任意给定10个整数,选取一检索元,分成功和不成功两种情况进行二分检索
/// </summary>
public class BINSRCH
{
static void Main()
{
int [] a = new int []{ 10 , 20 , 30 , 40 , 50 , 60 , 70 , 80 , 90 , 100 };
int x = 0 ;
try
{
Console.WriteLine( " 请填入你要查找的一个数字 " );
x = int .Parse(Console.ReadLine());
}
catch
{
Console.WriteLine( " 请填数字 " );
}
if (bin(a, 10 , x) == - 1 )
{
Console.WriteLine( " 没有找到你要的数字 " );
}
else
{
Console.WriteLine( " 用二分检索查找出位置为 " + (bin(a, 10 , x) + 1 ));
Console.WriteLine( " 用递归二分算法查找出位置为 " + (binD(a, 10 , x, 0 , 9 ) + 1 ));
Console.WriteLine( " 用三分检索查找出位置为 " + (triplesrch(a, 10 , x) + 1 ));
Console.WriteLine( " 用递归三分检索查找出位置为 " + (triplesrchD(a, 10 , x, 0 , 9 ) + 1 ));
}
}
private static int bin( int [] A, int n, int x)
{ // 二分检索算法
int low,high,mid;
low = 0 ;
high = n - 1 ;
while (low <= high)
{
mid = (low + high) / 2 ;
if (x < A[mid])
{
high = mid - 1 ;
}
else if (x > A[mid])
{
low = mid + 1 ;
}
else
{
return mid;
}
}
return - 1 ;
}
private static int binD( int [] A, int n, int x, int low, int high)
{ // 递归二分检索算法
int mid;
while (low <= high)
{
mid = (low + high) / 2 ;
if (x < A[mid])
{
high = mid - 1 ;
return (binD(A, n, x, low, high));
}
else if (x > A[mid])
{
low = mid + 1 ;
return (binD(A, n, x, low, high));
}
else
{
return mid;
}
}
return - 1 ;
}
private static int triplesrch( int [] A, int n, int x)
{ // 三分检索算法
int low, high, mid1,mid2;
low = 0 ;
high = n - 1 ;
while (low <= high)
{
mid1 = low + (high - low) / 3 ;
mid2 = low + 2 * (high - low) / 3 ;
if (x < A[mid1])
{
high = mid1 - 1 ;
}
else if (x > A[mid2])
{
low = mid2 + 1 ;
}
else if (x > A[mid1] && x < A[mid2])
{
low = mid1 + 1 ;
high = mid2 - 1 ;
}
else if (x == A[mid1])
{
return mid1;
}
else if (x == A[mid2])
{
return mid2;
}
}
return - 1 ;
}
private static int triplesrchD( int [] A, int n, int x, int low, int high)
{ // 递归三分检索算法
int mid1, mid2;
while (low <= high)
{
mid1 = low + (high - low) / 3 ;
mid2 = low + 2 * (high - low) / 3 ;
if (x < A[mid1])
{
high = mid1 - 1 ;
return triplesrchD(A, n, x, low, high);
}
else if (x > A[mid2])
{
low = mid2 + 1 ;
return triplesrchD(A, n, x, low, high);
}
else if (x > A[mid1] && x < A[mid2])
{
low = mid1 + 1 ;
high = mid2 - 1 ;
return triplesrchD(A, n, x, low, high);
}
else if (x == A[mid1])
{
return mid1;
}
else if (x == A[mid2])
{
return mid2;
}
}
return - 1 ;
}
}
}