查找学习总结

一.线性表的查找

   1.顺序查找

       顺序查找是从表的一段开始,依次将记录的关键字和给定的值进行比较,若某个记录的关键字和给定的值相同,则查找成功,反之,若扫描整个表之后,还未发现关键字和给定值

      相等的记录,则查找失败。

      书中给了两个算法。

      7.1

int search_seq(ssTable ST,Keytype  key)
{
for (i=ST.length;i>=1;i--)
   if(ST.R[i].key==key)  return i;
return o;
}


int search_seq(ssTable ST,Keytype  key)
{
ST.R[0]=key;
for (i=ST.length;ST.R[i].key!=key;i--)
  return i;
}

    第二个算法是第一个的改进,去掉了每次循环都要对i>=0的判断,从而减少了时间。但两个算法的所需的时间都取决于n的大小 ,时间复杂度都是O(n)。

   优点:算法简单,对表的结构无要求。

   缺点:平均查找长度大,效率低,当n值非常大时,顺序查找效率很低。

 2.折半查找

     搜索过程从数组的中间元素开始,如果中间元素正好是要查找的元素,则搜索过程结束;如果某一特定元素大于或者小于中间元素,则在数组大于或小于中间元素的那一半中查找,而且跟开始一样从中间元 素开始比较。如果在某一步骤数组为空,则代表找不到。这种搜索算法每一次比较都使搜索范围缩小一半。

  复杂度:T(n)=O(log2(n)),S(n)=O(1)  

  在处理无序储存的数据时,要先对数据进行排序使用快排的时间复杂度O(nlog2(n)),所以总的时间复杂度为T(n)=O(nlog2(n))+O(log2(n))取最高次=O(nlog2(n))。

  优点:比较次数少,查找效率高.

  缺点:只能用于顺序存储结构,查找的对象必须是有序数组。在处理无序数据要先排序,会浪费时间。而且为了保证数据的顺序,在插入和删除平均比较和移动一半的元素,这也会消耗大量时间,难以进行动态查找。其次,在数据量超出内存所能提供的连续空间时,二分查找无法进行。

二.树表的查找

 1.二叉排序树

 

(1)若左子树不空,则左子树上所有节点的值均小于它的根节点的值;

 

(2)若右子树不空,则右子树上所有节点的值均大于它的根节点的值;

 

(3)左、右子树也分别为二叉排序树;
  不同插入次序生成结果不同

    (1)最好:O(log2n)--完全二叉树

    (2)最坏:O(n)  ---单支树

三.   散列表

 之前的线性表和树表的查找方法,都是基于对所储存的关键字比较,而与存储的地址无关,当节点数很多时,查找时要与大量的无效节点进行比较,导致查找速度很慢。

 如果我们在关键字和它存储的位置之间建立某种联系,那么在查找时直接按照这种关系找到关键字,这就是散列查找的思想。

(1)散列函数和散列地址:记录的存储位置p和其关键字key之间建立一一对应联系H使得 p=H(key),H称为散列函数,p称为散列地址。

散列查找的主要研究问题:
1.如何构造散列函数。
(1)数字分析法
(2)平方取中法
(3)折叠法
(4)除留余数法
 
2.如何避免冲突。
(1)开放地址法
        1.线性探测法
        2.二次探测法
(2)链地址法
 
 

 

posted @ 2019-06-02 21:25  反派死于话多  阅读(167)  评论(0编辑  收藏  举报