查找(五元分区法)、排序算法(快排、归并)【Python】

import random


# 归并排序
def merge_sort(arr, start, end):
    if start >= end:
        return
    mid = (start + end) // 2
    merge_sort(arr, start, mid)
    merge_sort(arr, mid + 1, end)
    merge(arr, start, mid, end)


def merge(arr, start, mid, end):
    p1 = start
    p2 = mid + 1
    temp = []
    while p1 <= mid and p2 <= end:
        if arr[p1] > arr[p2]:
            temp.append(arr[p2])
            p2 += 1
        else:
            temp.append(arr[p1])
            p1 += 1
    while p1 <= mid:
        temp.append(arr[p1])
        p1 += 1
    while p2 <= end:
        temp.append(arr[p2])
        p2 += 1
    for i in range(len(temp)):
        arr[i + start] = temp[i]


# 基于快排查找
def quick_find(arr, start, end, k):
    p1 = start
    p2 = end
    while p1 != p2:
        while arr[p2] <= arr[start] and p2 > p1:
            p2 -= 1
        while arr[p1] >= arr[start] and p2 > p1:
            p1 += 1
        arr[p1], arr[p2] = arr[p2], arr[p1]
    arr[start], arr[p1] = arr[p1], arr[start]
    if p1 == k - 1:
        return arr[p1]
    elif p1 > k - 1:
        return quick_find(arr, start, p1 - 1, k)
    else:
        return quick_find(arr, p1 + 1, end, k)


# 快速排序
def quick_sort(arr, start, end):
    if start > end:
        return
    p1 = start
    p2 = end
    while p1 != p2:
        while arr[p2] >= arr[start] and p2 > p1:
            p2 -= 1
        while arr[p1] <= arr[start] and p2 > p1:
            p1 += 1
        arr[p1], arr[p2] = arr[p2], arr[p1]
    arr[start], arr[p1] = arr[p1], arr[start]
    quick_sort(arr, start, p1 - 1)
    quick_sort(arr, p1 + 1, end)


# 五元区分算法
def Select(arr, k):
    l = len(arr)

    if l < 75:
        merge_sort(arr, 0, l - 1)
        return arr[l - k]

    else:
        N = [arr[i:i + 5] for i in range(0, l - l % 5, 5)]
        M = []
        if l % 5 != 0:
            N.append(arr[l - l % 5:])

        for i in range(0, len(N)):
            merge_sort(N[i], 0, len(N[i]) - 1)
            M.append(N[i][len(N[i]) // 2])

        x = Select(M, len(M) // 2)

        S1, S2 = [], []
        for j in range(0, l):
            if arr[j] < x:
                S1.append(arr[j])
            else:
                S2.append(arr[j])

        if k <= len(S2):
            return Select(S2, k)
        else:
            return Select(S1, k - len(S2))


# 生成指定区间内指定数量的数组
def random_int_list(start, stop, length):
    start, stop = (int(start), int(stop)) if start <= stop else (int(stop), int(start))
    length = int(abs(length)) if length else 0
    random_list = []
    for i in range(length):
        random_list.append(random.randint(start, stop))
    return random_list


if __name__ == '__main__':
    # 输入
    # m, k = map(int, input("请输入个数和k:").split())
    # s = list(map(int, input("请输入整数:").split()))
    # arr = []
    # for i in range(m):
    #     arr.append(s[i])

    arr1 = random_int_list(0, 100, 153)
    arr2 = arr1.copy()
    k = int(input("请输入要查找的第几大的值:"))
    print("arr为:", arr1)

    merge_sort(arr1, 0, len(arr1) - 1)
    print("归并排序结果:", arr1)
    print('归并排序后第%d大的数为:' % k, arr1[len(arr1)-k])

    print("基于快排的查找:", quick_find(arr2, 0, len(arr2)-1, k))
    print('五元区分法查找:', Select(arr2, k))


 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值