1 二分查找
//二分查找
typedef int Rank;
template<typename T>
Rank BinarySearch(T *A, T const& value, Rank lo, Rank hi)
{
if (value < A[lo] || A[hi] < value)
return -1;
while (lo <= hi)
{
Rank mid = lo + ((hi - lo) >> 1);
if (A[mid] < value)
lo = mid + 1;
else if (value < A[mid])
hi = mid - 1;
else
return mid;
}
return -1;
}
2 差值查找
差值查找是对二分查找的改进,二分查找每次选择查找序列的中间位置:
差值查找需要经过查找值与查找序列中的最大最小值比较后来确定查找的位置:
//二分查找
template<typename T>
Rank BinarySearch(T *A, T const& value, Rank lo, Rank hi)
{
if (value < A[lo] || A[hi] < value)
return -1;
while (lo <= hi)
{
Rank mid = lo + ((hi - lo) >> 1);
if (A[mid] < value)
lo = mid + 1;
else if (value < A[mid])
hi = mid - 1;
else
return mid;
}
return -1;
}
3 斐波那契查找
斐波那契查找也是一种对二分查找的改进算法,将每次查找的位置选择在查找序列的黄金分割位置。
//斐波那契查找
//F[k-1] + F[k-2] = F[k]
//|----------|-----|
// F[k-1]-1| mid | F[k-2]-1
//Fibonacci递归函数
int Fib(int i)
{
if (i < 2)
{
return i == 0 ? 0 : 1;
}
return Fib(i - 1) + Fib(i - 2);
}
template<typename T>
Rank FibonacciSearch(T *A, T const& value, Rank lo, Rank hi)
{
if (value < A[lo] || A[hi] < value)
return -1;
Rank k = 0;
//计算n在Fibonacci数列中的位置
while (hi > Fib(k) - 1)
{
k++;
}
//补齐数列
for (int i = hi; i < Fib(k) - 1; i++)
{
A[i] = A[hi];
}
while (lo <= hi)
{
Rank mid = lo + Fib(k - 1) - 1;
if (value < A[mid])//在左侧
{
hi = mid - 1;
k--;
}
if (A[mid] < value)//在右侧
{
lo = mid + 1;
k = k - 2;
}
else
{
if (mid <= hi)
return mid;
else
return hi;
}
}
return -1;
}
三种有序查找算法的时间复杂度均为O(logn),差值查找和斐波那契查找是对二分查找的改进,其中,差值查找适合查找序列元素分布均匀的场合,斐波那契查找的平均性能要优于差值查找。
ref:
《大话数据结构》