【问题标题】:Sorting a list that have n fixed segments already sorted in ascending order对已按升序排序的具有 n 个固定段的列表进行排序
【发布时间】:2018-06-23 14:33:33
【问题描述】:

问题如下:

由固定数量的小段 n 组成的列表 端到端,每个段已经是升序了。

我考虑过使用合并排序,如果基本情况等于 n,然后返回并合并它们,因为我们已经知道它们是排序的,但是如果我有 3 个段,它就行不通,因为我要除以 2 并且你不能将 3 个片段平均分成两部分。

另一种类似于归并排序的方法。所以我为每个段使用 n 个堆栈,我们可以识别 L[i] > L[i+1] 因为段是升序的。但是我需要 n 个比较来确定哪个元素先出现,而且我不知道在不使用另一个数据结构比较堆栈顶部的元素的情况下动态比较 n 个元素的有效方法。 此外,您应该使用问题特征(已排序的段)来获得比传统算法更好的结果。即复杂度小于 O(nlogn)。

如果你有一个想法,一个伪代码会很好。

编辑

一个例子是 [(14,20,22),(7,8,9),(1,2,3)] 这里我们有 3 个元素的 3 个段,即使这些段是排序的,整个列表不是。

附言() 是否只指出片段

【问题讨论】:

  • 问题到底是什么?你写的没有意义。为什么要对已经排序的列表进行排序?
  • @ichantz 添加了编辑
  • 所以你只需要在内部对每个segment-sublists进行排序?
  • @ichantz 确实,这就是我们的目标
  • 运行for 循环,使用sort() 方法对每个段进行排序。您使用什么语言? Java 为集合内置了排序方法。

标签: algorithm sorting


【解决方案1】:

我想你可能误解了归并排序。虽然通常你会在合并之前分成两半并对每一半进行排序,但实际上是合并部分构成了算法。您只需要在运行时合并。

[(14,20,22),(7,8,9),(1,2,3)]为例

第一次合并后你有[(7, 8, 9, 14, 20, 22),(1, 2, 3)]

第二次合并后你有[(1, 2, 3, 7, 8, 9, 14, 20, 22)]

l = [14, 20, 22, 7, 8, 9, 1, 2, 3]

rl = [] # run list
sl = [l[0]] # temporary sublist

#split list into list of sorted sublists
for item in l[1:]:
    if item > sl[-1]:
        sl.append(item)
    else:
        rl.append(sl)
        sl = [item]
rl.append(sl)
print(rl)

#function for merging two sorted lists
def merge(l1, l2):
    l = [] #list we add into
    while True:
        if not l1:
            # first list is empty, add second list onto new list
            return l + l2
        if not l2:
            # second list is empty, add first list onto new list 
            return l + l1
        if l1[0] < l2[0]:
            # rather than deleting, you could increment an index
            # which is likely to be faster, or reverse the list
            # and pop off the end, or use a data structure which
            # allows you to pop off the front
            l.append(l1[0])
            del l1[0]
        else:
            l.append(l2[0])
            del l2[0]

# keep mergins sublists until only one remains
while len(rl) > 1:
    rl.append(merge(rl.pop(), rl.pop()))

print(rl)

值得注意的是,除非这只是一个练习,否则最好使用所选语言使用的任何内置排序功能。

【讨论】:

    猜你喜欢
    • 2019-07-23
    • 2016-10-18
    • 1970-01-01
    • 2013-10-16
    • 2020-10-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多