查找分为静态查找和动态查找。
静态查找:不涉及插入删除操作,无需动态修改查找表
查找分为:线性结构(顺序、折半、分块)、树性结构(二叉搜索树、二叉平衡树、B+/B树)、散列结构散列表
查找的效率指标:平均查找长度:查找成功,与查找不成功.所有元素 中该元素查找概率*该元素查找次数之和。
顺序查找分为有序表的顺序查找、无序表的顺序查找
无序表的顺序查找:从头开始,挨个比较,查找成功就返回位置,已经到了表的另一端还没找到,则查找失败。(n+1)/2
有序表的顺序查找:查找成功的平均查找长度与无序表的顺序查找一样,查找失败的平均查找长度好于无需表,因为当查到i时发现key小于目标值,而i+1的key又大于目标值。所以查找失败,不用在查到表的另一端。有序表的线性表可是链式存储结构的。
折半查找:仅适用于有序的顺序表。线性表的顺序存储结构。log(n+1),判定树是平很二叉树,树的高度为log(n+1)
分块查找:块内元素无序,块间元素有序。索引表,按关键字有序排列,每个元素含有各块的最大关键字和第一个关键字的地址。
分块查找分两步:第一步:索引表中确定待查记录所在块,可以顺序查找或折半查找。
第二步:在块内顺序查找
分块查找最快的时候是 快内和快间都是折半查找,快的大小为根号下n.
散列表:线性表和树表的查找中,都是建立在比较之上的,查找效率取决于比较次数。
散列表的查找效率取决于:散列函数、处理冲突的方法、装填因子
散列表把一个查找表中的关键字映射成该关键字对应的地址函数,根据关键字而直接进行访问。查找的时间复杂度与元素个数无关,好的情况下是0(1)
冲突:散列函数有可能把两个不同的关键字映射到同一地址。
散列函数的构造方法:直接定址法,除留余数法(取一个不大于表长但是最接近或等于表长的质数p)等
处理冲突的办法:任何设计的散列函数都不能绝对的避免冲突。
开放地址法:线性探测法(容易出现同义词与非同义词之间的冲突(聚集))、平方探测法、再散列法(不易产生聚集)等
拉链表
模式匹配算法:
最简单的算法:从主串的第一个字符开始一次往后比较,直到主串和负串不匹配。从第2个字符在重新匹配。。。。依次类推。所以简单的模式匹配的最坏时间复杂度是0(主串长度*模式串长度)o(N*M)
改进的模式匹配(KMP)
用滑动窗口进行改进,next数组存储匹配失败,下次重新匹配的地方。时间复杂度o(n+m)
整个KMP的重点就在于当某一个字符与主串不匹配时,我们应该知道j指针要移动到哪?