python算法题记录

import random
import time
# 1 顺序查找  O(n)
def linear_search(li : list, val):
    for i, v in enumerate(li):
        if v == val:
            return i
    else:
        return None

# 2 二分查找 O(log(n))
def binary_search(li: list, val):
    left = 0
    right = len(li) - 1
    while left <= right:
        mid = (left + right) // 2
        if li[mid] == val :
            return mid
        elif li[mid] > val:
            right = mid - 1
        else:
            left = mid + 1
    return None

# 3 排序 冒泡排序 O(n^2)

# 4 选择排序 O(n^2)
def select_sort(li: list):
    for i in range(len(li)):
        min_loc = i
        for j in range(i+1, len(li)):
            # print(min_loc, j, li[min_loc], li[j])
            if li[j] < li[min_loc]:
                min_loc = j
        li[i], li[min_loc] = li[min_loc], li[i]
        # print(li)
    return li

# 5 插入排序 O(n^2)
def insert_sort(li: list):
    # print(li)
    for i in range(1, len(li)): # 摸到牌的下标
        j = i - 1 # 手里牌的下标
        tmp = li[i]
        while j >= 0 and li[j] > tmp :
            li[j+1] = li[j]
            j -= 1
        li[j+1] = tmp
        # print(i, tmp , li)
    return li

# 6 快速排序 O(nlog(n))
def quick_sort(li: list, left, right):
    def partition(li, left, right):
        tmp = li[left]
        while left < right:
            while left < right and li[right] >= tmp:
                right -= 1 # 左走一步
            li[left] = li[right] # 左 = 右
            while left < right and li[left] <= tmp:
                left += 1
            li[right] = li[left]
        li[left] = tmp
        return left
    # left = 0
    # right = len(li) - 1
    if left < right:
        mid = partition(li, left, right)
        quick_sort(li, mid+1, right)
        quick_sort(li, left, mid - 1)

    return li

# 7 堆排序
def heap_sort(li: list):
    def shift(li: list, low, high):
        '''
        :param li:
        :param low: 堆的根节点位置
        :param high:  堆的最后一个元素
        :return:
        '''
        i = low
        j = 2 * i + 1
        tmp = li[low]
        while j <= high :
            if j + 1 <= high and li[j+1] > li[j]:
                j += 1
            if li[j] > tmp:
                li[i] = li[j]
                i = j
                j = 2 * i + 1
            else:
                # li[i] = tmp
                break
        li[i] = tmp
    print(li)
    n = len(li)
    for i in range((n-2)//2, -1, -1):
        print(li, i, n - 1)
        shift(li, i, n - 1)
    print(li)
    for i in range((n-1), -1, -1): # i 堆的最后一个位置
        print(i, li[i])
        li[0], li[i] = li[i], li[0]
        shift(li, 0, i-1)
        print(li)
    # 8 topk O(nlog(k))
def topk(li:list, k):
    def shift(li: list, low, high):
        '''
        :param li:
        :param low: 堆的根节点位置
        :param high:  堆的最后一个元素
        :return:
        小根堆
        '''
        i = low
        j = 2 * i + 1
        tmp = li[low]
        while j <= high:
            if j + 1 <= high and li[j + 1] < li[j]:
                j += 1
            if li[j] < tmp:
                li[i] = li[j]
                i = j
                j = 2 * i + 1
            else:
                # li[i] = tmp
                break
        li[i] = tmp
    heap = li[0:k]
    for i in range((k - 2) // 2, -1, -1):
        shift(heap, i, k - 1)
    # 建堆
    for i in range(k, len(li) - 1):
        if li[i] > heap[0]:
            heap[0] = li[i]
            shift(heap, 0, k - 1)
    # 遍历
    for i in range(k-1, -1, -1):
        li[0], li[i] = li[i], li[0]
        shift(heap, 0, i - 1)
    return heap

# 9 归并排序 O(nlog(n))
def merge_sort(li, low, high):
    def merge(li, low, mid, high):
        i = low
        j = mid + 1
        ltmp = []
        while i <= mid and j <= high:
            if li[i] < li[j]:
                ltmp.append(li[i])
                i += 1
            else:
                ltmp.append(li[j])
                j += 1
        while i <= mid :
            ltmp.append(li[i])
            i += 1
        while j <= high :
            ltmp.append(li[j])
            j += 1
        li[low:high+1] = ltmp
    if low < high:
        mid = (low + high) // 2
        merge_sort(li, low, mid)
        merge_sort(li, mid+1, high)
        merge(li, low, mid, high)
    return li

# 10 希尔排序 O(nlog(n))
def shell_sort(li):
    def insert_sort_gap(li: list,gap):
        for i in range(gap, len(li)):  # 摸到牌的下标
            j = i - gap  # 手里牌的下标
            tmp = li[i]
            while j >= 0 and li[j] > tmp:
                li[j + gap] = li[j]
                j -= gap
            li[j + gap] = tmp
        return li
    d = len(li) // 2
    while d >= 1:
        insert_sort_gap(li, d)
        d //= 2
  

# 11 桶排序 O(n+k) O(n^2 k)  空间O(nk)
def bucket_sort(li: list, n=100, max_num=1000000):
    buckets = [[] for _ in range(n)]
    for var in li:
        i = min(var // (max_num // n), n-1)
        buckets[i].append(var)
        for j in range(len(buckets[i]) - 1, 0 ,-1):
            if buckets[i][j] < buckets[i][j - 1]:
                buckets[i][j], buckets[i][j - 1] = buckets[i][j - 1], buckets[i][j]
            else:
                break
    sorted_li = []
    for buc in buckets:
        sorted_li.extend(buc)
    return sorted_li

# 12 基数排序 O(kn)
def radix_sort(li:list):
    max_num = max(li)
    it = 0
    while 10 ** it <= max_num :
        buckets = [[] for i in range(10)]
        for v in li :
            digit = (v // 10 ** it) % 10
            buckets[digit].append(v)
        
        li.clear()
        for b in buckets:
            li.extend(b)
        it += 1
    return l


if __name__ == "__main__":
    l = list(range(10))
    random.shuffle(l)
    # print(l)
    start = time.perf_counter()
    # print(linear_search(l, 6))
    # print(binary_search(l, 6))
    # select_sort(l)
    # insert_sort(l)
    # quick_sort(l, 0, len(l) - 1)
    heap_sort(l)
    # print(l)
    end = time.perf_counter()
    print(end - start)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值