查找——线性表查找技术

  在之前的数据结构ADT中都介绍了基于存储结构的基本运算,其中查找是数据处理中通用的常用操作——很多其他操作,比如删除、修改都是基于查找技术。

  介绍线性表查找技术之前介绍几个将要用到的术语,通用与后续查找技术:

  1、查找表

    查找表(Search Table)是一种以结合为逻辑结构、以查找为核心的数据结构。由于集合中的数据元素之间是没有“关系”的,因此在查找表的实现时就不受“关系”的约束而是根据实际应用对查找的具体要求组织查找表以便实现高效率的查找。

    对查找表中常做的运算有建立查找表、查找、读取表元素以及对表做修改操作(插入、删除元素)等。若对查找表的查找过程不包括对表的修改操作,则此类查找称为静态查找(Static Search);若在查找的同时插入表中不存在的数据元素,或从查找表中删除已存在的指定元素则称为动态查找(Dynamic Search)。

  2、关键码(Key)

    是数据元素(或记录)中某个数据项的值,用它可以标识一个数据元素(或记录)。能唯一确定一个数据元素(或记录)的关键码称为主关键码(PK);而不能唯一确定一个数据元素(或记录)的关键码称为此关键码(SK)。

  3、查找(Searching)

    是指在含有n个元素的查找表中找出关键码等于给定值kx的数据元素(或记录)。当要查找的关键码是主关键码时查找结果是唯一的,一旦找到称为查找成功同时查找过程结束并给出找到的数据元素的信息或指示该数据元素的位置。若是这个表检索完还是没有找到称为查找失败,此时查找结构应给出一个信息。

  4、平均查找长度

    由于查找运算的主要操作是关键码的比较,所以通常把查找过程中对关键码的比较次数的平均值作为衡量一个查找算法效率优劣的标准,称之为平均查找长度(Average Search Length, ASL)。

    ASL是指在查找过程中所进行的关键码比较次数的期望值。对一个含n个数据元素的查找表,查找成功时。其中n是结点的个数;Ci是查找第i个数据元素所需要的比较次数;Pi是查找第i个元素的概率且

  5、数据元素类型定义

    对于后续算法探讨需要自定义数据元素的数据类型,如下:

      

      

  线性表查找属于静态查找,是将查找表视为一个线性表将其顺序或链式存储在进行查找。因此查找思想较为简单,效率不高。那线性表查找相关的算法有哪些呢?结合数据结构之线性结构 - 池塘里洗澡的鸭子 - 博客园 (cnblogs.com)中介绍的线性结构实现各算法并验证测。

  一、顺序查找

  又称线性查找,即依次对每一个记录进行查找,是最基本的查找方法之一。其查找方法为:从表的一端开始,向另一端逐个按给定的关键码kx与每个元素的关键码进行比较——若找到,则查找成功给出数据元素在表中的位置;若这个表检索完之后仍未找到与kx相同的关键码,则查找失败给出失败信息。

  实现:

  1、简单顺序查找

    

  2、加监视哨后的顺序查找

    

    加监控哨后的顺序查找与简单顺序查找优化的地方在while循环的判断:在进行查找之前,data[0]分量的关键码被赋值为kx,不必每次都检测整个表是否查找完毕。即使查找失败,查找也是停在data[0]分量,即i=0。

  二、顺序存储的有序表查找

  有序表是指查找表中的元素是按关键码的大小有序存储的。很多情况下,查找表个元素关键字自己可能构成某种次序关系。如果查找表采用顺序结构存储且按关键码有序存储,那么查找时可采用效率较高的算法实现。下面算法实现假设查找表是按关键码递增有序的。

  实现:

  1、折半查找

    折半查找也称为二分查找,它的思想是:在有序表中取中间元素作为比较对象,若给定值与中间元素的关键码相等,这查找成功;若给定值小于中间元素的关键码,则在中间元素的左半区继续查找;若给定值大于中间元素的关键码,则在中间元素的右半区继续查找。不断重复上述查找过程直到成功或者失败。

      

  2、插值查找

    其思想类似于平常查英文字典的方法:例如在查一个以字母“C”开头的英文单词时,不会用二分查找从字典的中间一页开始,因为知道它的大概位置是在字典的较前面的部分所以可以从前面的某处查起。

    插值查找除要求查找表是顺序存储的有序表外,还要求数据元素的关键字在查找表中均匀分布,这样就可以按比例插值。这样可以利用下述公式找中间点:

      

     其中,low和high分别为表的两个端点下标;kx为给定值。具体算法与折半查找类似,但其是平均性能最好的查找方法,只是适用范围受限:仅适合于关键码均匀分布的表。

       

  3、斐波那契查找

    二分查找每比较一次,将查询区间划分为两个相等的区间,再对其中一个区间继续查找。可否在比较一次后,划分为不相等的两个区间呢?斐波那契就是这样一种划分方法。斐波那契查找通过斐波拉契数列对有序表进行分割,查找区间的两个端点和中间点都与斐波那契数有关。斐波那契数列定义为:

      

    设n个数据元素的有序表且n正好是某个斐波那契数-1,即n=F(k)-1时,可用此查找方法。

    斐波那契查找分割的思想是:对于表长为F(i)-1的有序表,以相对low偏移量F(i-1)-1取中间点,即mid=low+F(i-1)-1,对表进行分割,则左子表表长为F(i-1)-1,右表长为F(i)-1-[F(i-1)-1]-1=F(i-2)-1。可见,两个子表长也都是某个斐波那契数-1,因而可以对子表继续进行分割。

    设查找区间为[low....high],区间长度为F(k)-1(若不是,可增设若干虚结点使得查找表的长度为F(k)-1)。当n很大时,每次分割出来的两个子表的区间长度之比约为0.618,因此此查找方法称为黄金分割法。其平均性能比折半查找好,但是在最坏情况下比折半查找性能查。其有点在于计算分割点时仅作加减运算。

 

 

 

未完,待续……

 

posted on 2022-01-18 20:26  池塘里洗澡的鸭子  阅读(324)  评论(0编辑  收藏  举报