学完排序算法之后我们就要学习搜索啦,其中一个比较常见的就是二分查找,其实关于二分查找早就听说了,今天才正式学,好开心,终于学到这啦~~~先来说下二分查找算法的原理吧
原理概述
二分查找首先要求序列必须得是有序的,其次可以直接用下标索引的,所以也就是操作的时顺序表而不能是链表什么的
主要就是对于要查找的元素,先看该元素和表中间位置的元素相比是大是小,如果要查找的值比中间元素小,就把该元素继续在左半边查找,再对左半边取中间位置的元素,和要查找的值进行比较,决定是在左半边继续查找还是在右半边继续找,如果在查找过程中一旦发现元素相等的情况,立马return 即可,如果查找完所有的元素仍未发现要查找的值就返回false
知道了二分查找的原理之后我第一反应就是可以用快速排序的思想也就是用递归来写,我自己写的代码如下:
# -*- coding: utf-8 -*-
"""
Created on Tue May 29 14:48:05 2018
@author: xuanxuan
"""
#********************************************二分查找******************************************
def quick_sort(L,first,last):
n=len(L)
while first>=last:
return L
low,high=first,last
mid_value=L[first]
while low<high:
while low<high and L[high]>=mid_value:
high-=1
L[low]=L[high]
while low<high and L[low]<mid_value:
low+=1
L[high]=L[low]
L[low]=mid_value
quick_sort(L,first,low-1)
quick_sort(L,low+1,last)
return L
def binary_search(L,first,last,value=5): #默认查找5这个元素的索引
mid_index=(first+last)//2
if first>last:
print("查无此值!")
return False
if value<L[mid_index]:
binary_search(L,first,mid_index-1)
elif value>L[mid_index]:
binary_search(L,mid_index+1,last)
else:
print("需要查找的值在已排序列表中的索引为:",mid_index)
return
if __name__=="__main__":
L=[9,2,5,1,7,3,8,4]
print("排序之前的序列:",L)
L=quick_sort(L,0,7) #可以再给定需要查找的值~~
print("使用快速排序之后的序列:",L)
binary_search(L,0,7)
我首先用快排实现了原列表的排序,然后在使用二分查找算法。
嗯 ,看了一下老师的思路,觉得自己写的很魔幻。
*************************************二分查找(by_yeacher)*****************************
#第一种方法(采用递归的思想)
def binary_search(L,item): #要求L是有序序列
n=len(L)
mid=n//2
if n>=1:
if item<L[mid]:
return binary_search(L[:mid],item)
elif item>L[mid]:
return binary_search(L[mid+1:],item)
else:
return True
else:
return False
#第二种方法(采用非递归的方式有点类似于快速排序)
def binary_search_2(L,item):
n=len(L)
first,last=0,n-1
while first<=last:
mid=(first+last)//2
if item<L[mid]:
last=mid-1
elif item>L[mid]:
first=mid+1
else:
return True
return False
if __name__=="__main__":
print(binary_search([1,2,3,4,5,6,7,8],5))
print(binary_search([1,2,3,4,5,6,7,8],55))
print(binary_search_2([1,2,3,4,5,6,7,8],5))
print(binary_search_2([1,2,3,4,5,6,7,8],55))
嗯 还是有差距的,不过我也不知道我写出来的竟然有种老师两种方法的结合版??hhhhhh
时间复杂度
二分查找最快的时间复杂度是O(1) (也就是mid最中间位置对应的值就是要查找的值,一下就找到了)
二分查找最坏的时间复杂度为O(logn)因为需要折半查找每次除以2 知道最后一次就是只有一个值时才找到 (n–n/2—n/4—-1总共遍历了logn次 每一次只有一个比较 也就是每一次遍历的时间复杂度为O(1),总共遍历logn次)
与一般的顺序表利用索引查找值相比 最优的时间复杂度为O(1),最坏的时间复杂度为O(n)从前往后找找到最后一个才找到
啊啊啊啊,今天效率太低了啊,一直在玩手机,哼