数据结构之查找算法

这里介绍四种查找算法:

顺序查找:有哨兵查找和无哨兵查找 时间复杂度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;
}

这里写图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值