在顺序表中,基本的查找操作有挨过两种方法:二分法和fibonacci法。下面列出核心代码,x代表待查找数,hi代表顺序表末元素下标,lo代表首元素下标。
先说二分查找:
版本A:这是最容易想到的查找方法,但是效率有点低。
while (lo<hi)
{
Rank mi =(lo+hi) >>1;
if(x<A[mi])
hi=mi;
else if(A[mi]<x)
lo=mi+1;
else
return mi;
}
return -1;
版本B:和版本A的区别在于判断条件变成了x<A[mi]和x>=A[mi]。这样使得程序执行的时间开销降低了,因此比较高效。但是最好情况(直接命中中点)也要等到区间宽度到1的时候才能得到结果。
while (1<hi-lo)
{
Rank mi =(lo+hi)>>1;
(x<A[mi])?hi=mi:lo=mi;
}
return (x==A[lo])?lo:-1;
fibonacci查找:
#include<memory>
#include<iostream>
using namespace std;
const int _size = 20;
void Fibonacci(int * F)
{
F[0] = 0;
F[1] = 1;
for (int i = 2; i < _size; ++i)
F[i] = F[i - 1] + F[i - 2];
}
int FibonacciSearch(int *a, int n, int key)
{
int lo = 0;
int hi = n - 1;
int F[_size];
Fibonacci(F);
int k = 0;
while (n > F[k] - 1)
++k;
int * temp;
temp = new int[F[k] - 1];
memcpy(temp, a, n * sizeof(int));
for (int i = n; i < F[k] - 1; ++i)
temp[i] = a[n - 1];
//for (int i = 0; i < F[k] - 1; i++)
// cout << temp[i] << " ";
while (lo < hi)
{
int mid = lo + F[k - 1] - 1;
if (key < temp[mid])
{
hi = mid - 1;
k -= 1;
}
else if (key > temp[mid])
{
lo = mid + 1;
k -= 2;
}
else
{
if (mid < n)
return mid;
else
return n - 1;
}
}
delete[] temp;
return -1;
}
int main()
{
int a[] = { 1,2,3,4,5,6,7,8,9 };
int key;
while (1 > 0)
{
cout << "input a num for searching:";
cin >> key;
int index = FibonacciSearch(a, 9, key);
cout << key << "is located at:" << index << endl;
}
system("pause");
return 0;
}