查找学习总结
一.线性表的查找
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)最好:O(log2n)--完全二叉树
(2)最坏:O(n) ---单支树
三. 散列表
之前的线性表和树表的查找方法,都是基于对所储存的关键字比较,而与存储的地址无关,当节点数很多时,查找时要与大量的无效节点进行比较,导致查找速度很慢。
如果我们在关键字和它存储的位置之间建立某种联系,那么在查找时直接按照这种关系找到关键字,这就是散列查找的思想。
(1)散列函数和散列地址:记录的存储位置p和其关键字key之间建立一一对应联系H使得 p=H(key),H称为散列函数,p称为散列地址。