6.1顺序查找
顺序查找
int seq_search(Table T,Elem key){//顺序没有可从前往后,从后往前 for(int i=0;key!=T[i];i++) //顺序结构的Table;可链式结构 return i; }
平均查找长度
对于n个单元的表,给定key与表中第i个关键字相等,需比较i次;
ASL_success=1/n*(1+2+…+n)=n+1/2;
优点:对数据元素存储的方式没要求,顺序或链式存储结构;对表中数据可以为无序;
缺点:当n较大时,平均查找长度较大,效率低;
注:链表只能顺序查找
6.2折半查找
折半查找&二分查找,只用于已排序序列。
int binary_search(SeqTable T,Elem key){ int low=0,high=T.len-1,mid; while(low < high){ mid = (low+high)/2; //向下取整 if(T[mid]<key) low=mid+1; else if(T[mid]>key) high=mid-1; else return mid; } }
折半查找的时间复杂度为O(log_2{n}),平均情况比顺序查找效率高;
平均查找长度:ASL=1/n(1x1+2x2+…+hx2^h-1)
平均查找成功长度和平均查找失败长度(⭐️)
会画折半查找的判定树,王道p243.
n个元素的有序表,的判定树的高度向上取整log_2{n+1}
注:二分查找的存储结构必须具有随机存取的特性,故只用于线性表的顺序存储结构,即只用于顺序表,不适合链表。且要求有序,小到大,或大到小影响算法的mid移动。
6.3分块查找(不考)
分块查找又称索引顺序查找,集合了顺序查找和折半查找,将表分块,索引表顺序存储块中最大或最小关键字,将块有序排列;
分块查找先在索引表折半查找找到指定块,再在块中顺序查找指定关键字;
6.4 散列表(HashTable)
注:一篇博文,散列表的概念和实现,链接:https://blog.csdn.net/lin1094201572/article/details/89111958
散列表的查找的效率取决于比较的次数;
散列表中散列函数为核心,用于将关键字映射到对应地址的函数,Hash(key)=address;
那么问题来了,若两个或以上关键字映射到相同地址呢,这种问题叫做冲突,冲突的关键字为同义词,冲突不可避免,故我们需要解决冲突;
解决冲突的办法有:开放地址法、拉链法;
1.Hash函数的构造
散列函数应满足1)包含所有关键字;2)地址等概率、均匀分布;3)简单,计算快;
常用散列函数:
1.直接定址法:H(key)=a*key+b;不会造成冲突,但造成存储空间浪费;
2.除留余数法:H(key)=key%p;p小于表长;
3.数字分析法;4.平方取中法;5.折叠法;
2.处理冲突的方法
1.开放地址
1)线性探测法;2)平方探测法;3)再散列法;
2.拉链法
采用线性链表存储所有关键字,每一链表由一地址标识;适用于经常插入和删除的情况;
3.散列表查找及性能分析
决定散列表的查找效率的因素:散列函数、处理冲突的方法、装填因子;
装填因子:a=表中记录数/表长;
散列表的平均查找长度依赖于装填因子;还会受到堆积(聚集)现象的影响;