这里介绍四种查找算法:
顺序查找:有哨兵查找和无哨兵查找 时间复杂度O(n)
折半查找 时间复杂度O(log(n))
斐波那契查找:它是利用了黄金分割原理来实现的 时间复杂度O(log(n))
插值查找法:这种方法,是利用公式 mid=low+ (high-low)*(key-a[low])/(a[high]-a[low]); 时间复杂度O(log(n))
可以看出,后面的三种算法明显优于顺序查找,后三种算法,各有特点,具体情境具体选择
#include "stdio.h"
#include "stdlib.h"
#include "io.h"
#include "math.h"
#include "time.h"
#define OK 1
#define ERROR 0
#define TRUE 1
#define FALSE 0
#define MAXSIZE 100 /* 存储空间初始分配量 */
typedef int Status;
int F[100]; //斐波那契数列
//顺序查找:有哨兵查找和无哨兵查找 时间复杂度O(n)
//无哨兵查找
int Sequential_Search(int arr[],int n,int key){
int i;
for(i=1;i<=n;i++){ //每一次需要做多一次比较
if(arr[i] == key){
return i;
}
}
return 0;
}
//有哨兵查找
Sequential_Search2(int arr[],int n,int key){
int i;
arr[0] = key;
i = n;
while(arr[i]!=key){ //不需要 ,一般是最初始化的条件作为结束条件
i--;
}
return i;
}
//折半查找法 O(log(n))
int Binary_Search(int arr[],int n,int key){
int low,high,mid;
low = 1;
high = n;
while(low<=high){
mid = (low+high)/2;
if(key>arr[mid]){
low = mid+1;
}else if(key<arr[mid]){
high = mid-1;
}else{
return mid;
}
}
return 0;
}
// 斐波那契查找:它是利用了黄金分割原理来实现的 O(log(n))
int Fibonacci_Search(int arr[],int n,int key){
int low,high,mid,i,k;
low = 1;
high = n;
k = 0;
//步骤一:
while(n>F[k]-1){ //计算n位于斐波那数列的位置
k++;
}
//步骤二:
for(i=n;i<F[k]-1;i++){
arr[i] = arr[n]; //将不满的后面的数值补全,后面的值均为arr[n];
}
//步骤三:
while(low<=high){
mid = low+F[k-1]-1; //计算当前分隔的下标,也就是说我们将从mid下标开始比较
if(key<arr[mid]) { //若小于
high = mid-1; //最高下标跳到mid-1处
k=k-1; //斐波那契下标减一
}else if(key>arr[mid]){
low = mid +1;
k = k-2; //减两位
}else{ //找到 key = arr[mid]
if(mid<=n){
return mid; //说明mid即就是找到的位置
}else{
return n; //说明是补全的数值
}
}
}
}
// 插值查找法:这种方法,是利用公式 mid=low+ (high-low)*(key-a[low])/(a[high]-a[low]);
//很类似折半查找方法
//不过这种查找只适用于关键字分布比较均匀的表 ,偶然而已
int Interrupt_Search(int arr[],int n,int key){
int low,high,mid;
low =1;
high = n;
while(low<=high){
mid = low+(high-low)*(key-arr[low])/(arr[high]-arr[low]); //公式
if(key<arr[mid]){
high = mid-1;
}else if(key>arr[mid]){
low = mid+1;
}else{
return mid;
}
}
return 0;
}
int main(){
int i;
int arr[MAXSIZE] = {0,1,16,24,35,47,59,62,73,88,99};
//创建一个 Fibonacci数列
F[0] = 0;
F[1] = 1;
for(i=2;i<100;i++){
F[i] = F[i-1]+F[i-2];
}
//顺序查找 O(n)
printf("顺序查找--无哨兵下标=%d,有哨兵下标=%d\n",Sequential_Search(arr,10,62),Sequential_Search2(arr,10,62));
//折半查找 O(log(n))
printf("折半查找--下标=%d\n",Binary_Search(arr,10,62));
//插入查找 O(log(n))
printf("插入查找--下标=%d\n",Interrupt_Search(arr,10,62));
// Fibonacci查找 O(log(n))
printf("Fibonacci查找--下标=%d\n",Fibonacci_Search(arr,10,62));
return 0;
}