在2D列表中的某个索引处使用快速排序

时间:2014-01-15 20:07:04

标签: python list sorting quicksort

我正在尝试使用快速排序来对索引[1]中的列表进行排序。这是一个学校项目所以我没有使用快速排序算法。 例如:

list = [[2, 5, 3],
        [2, 4, 9],
        [0, 9, 1],
        [1, 1, 1],
        [4, 7, 5]]

我希望能够做到这一点,按索引[1]排序:

quickSort(list)

output:

list = [[1, 1, 1],
        [2, 4, 9],
        [2, 5, 3],
        [4, 7, 5],
        [0, 9, 1]]

这是我的快速排序代码:

def quickSort(list):
    pivot = list[0][1]
    lesser = quickSort([x for x in list[0][1:] if x < pivot])
    greater = quickSort([x for x in list[0][1:] if x >= pivot])
    return lesser + [pivot] + greater

当我运行它时,我收到错误:

Traceback (most recent call last):
  File "<pyshell#6>", line 1, in <module>
    quickSort(list)
  File "<pyshell#5>", line 3, in quickSort
    lesser = quickSort([x for x in list[0][1:] if x < pivot])
  File "<pyshell#5>", line 2, in quickSort
    pivot = list[0][1]
TypeError: 'int' object is not subscriptable

我不知道为什么我会这样,因为list [0] [1] = 5.我也试过了:

def quickSort(list):
    pivot = list[0][1]
    lesser = quickSort([x for x in list[0][1] if x < pivot])
    greater = quickSort([x for x in list[0][1] if x >= pivot])
    return lesser + [pivot] + greater

但我得到了错误:T

raceback (most recent call last):
  File "<pyshell#12>", line 1, in <module>
    quickSort(list)
  File "<pyshell#11>", line 3, in quickSort
    lesser = quickSort([x for x in list[0][1] if x < pivot])
TypeError: 'int' object is not iterable

所以我不太确定我做错了什么,所以任何帮助都会非常感激。

修改 @sweeneyrod 所以这就是我根据你的提示写的:

def quicksort(lis):
    if len(lis) <= 1:
        return lis
    else:
        pivot = lis[0][1]
        less = quicksort([i for i in lis[1:] if i[1] <= pivot])
        more = quicksort([i for i in lis[1:] if i[1] > pivot])
        return less + [pivot] + more

然后我用上面的列表运行它,但这就是我得到的:

[[1, 1, 1], 4, 5, [4, 7, 5], 9]

我没有正确地做某事吗?

3 个答案:

答案 0 :(得分:3)

首先,你需要一个基本案例(你不会对quicksort进行任何调用。在快速排序中,这种情况通常是一个包含一个或零个元素的列表。

以下是整数列表的快速排序实现:

def quicksort(lis):
    if len(lis) <= 1:
        return lis
    else:
        pivot = lis[0]
        less = quicksort([i for i in lis[1:] if i <= pivot])
        more = quicksort([i for i in lis[1:] if i > pivot])
        return less + [pivot] + more

由于这是家庭作业,我现在将其转换为在列表列表中运行的功能作为练习。

提示 - 您只需要更改三个部分:

pivot = lis[0]
if i <= pivot
if i > pivot

答案 1 :(得分:1)

您的第一个问题是您要对list的成员进行排序,但实际上您正在对list[0]的成员进行排序。这些成员是整数,而不是列表,因此您无法将它们编入索引。而且,更重要的是,它们不是你想要排序的东西。

所以,让我们先解决一下:

def quickSort(list):
    pivot = list[0]
    lesser = quickSort([x for x in list[1:] if x[1] < pivot[1]])
    greater = quickSort([x for x in list[1:] if x[1] >= pivot[1]])
    return lesser + [pivot] + greater

现在你的TypeError消失了,但你刚刚遇到一个新问题。在每一步,你都将列表减半,以分割你的工作。这意味着最终你会得到一个元素的列表。这意味着lessergreater将为空。如果您使用空列表调用quickSort会发生什么?它会立即尝试list[0][1],这是一个显而易见的IndexError

那么,你如何排序一个空列表?这很容易:它已经排序了。所以:

def quickSort(list):
    if not list:
        return list
    pivot = list[0]
    lesser = quickSort([x for x in list[1:] if x[1] < pivot[1]])
    greater = quickSort([x for x in list[1:] if x[1] >= pivot[1]])
    return lesser + [pivot] + greater

以下是它运行的一个例子:

list = [[2, 5, 3],
        [2, 4, 9],
        [0, 9, 1],
        [1, 1, 1],
        [4, 7, 5]]

print(quickSort(list))

输出结果为:

[[1, 1, 1], [2, 4, 9], [2, 5, 3], [4, 7, 5], [0, 9, 1]]

答案 2 :(得分:1)

试试这个,然后检查一下需要改变什么才能让它发挥作用:

def quick_sort(lis):
if len(lis) <= 1:
    return lis
else:
    pivot = lis[0][1]
    less = quicksort([i for i in lis[1:] if i[1] <= pivot])
    more = quicksort([i for i in lis[1:] if i[1] > pivot])
    return less + [pivot] + more