数据结构 - 静态查找

查找

主要讨论顺序表、有序表、索引表和哈希表查找的各种实现方法,以及相应查找方法在等概率情况下的平均查找长度。

 查找表(Search Table):相同类型的数据元素(对象)组成的集合,每个元素通常由若干数据项构成。
   关键字(Key,码):数据元素中某个(或几个)数据项的值,它可以标识一个数据元素。若关键字能唯一标识一个数据元素,则关键字称为主关键字(Primary Key) ;将能标识若干个数据元素的关键字称为次关键字(Secondary Key) 。
   查找/检索(Searching):根据给定的K值,在查找表中确定一个关键字等于给定值的记录或数据元素。

◆ 查找表中存在满足条件的记录:查找成功;结果:所查到的记录信息或记录在查找表中的位置。

◆ 查找表中不存在满足条件的记录:查找失败。

根据查找表的操作方式,分为静态查找表和动态查找表。

静态查找表(Static Search): 只对查找表进行如下操作:

(1)查看某个特定的数据元素是否在查找表中,

(2)检索某个特定元素和各种属性。

动态查找表(Dynamic Search):在查找过程中,可进行如下操作:

(1)可以将查找表中不存在的数据元素插入,

(2)从查找表中删除已存在的某个记录。

为了提高查找的效率,除了应用好的查找算法外,也会为查找设立专门的数据结构来存储数据,比如表、树等等。

查找表的存储结构:

查找表是一种非常灵活的数据结构,可以用多种方式来存储。

根据存储结构的不同,查找方法可分为三大类:

① 顺序表和链表的查找:将给定的K值与查找表中记录的关键字进行比较, 找到要查找的记录;

② 散列表的查找:根据给定的K值直接访问查找表, 从而找到要查找的记录;

③ 索引查找表的查找:首先根据索引确定待查找记录所在的块 ,然后再从块中找到要查找的记录。

一般地,认为记录的关键字是一些可以进行比较运算的类型,如整型、字符型、实型等,本章以后各节中讨论所涉及的关键字、数据元素等的类型描述如下:

典型的关键字类型说明是:

typedef  float   KeyType ;       /*  实型  */
typedef  int   KeyType ;       /*  整型  */
typedef  char  KeyType ;       /*  字符型  */
       数据元素类型的定义是:
typedef  struct  RecType
{  KeyType  key ;          /* 关键字码  */
┇ /* 其他域  */
}RecType ;

静态查找

    静态查找表的抽象数据类型定义如下:

ADT Static_SearchTable{

数据对象D:D是具有相同特性的数据元素的集合,

各个数据元素有唯一标识的关键字。

数据关系R:数据元素同属于一个集合。

基本操作P:

Create

Destroy

Search

Traverse

} ADT Static_SearchTable

线性表是查找表最简单的一种组织方式,本节介绍几种主要的关于线性表的查找方法。

顺序查找

适用场合:针对查找表中的元素没有按关键字进行排序(即无序线性表)

1 查找思想

从表的一端(第一个或 最后一个)开始逐个将记录的关键字和给定K值进行比较,若某个记录的关键字和给定K值相等,查找成功;否则,若扫描完整个表,仍然没有找到相应的记录,则查找失败。顺序表的类型定义如下:

#define MAX_SIZE  100
typedef  struct  SSTable
{  RecType  elem[MAX_SIZE] ;    /*  顺序表  */
int  length ;     /*  实际元素个数  */
}SSTable ;
int  Seq_Search ( SSTable  ST , KeyType key)
{   int i ;
ST. elem[0].key=key ;    /*  设置监视哨兵,失败返回0  */
for (i=ST.length; i>=1;i--)
     if (ST. elem[i].key==key)
            return i;
return 0;
}

折半查找

前提条件:查找表中的所有记录是按关键字有序(升序或降序) 。

查找过程中,先确定待查找记录在表中的范围,然后逐步缩小范围(每次将待查记录所在区间缩小一半),直到找到或找不到记录为止。

1 查找思想

用Low、High和Mid表示待查找区间的下界、上界和中间位置指针,初值为Low=1,High=n。

⑴ 取中间位置Mid:Mid=?(Low+High)/2? ;

⑵ 比较中间位置记录的关键字与给定的K值:

① 相等: 查找成功;

② 大于:待查记录在区间的前半段,修改上界指针: High=Mid-1,转⑴ ;

③ 小于:待查记录在区间的后半段,修改下界指针:Low=Mid+1,转⑴ ;

直到越界(Low>High),查找失败。

2  算法实现
int  Bin_Search(SSTable  ST , KeyType  key)
{    int  Low=1,High=ST.length, Mid ;
while (Low<High)
{     Mid=(Low+High)/2 ;
if  (ST. elem[Mid].key== key))
    return(Mid) ;
else if (ST. elem[Mid].key<key))
           Low=Mid+1 ;
       else   High=Mid-1 ;
}
return(0) ;      /*   查找失败  */
}

