二分查找及简单应用
2017-09-12 15:08
381 查看
二分查找
又称折半查找。优点:是比较次数少,查找速度快,平均性能好。
缺点:是要求待查表为有序表,且插入删除困难。
适用于不经常变动而查找频繁的有序列表。
过程:首先,假设表中元素是按升序排列,将表中间位置记录的关键字与查找关键字比较,如果两者相等,则查找成功;否则利用中间位置记录将表分成前、后两个子表,如果中间位置记录的关键字大于查找关键字,则进一步查找前一子表,否则进一步查找后一子表。重复以上过程,直到找到满足条件的记录,使查找成功,或直到子表不存在为止,此时查找不成功。
def BinarySearch(key, lst): lo = 0 hi = len(lst) - 1 while lo <= hi: mid = lo + (hi - lo)/2 if lst[mid] > key: hi = mid - 1 elif lst[mid] < key: lo = mid + 1 else: return mid return -1
简单应用
题目:找出一个序列(N个数)中三个相加和等于0的数,并打印。方法一:三层for循环——运行时间的增长数量级为立方级别:N3
def ThreeSum(l): N = len(l) results = [] for i in xrange(N): for j in xrange(i+1, N): for k in xrange(j+1, N): if l[i] + l[j] + l[k] == 0: results.append((l[i], l[j], l[k])) return results if __name__ == '__main__': print ThreeSum([1,2,3,4,5,6,-3,-7,-11]) ---------- 输出: [(-11, 5, 6), (-7, 1, 6), (-7, 2, 5), (-7, 3, 4), (-3, 1, 2)]
方法二:借助二分查找——运行时间的增长数量级为对数级别:N2logN
改进后的算法思想:当且仅当-(a[i]-a[j])在数组中时,才满足条件。
下面的代码会将数组排序并进行N(N-1)/2次二分查找,每次查找所需要的时间都和logN成正比。因此,总的运行时间和N2logN成正比。这个解法也使我们能够解决更大规模的问题。
def BinarySearch(key, lst): lo = 0 hi = len(lst) - 1 while lo <= hi: mid = lo + (hi - lo)/2 if lst[mid] > key: hi = mid - 1 elif lst[mid] < key: lo = mid + 1 else: return mid return def sum_3(l, BinarySearch): l = sorted(l)#先排序 N = len(l) results = [] for i in xrange(N): for j in xrange(i+1, N): if BinarySearch(-l[i]-l[j], l) > j: results.append((l[i], l[j], -l[i]-l[j])) return results if __name__ == '__main__': print sum_3([1,2,3,4,5,6,-3,-7,-11], BinarySearch) ---------- 输出: [(-11, 5, 6), (-7, 1, 6), (-7, 2, 5), (-7, 3, 4), (-3, 1, 2)]
目前数据规模较小,体现不出方法二的时间优势。接下来,我们再做一个测试,观察效果:
import time def ThreeSum(l): N = len(l) results = [] for i in xrange(N): for j in xrange(i+1, N): for k in xrange(j+1, N): if l[i] + l[j] + l[k] == 0: results.append((l[i], l[j], l[k])) return results def BinarySearch(key, lst): lo = 0 hi = len(lst) - 1 while lo <= hi: mid = lo + (hi - lo)/2 if lst[mid] > key: hi = mid - 1 elif lst[mid] < key: lo = mid + 1 else: return mid return def sum_3(l, BinarySearch): l = sorted(l)#先排序 N = len(l) results = [] for i in xrange(N): for j in xrange(i+1, N): if BinarySearch(-l[i]-l[j], l) > j: results.append((l[i], l[j], -l[i]-l[j])) return results if __name__ == '__main__': time_start = time.time() sum_3([i for i in xrange(-500, 500)], BinarySearch) time_end = time.time() print '方法一运行时间:'+str(time_end - time_start) time_start = time.time() ThreeSum([i for i in xrange(-500, 500)]) time_end = time.time() print '方法二运行时间:'+str(time_end - time_start)
输出:
方法一运行时间:0.558466911316 方法二运行时间:9.34502387047
相关文章推荐
- 循环语句的简单应用(二分查找、猜数字游戏)
- 二分查找的简单应用
- Can you solve this equation?(二分查找的简单应用)
- Can you solve this equation?(二分查找的简单应用)
- 20、二分查找的实现与应用
- 用php实现简单的二分查找
- C/C++:迭代器的简单二分查找
- 简单二分查找
- java简单算法(二分查找 冒泡排序 判断是否为素数)
- LintCode python 小白-简单题-457经典二分查找问题
- C语言编程中实现二分查找的简单入门实例
- 简单的猜数字游戏,二分查找,杨辉三角
- js基本算法:冒泡排序,二分查找的简单实例
- 二分查找应用-旋转数组
- 最简单的算法- 二分查找
- 二分法-二分查找的应用及三个经典例题
- 二分查找的应用
- 简单的二分查找
- 第一个算法-简单不容易的二分查找
- Split Array Largest Sum 二分查找应用 C实现