美文网首页
数据结构与算法——查找算法

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

作者: A慢慢懂 | 来源:发表于2020-05-17 09:45 被阅读0次

    一、定义

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

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

    二、查找表操作方式分类

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

    三、查找的算法

    • 3.1顺序查找:又称为线性查找,是最基本的查找技术。查找过程:从表中的第一个或者做后一个记录开始,逐个进行记录关键字和给定值比较。
      1.若某一个记录的关键字和给定值相等,则查找成功,找到所查记录。
      2.若到最后一个或者第一个两者都不相等,则查不到所查记录,查找不成功。
      代码实现:
    #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;
    }
    
    • 3.2折半查找:又称为二分查找。
      1、前提是线性表中的记录必须是关键码有序,线性表必须采用的是顺序存储。
      2、基本思想:
      a.在有序表中,取中间记录作为比较对象。若给定值与中间记录的关键字相等,则查找成功。
      b.若给定值⼩于中间的记录关键字,则在中间记录的左半区继续查找;
      c.若给定的值⼤于中间记录的关键字,则在中间记录的右半区继续查找;
      d.不断重复以上的过程,直到查找成功,或所以查找区域⽆记录,查找失败为⽌.
      代码实现:
    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;;
    }
    
    • 3.3插值查找:是根据查找的关键字key 与查找表中最⼤最⼩记录的关键字⽐较后的查找⽅法, 其核⼼就是在于插值的计算公式:( key - a[low])/ (a[high] - a[low] )
      代码实现:
    //插值查找
    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;
    }
    

    相关文章

      网友评论

          本文标题:数据结构与算法——查找算法

          本文链接:https://www.haomeiwen.com/subject/ngvxohtx.html