目录
归并排序
归并排序的思想
把一个无序序列从中间分开,知道每个字列表只剩下一个元素
然后再做合并,合并的过程中从小到大排序,课上老师讲的代码跑不通,还不知道哪里有问题,但是思想是理解了
跑不通但是理解了的代码
#总是报错,我也无语了
'''
def merge_sort(li):
n = len(li)
if n <= 1:
return li
mid = n // 2
#left采用归并排序后形成的有序的新的列表
left_list = merge_sort(li[:mid])
#right采用归并排序后形成的有序的新的列表
right_list = merge_sort(li[mid:])
#将两个有序的子系列合并为一个新的整体
#merge(left, right)
left_pointer, right_pointer = 0, 0
result = []
while left_pointer < len(left_list) and right_pointer < len(right_list):
if left_list[left_pointer] <= right_list(right_pointer):
result.append(left_list[left_pointer])
left_pointer += 1
else:
result.append(right_list[right_pointer])
right_pointer += 1
#退出循环的时候,把左列表或者右列表的剩余内容都加进去
result += left_list[left_pointer:]
result += right_list[right_pointer:]
return result
if __name__ == "__main__":
li = [54, 26, 93, 13, 77, 31, 55, 28]
print(li)
li = merge_sort(li)
print(li)
'''
'''
n = 9 n // 2 =4 时 left_li = merge_sort[54, 26, 93, 13]
n // 2 = 2时 left_li = merge_sort[54, 26]
n // 2 = 1时候 left_li = merge_sort[54]
n = 1 此时要把alist返回 即返回left_li = [54]
right_li = [26]
进入函数体之后,需要把两个列表进行合并,合并完之后是[26, 54]
返回result = [26, 54] left_li = merge_sort[54, 26] 的执行结果就是[26, 54]
然后返回上一级left_li = merge_sort[54, 26, 93, 13]中,进行right_li 的合并
right_li = merge_sort[93,17]
left_li = [93]
right_li = [17]
执行的结果为[17, 93]
然后将[26, 54] 和 [17, 93]进行合并
[17, 26, 54, 93]
继续执行,将[77, 31, 55, 28]这个列表进行切片操作之后,把整个过程重复以便,得到的结果为[28,31,55,77]
'''
跑通了且理解来了的代码
#先定义merge函数
def merge(L, R):
n = len(L) + len(R)
L.append(float("inf"))
R.append(float("inf"))
i = 0
j = 0
A = []
for k in range(0, n):
if L[i] <= R[j]:
A.append(L[i])
i = i+1
else:
A.append(R[j])
j = j+1
return A
#自定义merge_sort函数
def merge_sort(A):
l = len(A)
if l <= 1:
return A
else:
mid = l//2
print(mid)
left = merge_sort(A[0:mid])
right = merge_sort(A[mid:])
return merge(left, right)
if __name__ == "__main__":
li = [54, 26, 93, 13, 77, 31, 55, 28]
print(li)
li = merge_sort(li)
print(li)
#[13, 26, 28, 31, 54, 55, 77, 93]
常见算法的时间复杂度比较
二分查找
两个条件:(1)是已经排序好的序列;(2)支持索引,就是按顺序存放,也就是只能作用于顺序表
把有序列表从中间分开,mid =(第一个位置+列表最后一个位置) // 2 然后比较中间位置的数值和要查找的数值的大小
#二分查找的两个大前提:1、有序序列;2、顺序表
#递归版本
def binary_search(alist, item):
'''二分查找'''
n = len(alist)
if n > 0:
mid = n // 2
if alist[mid] == item:
return True
elif item < alist[mid]:
return binary_search(alist[:mid], item) #这里要返回一个结果!前面一定要有return
else:
return binary_search(alist[mid+1:], item)
return False
#非递归版本
def binary_search2(alist, item):
'''二分查找'''
n = len(alist)
first = 0
last = n-1
while first <= last:
mid = (first + last) // 2
if alist[mid] == item :
return True
elif alist[mid] > item:
last = mid - 1
else:
first = mid + 1
return False
if __name__ == "__main__":
li = [17, 20, 26, 31, 44, 54, 55, 77, 93]
print(binary_search(li, 20))
print(binary_search(li, 100))
print(binary_search2(li, 55))
print(binary_search2(li, 200))
'''
True
False
True
False
'''
#最优时间复杂度:O(1)
#最坏时间复杂度:O(logn)