排序算法

"""
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()

你可能感兴趣的:(排序算法)