python查找算法_Python实现常用查找与排序算法

查找算法

二分查找

importdoctestdefbinary_search(alist, item):""">>> alist=[1,3,4,7,11,18,29]

>>> binary_search(alist,1)

0

>>> binary_search(alist,7)

3

>>> binary_search(alist,18)

5

>>> binary_search(alist,31)"""binary_index= int(len(alist)/2)if alist ==[]:returnNoneelif alist[binary_index] >item:returnbinary_search(alist[:binary_index], item)elif alist[binary_index]

result= binary_search(alist[binary_index + 1:], item)return None if result is None else result + binary_index + 1

elif alist[binary_index] ==item:returnbinary_indexif __name__ == "__main__":

doctest.testmod(verbose=True)

排序算法

选择排序

原理:第一次从待排序的数据元素中选出最小(或最大)的一个元素,存放在序列的起始位置,然后再从剩余的未排序元素中寻找到最小(大)元素,然后放到已排序的序列的末尾。以此类推,直到全部待排序的数据元素的个数为零。

稳定性:不稳定

最差时间复杂度:O(n^2)

平均时间复杂度:O(n^2)

importdoctestdef select_sort(alist, reverse=False):""">>> alist = [1,7,4,8,6,9,2,5,3]

>>> select_sort(alist)

[1, 2, 3, 4, 5, 6, 7, 8, 9]

>>> select_sort(alist, reverse=True)

[9, 8, 7, 6, 5, 4, 3, 2, 1]"""alist=alist[:]defselect_sort_(alist, reverse):if alist ==[]:return[]

item= max(alist) if reverse elsemin(alist)

alist.remove(item)return [item] +select_sort_(alist,reverse)returnselect_sort_(alist, reverse)if __name__ == "__main__":

doctest.testmod(verbose=True)

冒泡排序

原理:依次比较相邻两个元素大小,交换两元素位置使之满足递增或递减关系,完成一次从序列头到序列尾部的过程称为一次冒泡,一次冒泡会产生最大或最小值于队列尾部,下一次冒泡序列长度减1,序列尾部的有序序列长度加1

稳定性:稳定

最差时间复杂度:O(n^2)

平均时间复杂度:O(n^2)

importdoctestdef bubbing_sort(alist, reverse=False):""">>> alist = [1,7,4,8,6,9,2,5,3]

>>> select_sort(alist)

[1, 2, 3, 4, 5, 6, 7, 8, 9]

>>> select_sort(alist, reverse=True)

[9, 8, 7, 6, 5, 4, 3, 2, 1]"""

defswap(alist, index1, index2):

temp=alist[index1]

alist[index1]=alist[index2]

alist[index2]=temppassalist=alist[:]for cnt in range(len(alist) - 1):for index1 in range(len(alist) - 1 -cnt):

index2= index1 + 1

if (alist[index1] > alist[index2] and reverse == False) or (alist[index1] < alist[index2] and reverse ==True):

swap(alist, index1, index2)returnalistif __name__ == "__main__":

doctest.testmod(verbose=True)

插入排序

原理:将序列元素依次插入到序列首部的有序序列中,即每个元素执行一次有序插入操作

稳定性:稳定

最差时间复杂度:O(n2)

平均时间复杂度:O(n2)

importdoctestdef insert_sort(alist, reverse=False):""">>> alist = [1,7,4,8,6,9,2,5,3]

>>> insert_sort(alist)

[1, 2, 3, 4, 5, 6, 7, 8, 9]

>>> insert_sort(alist, reverse=True)

[9, 8, 7, 6, 5, 4, 3, 2, 1]"""result= alist[:1]for val in alist[1:]:for sort_val inresult:if (val < sort_val and reverse == False) or (val > sort_val and reverse ==True):

result.insert(result.index(sort_val), val)break

else:

result.insert(len(result), val)returnresultif __name__ == "__main__":

doctest.testmod(verbose=True)

快速排序

原理:通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列

性质:不稳定

最差时间复杂度:O(n2)

