蓝桥杯Python——day2快速排序

快速排序基本思想:分治

下面假设对nums数组排序, l为左边界, r为右边界

  1. 确定分界点:可以是nums[l]、nums[r]、nums[(l + r) >> 2],设为d
  2. 调整区间:将小于d的元素放到相对于大于d元素的左边,大于d的放在右边
  3. 递归处理左右两端
调整区间的两种方法
  1. 每次调整区间用三个列表存,left、mid、right,left存小于d的元素,mid存等于d的元素,right存大于d的元素,最后将这三个列表连接即可
    上代码:
	def quick_sort1(nums) :
	    if len(nums) <= 1 : return nums
	    left = []
	    mid = []
	    right = []
	    d = nums[len(nums) // 2]
	    for i in nums :
	        if i < d :
	            left.append(i)
	        elif i > d :
	            right.append(i)
	        else :
	            mid.append(i)
	    return quick_sort1(left) + mid + quick_sort1(right)
  1. 双指针法: 没啥好讲的,碰到左右两边都需要交换的话,换一下。
def quick_sort2(nums, l, r) :
    if l >= r :
        return
    i = l - 1###配合下面do while中先移位后运算的方法
    j = r + 1
    d = nums[l]
    while i < j :
        while True :###因为每次交换完后都要跳到上次交换后的下一位,所以要用do...while..
            i += 1
            if nums[i] >= d :
                break
        while True :
            j -= 1
            if nums[j] <= d :
                break
        if i < j :
            nums[i], nums[j] = nums[j], nums[i]
    quick_sort2(nums, l, j)
    quick_sort2(nums, j + 1, r)

例题:
给定一个长度为 n 的整数数列,以及一个整数 k,请用快速选择算法求出数列从小到大排序后的第 k 个数。

输入格式
第一行包含两个整数 n 和 k。

第二行包含 n 个整数(所有整数均在 1∼109 范围内),表示整数数列。

输出格式
输出一个整数,表示数列的第 k 小数。

数据范围
1≤n≤100000,
1≤k≤n
输入样例:
5 3
2 4 1 5 3
输出样例:
3

n, k = map(int, input().split())

nums = list(map(int, input().split()))

def quick_sort(nums, k) :
    d = nums[0]
    left = []
    mid = []
    right = []
    for i in nums :
        if i < d :
            left.append(i)
        elif i == d :
            mid.append(i)
        else :
            right.append(i)
    if len(left) >= k :
        return quick_sort(left, k)
    elif len(left) + len(mid) >= k :
        return d
    else :
        return quick_sort(right, k - len(left) - len(mid))

print(quick_sort(nums, k))
总结

记得大二上学期学数据结构就学过快排,到今天大三才弄得,真的觉得自己太不扎实了emo,说实话Python写代码真不习惯。循序渐进吧,一定要有自己思考和感悟,遇到问题一定要解决,不要好高骛远,不着边际。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值