排序算法
2018-11-26 本文已影响6人
她即我命
"""
Python解释器的实现:
- CPython - C
- Jython - Java
- IronPython - C#
- PyPy - Python - JIT编译
排序
- 简单排序算法 - O(N**2):选择排序、插入排序、冒泡排序
- 高级排序算法 - O(N*log_2N):快速排序、归并排序、基数排序、堆排序
冒泡排序:
38 95 12 46 78 65 53 82
38 12 46 78 65 53 82 95
12 38 46 65 53 78 82
12 38 46 53 65 78
12 38 46 53 65
归并排序:
38 95 12 46 78 65 53 82
[38 95 12 46] [78 65 53 82]
[38 95] [12 46] [78 65] [53 82]
[38] [95] [12] [46] [78] [65] [53] [82]
[38 95] [12 46] [65 78] [53 82]
[12 38 46 95] [53 65 78 82]
[12 38 46 53 65 78 82 95]
快速排序 - 枢轴
38 95 12 46 78 65 53 82
[38 53 12 46 65] 78 [82 95]
[12] 38 [53 46 65] 78 82 [95]
12 38 [46] 53 [65] 78 82 95
sorted - TimSort
"""
import sys
class Person(object):
"""人"""
def __init__(self, name, age):
self.name = name
self.age = age
def __repr__(self):
return f'{self.name}: {self.age}'
# 9 1 2 3 4 5 6 7 8
# 9 2 3 4 5 6 7 8 1
# *前面的是位置参数 - 传参时只需要参数值对号入座即可
# *后面的是命名关键字参数 - 传参时必须书写为"参数名=参数值"格式
# 好的函数应该是没有副作用的(调用函数不会让函数的调用者受到任何影响)
def bubble_sort(origin_items, *, comp=lambda x, y: x > y):
"""冒泡排序 - 平方复杂度 - O(N**2)"""
items = origin_items[:]
for i in range(1, len(items)):
swapped = False
for j in range(0, len(items) - i):
if comp(items[j], items[j + 1]):
items[j], items[j + 1] = items[j + 1], items[j]
swapped = True
if not swapped:
break
return items
# 斐波拉切数列: 1 1 2 3 5 8 13 21 34 55
# 动态规划
def fib(num, temp={}):
"""斐波拉切数 - O(2**N)"""
if num in (1, 2):
return 1
try:
return temp[num]
except KeyError:
temp[num] = fib(num - 1) + fib(num - 2)
return temp[num]
"""
小孩爬楼梯 - 一次可以走1个或2个或3个台阶
有10级台阶,一共有多少种走法
"""
def factorial(num):
# 收敛条件 - 什么时候结束递归
if num in (0, 1):
return 1
# 递归公式 - 当前调用和递归调用之间的关系
return num * factorial(num - 1)
# 函数的递归调用 - 一个函数如果直接或者间接的调用了自身就称为递归调用
# 写递归调用的函数有两个关键点:
# 1. 收敛条件
# 2. 递归公式
def merge_sort(items, comp=lambda x, y: x <= y):
"""归并排序"""
if len(items) < 2:
return items[:]
mid = len(items) // 2
left = merge_sort(items[:mid], comp)
right = merge_sort(items[mid:], comp)
return merge(left, right, comp)
def merge(items1, items2, comp):
"""合并 - 将两个有序列表合并为一个有序列表"""
items = []
idx1, idx2 = 0, 0
while idx1 < len(items1) and idx2 < len(items2):
if comp(items1[idx1], items2[idx2]):
items.append(items1[idx1])
idx1 += 1
else:
items.append(items2[idx2])
idx2 += 1
items += items1[idx1:]
items += items2[idx2:]
return items
def main():
"""主函数"""
# items1 = [38, 95, 12, 46, 78, 65, 53, 82]
# print(merge_sort(items1))
# items2 = [
# Person('Hao', 38), Person('Wang', 25),
# Person('Zhang', 40), Person('Lee', 18)
# ]
# items3 = merge_sort(items2, comp=lambda x, y: x.age <= y.age)
# print(items2)
# print(items3)
# print(sys.getrecursionlimit())
for num in range(1, 121):
print(f'{num}: {fib(num)}')
if __name__ == '__main__':
main()