2016-03-02 66 views
1

我对合并工作排序使用递归的Python合并的错误。 我找不到我犯的错误,总是得到错误的答案。 的代码如下:排序使用Python

def mergeSort(xlist): 
    print ('Splitting',xlist, len(xlist)) 
    if len(xlist)>1: 
     midpoint = len(xlist) // 2 
     left = xlist[:midpoint] 
     right = xlist[midpoint:] 
     print ('----------------------------') 
     mergeSort(left) 
     mergeSort(right) 

     print (left, 'r', right) 

     while len(right) >0: 
      left.append(right[0]) 
      right.remove(right[0]) 
      slot= len(left)-1 
      while slot >0: 
       if left[slot] < left[slot-1]: left[slot], left[slot-1] = left[slot-1], left[slot] 
       slot -= 1 

     print ('sorted',left, right,xlist) 
     return left 

print('A',mergeSort([100,1,91,54])) 

合并时,输出也示出了在以错误的方式,如:

Splitting [100, 1, 91, 54] 
---------------------------- 
Splitting [100, 1] 2 
---------------------------- 
Splitting [100] 1 
Splitting [1] 1 
[100] r [1] 
sorted [1, 100] [] [100, 1] 
Splitting [91, 54] 2 
---------------------------- 
Splitting [91] 1 
Splitting [54] 1 
[91] r [54] 
sorted [54, 91] [] [91, 54] 
[100, 1] r [91, 54] 
sorted [1, 54, 100, 91] [] [100, 1, 91, 54] 
A [1, 54, 100, 91] 

我期望的最后第三行应为“[1100] R [54 ,91]“之后回来。 这里有什么问题?我知道interactivePython.org中有一个代码,但我想知道我在哪里犯了逻辑错误。谁能帮我?一吨谢谢!

+0

如果'LEN(的Xlist)> 1'是不正确的,功能不执行任何操作,因此它返回无。这是故意的吗? –

+1

你的代码的后半部分并没有真正进行合并排序。附加到'left'不是合并 - 它依靠你的清理代码*低调地*按照正确的顺序排列列表。你已经有效地实现了一个** shell排序**的伪装合并排序。 –

回答

1

你需要决定你mergesort代码是否要修改它传递的列表到位,还是要返回新列表。代码的顶部部分被编写为就像它将修改列表一样。下半部分写成好像它返回一个新列表。他们都需要以相同的方式工作,否则排序不起作用。

如果你想坚持就地修改的方法,代码的顶部部分是没问题的,它只是合并leftright在最后你需要修复。而不是合并到left,您需要合并到xlist。我建议在每个列表中使用单独的索引,而不是像你目前正在做的那样在left中插入昂贵的代码。

如果你想返回一个新的列表,你需要改变代码的顶部。如果您遇到基本情况(len(xlist) < 2),则需要返回xlist未修改。您还需要从递归调用保存的返回值,也许left = mergesort(left)right = mergesort(right)。你后来合并代码可能是好的,但它丢弃大部分归并排序的性能优势,由于插入逻辑是O(N**2)

+0

其实我也想修改我的代码加入“的Xlist =左”恰到好处打印之前”(‘排序’,左,正确,xlist)“并删除”返回“。这是修改原地方法,但它仍然不起作用。 – Hsiang

+0

'xlist = left'不会修改'xlist'指向的列表,它只是重新绑定名称。你可以做'xlist [:] = left',但是直接将'left'和'right'的值合并到'xlist'中真的会更好(你当前的合并过程非常低效)。 – Blckknght

+0

谢谢!它现在有效。 xlist = left和xlist [:] = left有什么区别?另外感谢您的提醒,我目前的合并程序完全没有效率。 – Hsiang

0

我花了几分钟的时间,但我发现它。您在左侧&右侧正确地重复,但是然后您丢弃结果并合并原始列表。产品纠错:

print ('----------------------------') 
    left = mergeSort(left) 
    right = mergeSort(right) 

我希望你现在可以看到效果。


下面是产生上述输出的工作代码:

def mergeSort(xlist): 
    print 'Splitting', xlist, len(xlist) 
    if len(xlist) <= 1: 
     return xlist 
    else: 
     midpoint = len(xlist) // 2 
     left = xlist[:midpoint] 
     right = xlist[midpoint:] 
     print ('----------------------------') 
     left = mergeSort(left) 
     right = mergeSort(right) 

     print left, 'r', right 

     # print "merge", left, right 
     while len(right) > 0: 
      left.append(right[0]) 
      right.remove(right[0]) 
      slot = len(left) - 1 
      while slot > 0: 
       if left[slot] < left[slot-1]: 
        left[slot], left[slot-1] = left[slot-1], left[slot] 
       # print "switched", left 
       slot -= 1 

     print 'sorted', left, right, xlist 
     return left 

print 'A',mergeSort([100,1,91,54]) 

输出:

A Splitting [100, 1, 91, 54] 4 
---------------------------- 
Splitting [100, 1] 2 
---------------------------- 
Splitting [100] 1 
Splitting [1] 1 
[100] r [1] 
sorted [1, 100] [] [100, 1] 
Splitting [91, 54] 2 
---------------------------- 
Splitting [91] 1 
Splitting [54] 1 
[91] r [54] 
sorted [54, 91] [] [91, 54] 
[1, 100] r [54, 91] 
sorted [1, 54, 91, 100] [] [100, 1, 91, 54] 
[1, 54, 91, 100] 
+0

谢谢!但实际上我试图按照你的建议,它显示以下错误消息(我使用ipython): ..... mergeSort(xlist)中的 12 print(left ,'r',right) ---> 14 while len(right)> 0: 15 left.append(right [0]) 16 right。删除(右[0]) 类型错误:类型NoneType“的对象没有LEN() – Hsiang