Fibonacci查找

       Fibonacci查找方法是根据Fibonacci数列的特点对查找表进行分割。Fibonacci数列的定义是:
        F(0)=0,F(1)=1,F(j)=F(j-1)+F(j-2) 。
若共有20(F(8)-1)个数, j=8,则mid= low+F(7)-1 =13
若key <a[13], 则low=1,high=12
下一步:j=7, mid= low+F(6)-1 =8
若key >a[13], 则low=14,high=20( F(8) -1)
下一步:j=6, mid=low+F(5)-1=18

1 查找思想

设查找表中的记录数比某个Fibonacci数小1,即设n=F(j)-1。用Low、High和Mid表示待查找区间的下界、上界和分割位置,初值为Low=1,High=n。

⑴ 取分割位置Mid:Mid=low+F(j-1)-1;

⑵ 比较分割位置记录的关键字与给定的K值:

① 相等: 查找成功;

② 大于:待查记录在区间的前半段(区间长度为F(j-1)-1),修改上界指针: High=Mid-1,转⑴ ;

③ 小于:待查记录在区间的后半段(区间长度为F(j-2)-1),修改下界指针:Low=Mid+1,转⑴ ;

直到越界(Low>High),查找失败。

算法实现

在算法实现时,为了避免频繁计算Fibonacci数,可用两个变量f1和f2保存当前相邻的两个Fibonacci数,这样在以后的计算中可以依次递推计算出。

int fib(int n)
{    int i, f , f0=0 , f1=1 ;
if (n==0)  return(0) ;
if (n==1)  return(1) ;
for (i=2 ; i<=n ; i++ )
{   f=f0+f1 ; f0=f1 ; f1=f ;   }
return(f) ;
}
int Fib_search(RecType ST[] , KeyType key , int n)
    /*  在有序表ST中用Fibonacci方法查找关键字为key的记录  */
{    int Low=1, High, Mid, f1, f2 ;
High=fib(n)-1 ; f1=fib(n-1) ; f2=fib(n-2) ;
while (Low<=High)
{   Mid=Low+f1-1;
                          if ( ST.[Mid].key==key )   return(Mid) ;
                          else if ( key<ST.[Mid].key) )
                                {   High=Mid-1 ; f2=f1-f2 ; f1=f1-f2 ;     }
                                 else
                                {   Low=Mid+1 ;f1=f1-f2 ; f2=f2-f1 ;  }
                      }
      return(0) ;
}

Fibonacci查找的时间复杂度也为O(logn)

平均性能,优于折半查找;但在最坏情况下性能比折半查找差。

折半查找需进行加法和除法运算;但Fibonacci查找只需进行加、减运算。

分块查找

分块查找(Blocking Search)又称索引顺序查找,是前面两种查找方法的综合。

1 查找表的组织

① 将查找表分成几块。块间有序,即第i+1块的所有记录关键字均大于(或小于)第i块记录关键字;块内无序。

② 在查找表的基础上附加一个索引表,索引表是按关键字有序的,索引表中记录的构成是

应用

分块索引兼顾了对细分块不需要有序的情况下,大大增加了整体查找速度,普遍应用于数据库表查找技术中。

算法实现
typedef struct IndexType
{ keyType  maxkey ;     /*  块中最大的关键字  */
   int startpos ;     /*  块的起始位置  */
}Index;
int Block_search(RecType ST[] , Index ind[] , KeyType key , int n , int b)
      /*  在分块索引表中查找关键字为key的记录 */
      /*表长为n ,块数为b */
{          int i=0 , j , k ;
while ((i<b)&&LT(ind[i].maxkey, key) )  i++  ;
if (i>b) {  printf("\nNot found");   return(0);  }
j=ind[i].startpos ;
while ((j<n)&&LQ(ST[j].key, ind[i].maxkey) )
{   if ( EQ(ST[j].key, key) )  break ;
j++ ;
}     /*  在块内查找  */
           if (j>n||!EQ(ST[j].key, key) )
               {  j=0; printf("\nNot found");  }
          return(j);
}
时间: 2024-08-12 13:35:12

数据结构 - 静态查找的相关文章

数据结构:静态查找表

数据结构:静态查找表(C语言版) 1.写在前面 ?从查找说起: 在英汉字典中查找某个英文单词的中文解释:在新华字典中查找某个汉字的读音.含义:在对数表.平方根表中查找某个数的对数.平方根:邮递员送信件要按收件人的地址确定位置等等. 从计算机.计算机网络中查找特定的信息,就需要在计算机中存储包含该特定信息的表.查找是许多程序中最消耗时间的一部分.因而,一个好的查找方法会大大提高运行速度. ?先讨论静态查找表: 静态查找表应该是查找中最为简单的.仅仅是在固定的表中对元素的查找,而不涉及修改表中的元素

数据结构算法C语言实现(三十二)--- 9.1静态查找表

