数据结构与算法——查找算法

2020-05-17  本文已影响0人  A慢慢懂

一、定义

查找:根据给定的某一个值,在查找表中确定一个其关键字等于给定值的数据元素。
查找表:是有同一类型的数据元素构成的集合。
关键字:是数据元素中某一个数据项值,又称为键值。用它可以表示一个数据元素,也可以标识一个记录的某一个数据项(字段)
若关键字可以唯⼀地标识⼀个记录, 则称此关键字为关键字
(Primary Key)

对于那些可以识别多个属于元素(记录)的关键字,我们称为次关键
字(Secondary Key)

二、查找表操作方式分类

1.静态查找表:只作查找操作的查找表
a.查询某个”特定的”数据元素是否在查找表中
b. 检索某个"特定的"数据元素和各种属性;
2.动态查找表(Dynamic Search Table): 在查找过程中同时插⼊查找表中不存在的数据元素, 或者从查找表中删除已经存在的某个数据元素; 显然动态查找表的操作就是2个动作
a. 查找时插⼊数据元素;
b. 查找时删除数据元素;

三、查找的算法

#include <stdio.h>
#include <string.h>
#include <math.h>
#define OK 1
#define ERROR 0
#define TRUE 1
#define FALSE 0
#define MAXSIZE 100 /* 存储空间初始分配量 */
typedef int Status; /* Status是函数的类型,其值是函数结果状态代码,如OK等 */
typedef int Elemtype;
//a表示数组,n代表个数、key代表所查的记录
Status Sequential_Search(int *a,int n,int key){
    for (int i = 1; i < n-1; i++) {
        if (a[i] == key) {
            //如果有返回OK
            return i;
        }
    }
    return ERROR;
}
int main(int argc, const char * argv[]) {
    // insert code here...
    printf("顺序查找!\n");
    int a[10] = {9,1,3,5,7,9,10,11,13,17};
     int n = 10,key = 15;
    printf("顺序查找啦\n");
    printf("数组a中是否有key = %d的记录------下标为%d(0代表无)\n",key,Sequential_Search(a, n, key));
    return 0;
}
int Binary_Search(int *a,int n,int key){
    int minIndex,maxIndex,mid = 0;
    mid = n;
    minIndex = 1;
    maxIndex = n -1;
    while (minIndex<mid) {
        //每次取中间
        mid = (maxIndex+minIndex)/2;
        if (a[mid]== key) {
            //相等,返回下标
            return mid;
        }else if (a[mid]<key){
            //中间记录值小于key,使最小下标等于mid的下一个下标
            minIndex = mid+1;
        }else{
             //中间记录值大于key,使最小下标等于mid的上一个下标
            maxIndex = mid-1;
        }
    }
    return 0;;
}
//插值查找
int Interpolate_Search(int *a,int n,int key){
    int low,hight,mid = 0;
       mid = n;
       low = 1;
       hight = n -1;
       while (low<hight) {
           mid = low + (hight - low)*(key - a[low])/(a[hight]-a[low]);
           if (a[mid]== key) {
               //相等,返回下标
               return mid;
           }else if (a[mid]<key){
               //记录值小于key,使最小下标等于mid的下一个下标
               low = mid+1;
           }else{
                //记录值大于key,使最小下标等于mid的上一个下标
               hight = mid-1;
           }
       }
       return 0;
}

3.3插值查找:
斐波那契数列,又称黄金分割数列,指的是这样一个数列:0、1、1、2、3、5、8、13、21、····,在数学上,斐波那契被递归方法如下定义:F(1)=1,F(2)=1,F(n)=f(n-1)+F(n-2) (n>=2)。该数列越往后相邻的两个数的比值越趋向于黄金比例值(0.618)
在斐波那契数列找一个等于略大于查找表中元素个数的数F[n],将原查找表扩展为长度为Fn,完成后进行斐波那契分割,即F[n]个元素分割为前半部分F[n-1]个元素,后半部分F[n-2]个元素,找出要查找的元素在那一部分并递归,直到找到。
代码实现:

//5.斐波拉契查找
int F[100]; /* 斐波那契数列 */
int Fibonacci_Search(int *a,int n,int key){
  
    int low,high,mid,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) {
        
        //计算当前分隔的下标;
        mid = low+F[k-1]-1;
        
        
        if (key < a[mid]) {
            //若查找的记录小于当前分隔记录;
            //将最高下标调整到分隔下标mid-1处;
            high = mid-1;
            //斐波拉契数列下标减1位;
            k = k-1;
            
        }else if(key > a[mid]){
            //若查找的记录大于当前的分隔记录;
            //最低下标调整到分隔下标mid+1处
            low = mid+1;
            //斐波拉契数列下标减2位;
            k = k-2;
            
        }else{
            if (mid <= n) {
                //若相等则说明,mid即为查找的位置;
                return mid;
            }else
            {
                //若mid>n,说明是补全数值,返回n;
                return n;
            }
        }
    }
    return 0;
}
上一篇下一篇

猜你喜欢

热点阅读