平均时间复杂度:O(nlogn)

importdoctestimportcopyimportrandomdef quick_sort(alist, reverse=False):""">>> alist = [1,7,4,8,6,9,2,5,3]

>>> quick_sort(alist)

[1, 2, 3, 4, 5, 6, 7, 8, 9]

>>> quick_sort(alist, reverse=True)

[9, 8, 7, 6, 5, 4, 3, 2, 1]"""alist=copy.copy(alist)defquick_sort_(alist, reverse):if alist ==[]:return[]

dichotomy_index= random.randint(0, len(alist) - 1)

dichotomy_val=alist[dichotomy_index]

alist.pop(dichotomy_index)

left_list=[]

right_list=[]for val inalist:if (val >= dichotomy_val and reverse == True) or (val < dichotomy_val and reverse ==False):

left_list+=[val]else:

right_list+=[val]return quick_sort_(left_list, reverse) + [dichotomy_val] +quick_sort_(right_list, reverse)returnquick_sort_(alist, reverse)if __name__ == "__main__":

doctest.testmod(verbose=True)

归并排序

原理:将序列通过递归二分拆分到不可分,不可分的序列可以认为是有序序列,然后将两个有序序列合并为一个有序序列,直到整个序列变为一个有序序列

稳定性:稳定

最差时间复杂度:O(nlogn)

平均时间复杂度:O(nlogn)

importdoctestdef merger_sort(alist, reverse=False):""">>> alist = [1,7,4,8,6,9,2,5,3]

>>> merger_sort(alist)

[1, 2, 3, 4, 5, 6, 7, 8, 9]

>>> merger_sort(alist, reverse=True)

[9, 8, 7, 6, 5, 4, 3, 2, 1]"""

defmerger(a, b):

result=[]for n in range(len(a) +len(b)):if a ==[]:return result +belif b ==[]:return result +aelif (a[0] < b[0] and reverse == False) or (a[0] > b[0] and reverse ==True):

result+=[a.pop(0)]else:

result+=[b.pop(0)]returnresultdefmerger_sort_(alist):

contre_index= int(len(alist)/2)

left_list=alist[:contre_index]

right_list=alist[contre_index:]if len(left_list) >= 2:

left_list=merger_sort_(left_list)if len(right_list) >= 2:

right_list=merger_sort_(right_list)returnmerger(left_list,right_list)returnmerger_sort_(alist)if __name__ == "__main__":

doctest.testmod(verbose=True)

堆排序

原理:堆排序也是选择排序的一种,他是利用完全二叉树的结构,从而构造出最大堆或最小堆,将堆顶元素替换到堆尾,如此反复,从而构造出有序序列

稳定性:不稳定

最差时间复杂度:O(nlogn)

平均时间复杂度:O(nlogn)

importdoctestdef heap_sort(alist, reverse=False):""">>> alist = [1,7,4,8,6,9,2,5,3]

>>> heap_sort(alist)

[1, 2, 3, 4, 5, 6, 7, 8, 9]

>>> heap_sort(alist, reverse=True)

[9, 8, 7, 6, 5, 4, 3, 2, 1]"""A=alist[:]defperc_down(A, i, N):

Ai=A[i]defperc_down_(A, i, N):

temp=A[i]

child= i * 2 + 1

if child < N - 1 and ((A[child] < A[child + 1] and reverse == False) or (A[child] >= A[child + 1] and reverse ==True)):

child+= 1

if child < N and ((Ai < A[child] and reverse == False) or (Ai >= A[child] and reverse ==True)):

A[i]=perc_down_(A, child, N)else:

A[i]=Aireturntemp

perc_down_(A, i, N)defswap(A, a, b):

temp=A[a]

A[a]=A[b]

A[b]=tempfor n in list(range(int(len(A)/2)))[::-1]:

perc_down(A, n, len(A))for n in list(range(len(A)))[::-1]:

swap(A, 0, n)

perc_down(A, 0, n)returnAif __name__ == "__main__":

doctest.testmod(verbose=True)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值