如何为单个列表构建合并排序,对列表"列表进行排序"代替?

时间:2017-10-21 05:01:31

标签: python

所以,假设我有一个这样的列表列表:

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

如果我想按每个子列表中的中间数字对其进行排序,它最终会像这样:

[[3, 5, 7],[2, 7, 9],[2, 8, 9],[0, 9, 8]]

如何构建用于对列表进行排序的合并排序:

[1,2,3,4]

要对列表进行排序并根据每个子列表的中间数指定要合并的列表? python是否有一个技巧可以让它工作?我唯一能找到的就是使用内置的排序功能,我不想这样做。

以下是我正在实施的合并排序。它像这样工作

归并(list_here)

它合并了列表。但是,我想使用一个技巧来根据列表列表进行python合并,而不是每个子列表的中间索引都是比较的。

感谢您提供任何指导。以下是合并排序:

def mergeSort(list_num):
    mergeSort2(list_num, 0, len(list_num)-1)


def mergeSort2(list_num, first, last):
    if first < last:
        middle = (first+last)//2
        mergeSort2(list_num, first, middle)
        mergeSort2(list_num, middle+1, last)
        merge(list_num, first, middle, last)


def merge(list_num, first, middle, last):
    L = list_num[first:middle+1]
    R = list_num[middle+1:last+1]
    L.append(sys.maxsize)
    R.append(sys.maxsize)
    i = j = 0

    for k in range(first, last+1):
        if L[i] <= R[j]:
            list_num[k] = L[i]
            i += 1
        else:
            list_num[k] = R[j]
            j += 1

2 个答案:

答案 0 :(得分:1)

这是您的代码版本,可以接受关键功能,例如内置的sort和相关功能。

我使用max来创建&#34; sentinel&#34;值。这是相当低效的,因为max必须扫描整个列表以找到它的最大值。此外,内置sort仅对其排序列表中的每个项目调用一次键函数,而此代码每次进行比较时都必须调用它两次。

def mergeSort(list_num, key=None):
    mergeSort2(list_num, 0, len(list_num)-1, key=key)

def mergeSort2(list_num, first, last, key=None):
    if first < last:
        middle = (first+last)//2
        mergeSort2(list_num, first, middle, key=key)
        mergeSort2(list_num, middle+1, last, key=key)
        merge(list_num, first, middle, last, key=key)

def merge(list_num, first, middle, last, key=None):
    if key is None:
        key = lambda x: x

    L = list_num[first:middle+1]
    R = list_num[middle+1:last+1]
    sentinel = max(list_num, key=key)
    L.append(sentinel)
    R.append(sentinel)
    i = j = 0

    for k in range(first, last+1):
        if key(L[i]) <= key(R[j]):
            list_num[k] = L[i]
            i += 1
        else:
            list_num[k] = R[j]
            j += 1

# Test

lst = [3, 1, 4, 6, 5, 2]
print(lst)
mergeSort(lst)
print(lst)

lst = [[0, 9, 8], [1, 7, 9], [2, 8, 9], [3, 5, 7]]
print(lst)
mergeSort(lst, key=lambda x: x[1])
print(lst)

<强>输出

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

正如您所看到的,它可行,但最好更改合并算法以消除哨兵,因此我们不需要max

我们还可以通过对数据执行Schwartzian transform来提高效率,这样每个项目只需要调用一次键函数,但这会使代码变得更复杂,当然它还需要更多RAM来保存转换后的数据。

答案 1 :(得分:0)

如果您理解正确,则可以使用以下代码:

FacesContext.getCurrentInstance().getExternalContext().redirect("../../faces/index.xhtml");

其中l是您的输入列表。