查找算法

275 阅读2分钟
#define OK 1
#define ERROR 0
#define TRUE 1
#define FALSE 0
#define MAXSIZE 100 /* 存储空间初始分配量 */
typedef int Status; /* Status是函数的类型,其值是函数结果状态代码,如OK等 */

//1.顺序查找
int Sequential_Search(int *a,int n,int key){
    for (int i=1; i<=n; i++) {
        if (a[i] == key) {
            return i;
        }
    }
    return 0;
}
//2.顺序查找——哨兵
int Sequential_Search2(int *a,int n,int key){
    int i = n;
    a[0] = key;
    while (a[i] != key) {
        i--;
    }
    return i;
}
//3.折半查找(适用于正序排列的数组)
int Binary_Search(int *a,int n,int key){
    int low,mind,high;
    low = 1;
    high = n;
    
    while (low<=high) {
        mind = (low+high)/2;
        if (key<a[mind]) {
            high = mind-1;
        }else if (key>a[mind]){
            low = mind+1;
        }else{
            return mind;
        }
    }
    return 0;
}
//4.插值查找(适用于正序排列的数组)
int Interpolation_Search(int *a,int n,int key){
    int low,high,mind;
    low = 1;
    high = n;
    while (low<= high) {
        //float强转int,向下取整
        mind = ((key-a[low])/(a[high]-a[low])) * (high-low) + low;
        if (key<a[mind]) {
            high = mind-1;
        }else if (key>a[mind]){
            low = mind+1;
        }else{
            return mind;
        }

    }
    return 0;
}

//5.斐波拉契查找(适用于正序排列的数组)
int F[100];
int Fibonacci_Search(int *a,int n,int key){
    int low,high,mind,i,k;
    low = 1;
    high = n;
    k = 0;
    //1.找到n在斐波拉契数组中的位置
    while (n > F[k]-1) {
        k++;
    }
    
    //2.将数组a不满的位置补全
    for (i = n; i<F[k]-1; i++) {
        a[i] = a[n];
    }
    
    //3.
    while (low <= high) {
        //计算当前分隔的下标;
        mind = low + F[k-1]-1;
        if (key < a[mind]) {
            //若查找的记录小于当前分隔记录
            //将最高下标调整到分隔下标mid-1处
            high = mind-1;
            //斐波拉契数列下标减1位
            k = k -1;
        }else if (key > a[mind]){
            //若查找的记录大于当前的分隔记录
            //最低下标调整到分隔下标mid+1处
            low = mind + 1;
            //斐波拉契数列下标减2位
            k = k-2;
        }else{
            if (mind<= n) {
                //若相等则说明,mid即为查找的位置
                return mind;
            }else{
                //若mid>n,说明是补全数值,返回n
                return n;
            }

        }

    }

    return 0;
}

int main(int argc, const char * argv[]) {
    printf("Hello, 静态查找!\n\n");
    int a[MAXSIZE+1],i,result;
    int arr[MAXSIZE] = {0,1,16,24,35,47,59,62,73,88,99};
    for (i = 0; i<= MAXSIZE; i++) {
        a[i] = i;
    }
    //1.顺序查找,时间复杂度O(n)
    result=Sequential_Search(arr,MAXSIZE,59);
    printf("顺序查找:%d\n",result);
    
    //2.顺序查找_哨兵,时间复杂度O(n)
    result=Sequential_Search2(arr,MAXSIZE,59);
    printf("顺序查找_哨兵:%d \n",result);
    
    //3.折半查找,时间复杂度O(log(n))
    result = Binary_Search(arr, 10, 59);
    printf("折半查找:%d \n",result);
    
    //4.插值查找
    result = Interpolation_Search(arr, 10, 59);
    printf("插值查找:%d \n",result);
    
    //5.斐波拉契查找
    //斐波拉契数列计算
    F[0] = 0;
    F[1] = 1;
    for (int i=2; i<100; i++) {
        F[i] = F[i-1] + F[i-2];
    }
    
    result=Fibonacci_Search(arr,10,59);
    printf("斐波拉契查找:%d \n",result);

    printf("\n");
    return 0;
}