查找(顺序、二分、斐波那契和插值)算法的实现和测试
来源:互联网 发布:中国洗脑 知乎 编辑:程序博客网 时间:2024/04/28 23:29
0. 快速开始
- 编程语言:python3.x (语言并不影响,但是为了方便说明,选择python来实现)
- 二分查找、斐波那契查找和插值查找的本质是一样的,但是每次选择的分割点不同。
- 二分查找:分割点是
length/2
(length是数据量大小) - 斐波那契查找:分割点根据斐波那契数列
- 插值查找:根据数据自身特点
- 二分查找:分割点是
1. 顺序查找
对于python来说,就是检索迭代器中的每一个元素是否与目标元素相同(一个
for
循环就可以搞定)。显而易见,时间复杂度是O(n)
。实现很简单,这里不贴代码(重点在后面)。
2. 二分查找
取中间记录作为比较对象,若给定值与中间记录的关键字相等,则查找成功;若给定值小于中间记录的关键字,则在中间记录左半区继续查找;否则,在右半区查找。不断重复,知道查找成功或者查找失败为止。毫无疑问,这样的查找是非常快的,达到
O(LogN)
的复杂度。
3. 斐波那契查找
不多说,直接上图:
需要注意的是,斐波那契数列越往后,两个值越接近黄金分割比。这种查找正事利用这种思想来平衡递归深度或者查找分割点的。
4. 插值查找
- 一般用于数据量较大的查找
- 缩小范围后,可以退到斐波那契查找或者二分查找
- 我们假设数据是均匀分布(你可以根据需要来手动设置分割点的规则),那么数据满足下面的规律:
5. 应用
一般来说,数据较多的时候,根据数据特点,可以采用插值查找,待数据量减小到某个值,可以采用斐波那契或者二分查找,当数据量确实很小的时候,可以直接采用顺序查找。
6. 代码实现
6.0 效果展示
6.1 查找类的代码
def fibonacci(max_num = 10000000): a,b = 0,1 while b<=max_num: yield b a,b = b,a+bclass AllSearch(object): __slots__ = ('obj','ele','_is_sort','name') def __init__(self): self.name = "AllSearch" def __str__(self): return "Include binary-search,fibonacci-search and insert-search " #优化 def setObj(self,obj): assert isinstance(obj, list) self._is_sort = False self.obj = obj def _sort(self): if not self._is_sort: self.obj = sorted(self.obj) self._is_sort = True def setElem(self,ele): self.ele = ele def binSearch(self): ''' 二分查找 :return: True:找到;False:找不到 ''' self._sort() low = 0 high = len(self.obj)-1 while low<=high: mid = (low+high)//2 # print(type(self.ele), type(self.obj[mid])) if self.obj[mid] == self.ele: return True elif self.obj[mid] > self.ele: high = mid - 1 else : low = mid+1 return False def fibSearch(self): ''' 斐波那契查找 :return: True:找到;False:找不到 ''' self._sort() fib_pos = [] for pos in fibonacci(len(self.obj)+1): fib_pos.append(pos) if (len(self.obj)+1) not in fib_pos: # 如果length != fib(k)-1 return self.binSearch() # 无法分割,调用二分查找 low = 0 high = len(self.obj)-1 index = len(fib_pos)-1 # 最后一个元素代表:max_num while low<=high: index-=1 if index<0: return False mid = low+fib_pos[index]-1 if self.obj[mid] == self.ele: return True elif self.obj[mid] > self.ele: high = mid-1 # k = k-1分支 else: index-=1 # k = k-2分支 low = mid +1 return False def insertSearch(self): ''' 差值查找(针对大数据) :return: True:找到;False:找不到 ''' if len(self.obj)<=100000: # 数据量太小,不需要调用插值查找 return self.fibSearch() self._sort() low = 0 high = len(self.obj)-1 last_mid = None while high-low>100000: mid = low + int((high-low)*((self.ele-self.obj[low])/(self.obj[high]-self.obj[low]))) if self.obj[mid] == self.ele: return True elif self.obj[mid]> self.ele: high = mid-1 else: low = mid+1 if mid==last_mid: # 防止死循环 break last_mid = mid self.setObj(self.obj[low:high+1]) # 下面只要检索low:high+1 区间即可。 return self.fibSearch()if __name__=='__main__': pass
6.2 测试代码
import timeimport randomfrom all_search import AllSearchif __name__=='__main__': searcher = AllSearch() test_times = 100 error_times = 0 for t in range(test_times): ele = random.randint(1, 1000000) searcher.setElem(ele) searcher.setObj([random.randint(1, 1000000) for i in range(105000)]) real = ele in searcher.obj bin = searcher.binSearch() fib = searcher.fibSearch() insert = searcher.insertSearch() if not real==bin==fib==insert: print("%d error"%t) error_times+=1 else: print("%d ok"%t) print("All error is %d times" % error_times)
阅读全文
0 0
- 查找(顺序、二分、斐波那契和插值)算法的实现和测试
- 查找算法小结:顺序查找、 二分查找、斐波那契查找 、插值查找
- 常见的查找算法(顺序、二分、插值、斐波那契查找,哈希查找)
- 查找(顺序查找、插值查找和斐波那契查找)
- 顺序查找:二分查找,斐波那契查找,插值查找
- 二分查找,插值查找,斐波那契查找
- 静态查找(顺序查找,折半查找,插值查找,斐波那契查找)
- 有序表查找(二分查找,插值查找,斐波那契查找)
- 【查找】二分查找、插值查找、斐波那契查找
- 折半查找、插值查找和斐波那契查找
- 有序向量:二分查找&斐波那契查找&插值查找
- 斐波那契数列和二分查找的算法(递归与非递归)
- 简单查找算法之折半查找、插值查找、斐波那契查找
- 查找算法集:顺序查找、二分查找、插值查找、动态查找(数组实现、链表实现)
- 查找算法集:顺序查找、二分查找、插值查找、动态查找(数组实现、链表实现)
- 查找算法集:顺序查找、二分查找、插值查找、动态查找(数组实现、链表实现)
- 查找算法集:顺序查找、二分查找、插值查找、动态查找(数组实现、链表实现)
- 查找算法集:顺序查找、二分查找、插值查找、动态查找(数组实现、链表实现,附代码)
- 机器学习_聚类分析_K-mens
- vux使用教程
- Java 消息中间件相关概念
- 算法之最大子串和
- linux之文件的打包、解压和传输
- 查找(顺序、二分、斐波那契和插值)算法的实现和测试
- 剑指05-栈和队列实现
- 存储远程复制技术
- 基于CentOS搭建Docker环境
- scrapy TypeError: parse() missing 1 required positional argument: 'response'
- 运用筛法思想解决其他题目。选太子(select the prince)和幸运的编号
- SQLite学习1_Windows下安装配置SQLite和使用的教程(1)
- Java 并发工具包 java.util.concurrent 用户指南
- springmvc的InternalResourceViewResolver自我理解