一.简述 静态查找表又分为顺序表.有序表.静态树表和索引表.以下只是算法的简单实现及测试,不涉及性能分析. 二.头文件 1 /** 2 author:zhaoyu 3 date:2016-7-12 4 */ 5 #include "6_3_part1_for_chapter9.h" 6 typedef struct { 7 int key; 8 }SElemType; 9 //静态查找表的顺序储存结构 10 #define ElemType SElemType 11 #define K

看数据结构写代码(53) 静态查找表(线性查找,二分查找,斐波那契查找,插值查找)

查找定义:根据给定的某个值,在查找表中确定一个其关键字等于给定值的数据元素(或记录). 查找表分类:静态查找表和动态查找表. 静态查找表:只查找,而不进行插入,删除. 动态查找表:在查找过程中同时插入查找表中不存在的数据元素,或者从查找表中删除已经存在的某个数据元素. 静态表的 查找 大致 四种 算法: 线性查找,二分查找,斐波那契查找和插值查找. 其中 在线性查找之前,对表 无要求.对于 其余三种 需要 在查找之前 排序.插值查找 除了 需要 排序,还需要 均匀分布. 下面 给出代码: 线性查

静态查找表:顺序查找、折半查找、分块查找

引言: 除去各种线性和非线性的数据结构外.另一种在实际应用中大量使用的数据结构--查找表.查找表是由同一类型的数据元素构成的集合. 对查找表常常进行的操作有:1.查找某个"特定的"数据元素是否在查找表中:2.检索某个"特定的"数据元素的各种属性:3.在查找表中插入一个数据元素:4.从查找表中删去某个数据元素.对查找表仅仅作前两种统称为"查找"的操作,则称此类查找表为静态查找表. 若在查找过程中同一时候插入查找表中不存在的数据元素,或者从查找表中删

动态查找与静态查找的区分

1.静态查找 首先无论是静态查找还是动态查找,都要有查找的对象,也就是包含很多同类型数据的"表",这个"表"可以理解为一个由同类型数据元素组成的一个"集合",该集合可以用各种容器来存储,例如数组.链表.树等,我们统称这些存储数据的数据结构为--查找表.可见,查找表有时是我们传统意义的表,有时候是很复杂的一种结构. 静态查找就是我们平时概念中的查找,是"真正的查找".之所以说静态查找是真正的查找,因为在静态查找过程中仅仅是执行&

算法学习之查找算法:静态查找表(2)有序表查找

如果静态查找表是一个有序表,则可以使用折半查找. 折半查找的过程是:先确定待查记录所在的范围(区间),然后逐步缩小范围直到找到或找不到该记录为止.折半查找过程是以处于区间中间位置记录的关键字和给定值比较,若相等,则查找成功,若不等,则缩小范围,直至新的区间中间位置记录的关键字等于给定值或者查找区间的大小小于零时(表明查找不成功)为止. 关键字key与表中某一元素array[i]比较,有3种情况: 1.key==array[i],查找成功 2.key > array[i],待查找元素可能的范围是a

算法学习之查找算法:静态查找表(1)顺序表查找

引言: 对查找表一般的操作有:1.查询某个"特定的"数据元素是否在查找表中:2.检索某个"特定的"数据元素的各种属性:3.在查找表中插入一个数据元素:4.从查找表中删去某个数据元素. 静态查找表的操作只包括两种:1.查找某个"特定的"数据元素是否在查找表中:2.检索某个"特定的"数据元素的各种属性: 静态查找表又有四种表现形式:顺序表的查找.有序表的查找.静态树的查找.索引顺序表的查找. 静态查找涉及的关键字类型和数据元素类型

数据结构之查找

一.静态查找 顺序的查找 有序表查找 平均查找长度: 特点 1.折半查找 log(n+1)-1 只是适用于有序表,且限于顺序存储结构(线性链表无法进行折半查找.) 2.斐波那契查找 O(logn)平均性能比折半好,但最坏性能比折半差 分割时只需进行加减运算,适用于关键字均匀分布的表 对表长较大的顺序表,其性能比折半好 3.索引顺序表查找   二.动态查找   1.二叉排序树 左子树的值小于右子树的值(左小右大): 二叉链表作为二叉排序树的存储结构: 插入的节点一定是叶子节点: 二叉排序树的中序遍

数据结构之查找与排序

查找 静态查找:查找时,只查找读取 顺序表上查找 无序表上查找,设置位置0为岗哨,从后往前查找,查找长度为(n+1)/2 有序表上查找,使用二分查找,平均查找长度为 log2(n+1)-1 索引顺序表上查找,索引表将顺序表分别分割为若干块,顺序表按块有序,查找长度为 (n/s+s)/2+1 动态查找 二叉排序树:或为空树或具有下列性质: 1.若左子树不为空,则左子树上的所有结点的键值均小于它的根结点的键值, 2.若右子树不为空,则右子树上的所有结点的键值均小于它的根结点的键值, 3.根的左子树,