当前位置: 首页 > 知识库问答 >
问题:

Quicksort函数不会产生预期的输出,但partition函数会产生(python)

南门鸿畴
2023-03-14

我必须在一个学校项目的“slice”对象上实现一个快速排序算法,该slice对象是一个具有:

  • “数据”字段(要排序的整个数组)
  • “左”和“右”字段(表示数组中切片子部分的索引

分区函数代码如下:

def partition (s, cmp, piv=0):
"""
Creates two slices from *s* by selecting in the first slice all
elements being less than the pivot and in the second one all other
elements.

:param s: A slice of is a dictionary with 3 fields :
          - data: the array of objects,
          - left: left bound of the slide (a position in the array),
          - right: right bound of the slice.
:type s: dict
:param cmp: A comparison function, returning 0 if a == b, -1 is a < b, 1 if a > b
:type cmp: function
:return: A couple of slices, the first slice contains all elements that are
         less than the pivot, the second one contains all elements that are
         greater than the pivot, the pivot does not belong to any slice.
:rtype: tuple

>>> import generate
>>> import element
>>> import numpy
>>> def cmp (x,y):
...    if x == y:
...       return 0
...    elif x < y:
...       return -1
...    else:
...       return 1
>>> t = numpy.array([element.Element(i) for i in [4,2,3,1]])
>>> p = {'left':0,'right':len(t)-1,'data':t}
>>> pivot = 0
>>> p1,p2 = partition(p,cmp,pivot)
>>> print(p1['data'][p1['left']:p1['right']+1])
[1 2 3 4]
>>> print(p2['data'][p2['left']:p2['right']+1])
[]
"""
#convenience variables to make the function easily readable.
left = s['left']
right = s['right']
swap(s['data'],right,piv)

j = left
for i in range(left,right+1):
    if (cmp(s['data'][i] , s['data'][right]) != 1 ):
        swap(s['data'],i,j)
        j += 1
s1 = {'data':s['data'],'left':left,'right':j-1}
s2 = {'data':s['data'],'left':j+1,'right':right}

return s1,s2

该函数的doctests不会失败,但是当调用quicksort递归函数时,分区函数的行为不会像预期的那样。quicksort函数的代码如下:

def quicksort_slice (s, cmp):
"""
A sorting function implementing the quicksort algorithm

:param s: A slice of an array, that is a dictionary with 3 fields :
          data, left, right representing resp. an array of objects and left
          and right bounds of the slice.
:type s: dict
:param cmp: A comparison function, returning 0 if a == b, -1 is a < b, 1 if a > b
:type cmp: function
:return: Nothing

>>> import generate
>>> import element
>>> import numpy
>>> def cmp (x,y):
...    if x == y:
...       return 0
...    elif x < y:
...       return -1
...    else:
...       return 1
>>> t = numpy.array([element.Element(i) for i in [4,5,1,2,3,8,9,6,7]])
>>> p = {'left':0,'right':len(t)-1,'data':t}
>>> quicksort_slice(p,cmp)
>>> print(p['data'])
[1 2 3 4 5 6 7 8 9]
"""

if s['left'] < s['right'] :
    s1,s2 = partition(s,cmp)
    quicksort_slice(s1,cmp)
    quicksort_slice(s2,cmp)
File "C:\Users\Marion\Documents\S2\ASD\TP\tp2_asd\src\sorting.py", line 148, in __main__.quicksort_slice
Failed example:
    print(p['data'])
Expected:
    [1 2 3 4 5 6 7 8 9]
Got:
    [8 2 1 3 7 4 9 5 6]

编辑:正如下面的一条评论所指出的,我简直忘了更新piv的值,在对函数的第一次调用之后,piv的值并不总是0。我还替换了:

for i in range(left,right+1):
if (cmp(s['data'][i] , s['data'][right]) != 1 ):
    swap(s['data'],i,j)
    j += 1

for i in range(left,right):
    if (cmp(s['data'][i] , s['data'][right]) != 1 ):
        swap(s['data'],i,j)
        j += 1
swap(s['data'],right,j)

共有1个答案

孙修德
2023-03-14

尝试关闭这个线程之前,只是意识到我需要一个答案来做这件事。解决方案由JasonHarper提供。正如jasonharper所指出的,我“总是使用索引为0的元素作为枢轴--即使0不在切片内”。

 类似资料:
  • 我尝试转换一个从Java转换程序获得的html文件。 如果我从“文件”/“打开”菜单中打开该文件,并从“文件类型”中选择“HTML”,则LibreOffice将正确显示该文件。 在本例中,我在编辑器中显示从LibreOffice呈现的网页。所以,现在我想把这个文件转换成odt文件。 创建的.odt文件,如果我直接用LibreOffice Writer打开它,将显示原始HTML,而我希望显示呈现的H

  • 这涉及https://stackoverflow.com/help/on-topic中的“软件算法”,在本例中是quicksort排序算法 这是一个来自https://www.hackerrank.com/challenges/quicksort1的练习编码问题(非竞争) 这里是我的分区代码(基于https://courses.cs.washington.edu/courses/cse373/13

  • 我正在尝试编写一个Python实用程序,将Oracle的RAW字节字符串(作为字符串)转换为Guid,反之亦然。我试图重用我在C#中构建的同一个实用程序中的算法,但是从同一个字节数组构造一个和一个会产生不同的Guid/UUID。它们是一样的,不是吗?我读过UUID只是一个更好的术语。 在C#中,我有一个字节数组,< code>byte_array如下所示: 在 Python 中,我有一个字节数组,

  • 假设我们有下面的Jade源码: - var title = 'yay' h1.title #{title} p Just an example 当 compileDebug 选项不是false, Jade 会编译时会把函数里加上 __.lineno = n;, 这个参数会在编译出错时传递给rethrow(), 而这个函数会在Jade初始输出时给出一个有用的错误信息。 function anonym

  • 我在下面有一个函数,它的目的是返回第一个索引,其中数据不是按升序排序的。如果对数据进行排序,它将只返回数组的长度。例如,{10,20,90,5,70}将返回3(90 测试用例:

  • 问题内容: 因此,我正在进行一些数值计算。我已经计算了一个只能通过数字计算的函数()的100,000个点,现在想使用来推导它。据我了解(doc),对于f(x),我可以给出以下参数:使它起作用。这就是我(打算做的)事情。 除非它不起作用。结果到处几乎(但不完全)为零。该错误由下面的代码摘要重现(sin ^ 2(x)的形状类似于我的原始函数): 结果令人失望: 如果我打印,则表明它确实不是完全为零: