【问题标题】:Python MergeSortPython 合并排序
【发布时间】:2019-05-14 03:56:57
【问题描述】:

我正在尝试实现 Python 合并排序,但在某些方面我失败了。我拥有的伪代码是准确的,但看起来它是为不同的语言构建的。

伪需要以下
/声明输入数组a大小的数组temp

我不确定这在 Python 中是如何实现的。无论如何,代码如下。 整个想法是我需要对数组/列表进行排序并返回排序后的。

到目前为止,它失败并显示以下消息。我会说这是因为新的临时数组/列表,但我不确定

Traceback (most recent call last):  
  File "./mergesort", line 56, in <module>  
    main()  
  File "./mergesort", line 52, in main  
    mergesortbase(array)  
  File "./mergesort", line 4, in mergesortbase  
    mergesort(num, 0, len(num)-1)  
  File "./mergesort", line 10, in mergesort  
    mergesort(num, low, mid)  
  File "./mergesort", line 10, in mergesort  
    mergesort(num, low, mid)  
  File "./mergesort", line 12, in mergesort  
    merge(num, low, mid, mid+1, high)  
  File "./mergesort", line 27, in merge  
    temp[k] = a[j]  
IndexError: list assignment index out of range  

注意:对代码进行全面修改无济于事,因为我需要使用确切的伪代码。

#!/usr/bin/python3.6

def mergesortbase(num):
    mergesort(num, 0, len(num)-1)


def mergesort(num, low, high):
    if low < high:
      mid = (low + high) // 2
      mergesort(num, low, mid)
      mergesort(num, mid+1, high)
      merge(num, low, mid, mid+1, high)

def merge(a, l1, u1, l2, u2):
# declare array temp of size of input array a
# Comment -- Not doable in Python to create array/list with specific size
    temp = []
    i = l1
    j = l2
    k = l1

    while (i <= u1 and j <= u2):
      if (a[i] <= a[j]):
         temp[k] = a[i]
         i = i + 1
      else:
         temp[k] = a[j]
         j = j + 1

      k = k + 1

    while ( i <= u2 ):
       temp[k] = a[i]
       k = k + 1
       i = i + 1

    while ( j <= u2 ):
       temp[k] = a[j]
       k = k + 1
       i = i + 1

    h = l1

    while ( h <= u2 ):
       a[h] = temp[h]
       h = h + 1


def main():
   array = [8, 5, 7, 1, 9, 3]
   mergesortbase(array)


if __name__ == "__main__":
  main()

【问题讨论】:

  • "注释 -- 在 Python 中无法创建具有特定大小的数组/列表" 当然,您可以在 python 中创建具有特定大小的列表。在这种情况下,您可以只使用.append,这将更加Pythonic

标签: python list mergesort pseudocode


【解决方案1】:

我很好奇你为什么不只使用 Python 的内置排序工具,sortsorted,这取决于你的需要。它可能比你自己滚动的东西更有效(除非你在数据集上使用特定的额外信息,这里似乎不是这种情况)。 可能您这样做是出于教育目的,在这种情况下可以随意忽略此段落,但如果您的意图只是为了对一些数据进行排序。

无论如何,您的具体问题似乎是如何“声明输入数组 a 大小的数组 temp”。

使用语句很容易做到:

temp = [0] * len(a)

以下成绩单显示了这一点:

>>> a = [1,2,3]
>>> temp = [0] * len(a)
>>> temp
[0, 0, 0]

你现在拥有的是:

temp = []

创建一个大小为零的列表,后跟:

temp[k] = a[i]

这总是会导致问题,因为没有 k 的值可以工作。


最重要的是,您的实际合并存在缺陷,因为您使用了不正确的变量来处理数组。您在逻辑上将某些项目绑定在一起,例如 i 与第一个数组部分,j 与第二个数组部分,但后来您违反了:

while ( i <= u2 ):  # i and u1 should be associated: while i <= u1:
   temp[k] = a[i]   # (no need for '()' in Python conditions by the way).
   k = k + 1
   i = i + 1

while ( j <= u2 ):
   temp[k] = a[j]
   k = k + 1
   i = i + 1        # j and u2 should be associated: j = j + 1

即使您修复了数组创建,上面的第二个循环也可能会导致问题。它将永远运行(或直到异常,以先到者为准),因为您正在检查 j 但永远不会更改它。但是,上述两项项都不正确,因此应予以修复。

一旦我将数组设置为正确的大小,进行这两项更改,并在排序前后打印出数组,看起来会好一些:

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

【讨论】:

  • @paxdiablo, k 被赋值为 l1,l1 的值是函数调用“merge(num, low, mid, mid+1, high)”中的“low”值
  • @Wael,如果您尝试使用它来索引一个零大小的数组,k 的值并不重要。我建议你先修复数组。
  • "用语句很容易做到:" 迂腐,在 Python 中不容易做到,因为 Python 没有变量声明。当然,伪代码可能不应该指代“声明”之类的东西,当然,我们都明白它在这种情况下的含义……但仍然
  • @paxdiablo ,我用“temp = a.copy()”复制了列表,但仍然失败,很难追查为什么它仍然失败,但无论如何,这就是我改变的。 temp = a.copy()。错误信息是 IndexError: list assignment index out of range
  • @Wael,查看更新,它解释了您的代码在哪里出轨。
【解决方案2】:

您的代码中有三个错误

  1. temp 没有初始化为任何大小,所以 k 总是给list assignment index out of range

  2. 用于将剩余元素 l1 添加到 u1 的第二个 while 循环只需要运行到 u1 而不是 u2:

  3. 将剩余元素从 l2 添加到 u2 的第三个 while 循环需要增加 j 而不是 i

    def merge(a, l1, u1, l2, u2):
        temp = [0]*len(a)
        i = l1
        j = l2
        k = l1
        while (i <= u1 and j <= u2):
            if (a[i] <= a[j]):
                temp[k] = a[i]
                i = i + 1
            else:
                temp[k] = a[j]
                j = j + 1
    
            k = k + 1
        while ( i <= u1 ):
            temp[k] = a[i]
            k = k + 1
            i = i + 1
        while ( j <= u2 ):
            temp[k] = a[j]
            k = k + 1
            j = j + 1
    
        h = l1
    
        while ( h <= u2 ):  
            a[h] = temp[h]
            h = h + 1
    

【讨论】:

  • 如何从中返回最终排序的数组?
  • @Wael 数组a 已经排序,可以直接在main函数中print(a)
  • 我不知道该说什么,你太棒了GGGGGGGG,谢谢你的帮助。我接受了你的回答
【解决方案3】:

你能复制输入数组吗?

temp = a.copy()

大小相同。

如果您想将 temp 中的所有元素初始化为某个值,请使用类似:

温度 = [0] * 长度(a)

【讨论】:

    【解决方案4】:

    看看这个,应该就能得到理解归并排序所需的答案

    MergeSort

    【讨论】:

      猜你喜欢
      • 2013-09-16
      • 1970-01-01
      • 2021-08-20
      • 2021-06-27
      • 2020-10-25
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多