合并排序单词列表

时间:2016-04-18 00:32:16

标签: python algorithm sorting mergesort

我已经使用codereview上的帖子实现了mergesort算法。它在整数列表上工作得很好,但我认为需要一个更实际的应用程序。所以我下载了一个带有随机英文单词的文本文件,并尝试对它们进行排序。

然而它绝对没有。

save

我认为问题在于它处理的是列表而不是单个列表。此功能也无法知道排序的基础是什么。这是对的吗?

以下是我想要的方式

def merge_sort(seq):
    if len(seq) == 1:
        return seq
    else:
        # recursive step. Break the list into chunks of 1
        mid_index = len(seq) // 2
        left  = merge_sort( seq[:mid_index] )
        right = merge_sort( seq[mid_index:] )

    left_counter, right_counter, master_counter = 0, 0, 0

    while left_counter < len(left) and right_counter < len(right):
        if left[left_counter] < right[right_counter]:
            seq[master_counter] = left[left_counter]
            left_counter += 1
        else:
            seq[master_counter] = right[right_counter]
            right_counter += 1

        master_counter += 1

    # Handle the remaining items in the remaining_list
    # Either left or right is done already, so only one of these two
    #    loops will execute

    while left_counter < len(left):  # left list isn't done yet
        seq[master_counter] = left[left_counter]
        left_counter   += 1
        master_counter += 1

    while right_counter < len(right):  # right list isn't done yet
        seq[master_counter] = right[right_counter]
        right_counter   += 1
        master_counter  += 1

    return seq

1 个答案:

答案 0 :(得分:3)

正如您所发现的那样,问题是merge_sort无法知道排序的基础。您可以更改merge_sort以接收另一个参数,该参数返回序列中每个元素的键,就像sorted一样:

def merge_sort(seq, key=lambda x: x):

然后将比较更改为调用传递函数而不是直接比较元素:

if key(left[left_counter]) < key(right[right_counter]):
    seq[master_counter] = left[left_counter]
    left_counter += 1
else:
    seq[master_counter] = right[right_counter]
    right_counter += 1

最后将密钥传递给递归调用:

left  = merge_sort( seq[:mid_index], key )
right = merge_sort( seq[mid_index:], key )

通过这些更改,它可以按预期工作:

merge_sort([4, 6, 2, 1]) # [1, 2, 4, 6]
merge_sort(['foo', 'a', 'bar', 'foobar'], key=len) # ['a', 'bar', 'foo', 'foobar']

有一点需要注意的是,结果与sorted不一致,因为merge_sort不是stable

merge_sort(['foo', 'a', 'bar', 'foobar'], key=len) # ['a', 'bar', 'foo', 'foobar']
sorted(['foo', 'a', 'bar', 'foobar'], key=len) # ['a', 'foo', 'bar', 'foobar']