【问题标题】:QuickSort by different values按不同值快速排序
【发布时间】:2021-09-28 09:38:23
【问题描述】:

你好!我有一个这样的列表:

list_ = [["a", 1],
    ["b", 3],
    ["c", 2],
    ["d", 2]]

我想每隔一个元素对其进行排序,我可以使用快速排序来做到这一点。

def partition(a, low, high):
    i = low - 1
    pivot = a[high][1]
        
    for j in range(low, high):
        
        if a[j][1] >= pivot:
            i += 1
            a[i], a[j] = a[j], a[i]

def quicksort_inplace(a, low=0, high=None):
    if high is None:
        high = len(a) - 1
    if low < high:
        p_idx = partition(a, low, high)
        quicksort_inplace(a, low, p_idx - 1)
        quicksort_inplace(a, p_idx + 1, high)
    
    return a

问题。我知道如何一次对一个项目进行排序,但我不明白如何对我的列表进行排序,以便如果有相同的项目,则按字母顺序(按第一项)进行排序。

在:

[
    ["a", 1],
    ["b", 3],
    ["c", 2],
    ["d", 2]
]

出局:

[
    ["b", 3],
    ["d", 2]
    ["c", 2],
    ["a", 1],
]

【问题讨论】:

  • a[j][1] == pivot 时,您不想将所有元素放在分区的同一部分。而是将它们划分为列表的第一个元素。
  • 您的示例也显示了第一项的字母排序的相反顺序。这是您想要的结果,还是您当前算法提供的错误输出?
  • P.S.我希望您只是将其作为一个学习练习,因为您永远无法击败内置的 Python 排序。

标签: python-3.x algorithm sorting quicksort


【解决方案1】:

您可以调整您的枢轴值和比较函数来执行您想要的任何逻辑,但是,通常情况下,您正在寻找“lexographic”顺序。 幸运的是,python 已经用列表和元组为您实现了这个逻辑,比较第一个元素,如果相等,则转到下一个,然后再确定哪个更大。

只是使用

pivot = a[high]
...
if a[j] < pivot:

将首先比较字符串,然后是数字。但是,您想要另一个顺序,并且除此之外,您还想要颠倒数字。

最简单的方法就是创建一个您可以排序的key

pivot = (-a[high][1], a[high][0]) # reversed number first, then ordinary letter.
...
if (-a[j][1], a[j][0]) < pivot:

当然,我们也可以在正常的排序例程中使用key

sorted(list_, key=lambda x: (-x[1], x[0]))
list_.sort(key=lambda x: (-x[1], x[0]))

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-05-18
    • 2021-07-14
    • 1970-01-01
    • 2012-11-21
    • 2023-03-03
    相关资源
    最近更新 更多