我有一个快速排序错误与无限的rersrs

时间:2017-10-05 02:30:16

标签: python-3.x recursion quicksort

我遇到问题,我的快速排序功能不断重复三个功能中的最佳功能。我不知道为什么这样做,我需要帮助。我正在尝试为下个学期的编码课练习这个,这是去年我的朋友所做的任务之一,当我遇到这个错误时我失去了 这是我的快速排序功能:

def quick_sort ( alist, function  ):
    if len(alist) <= 1:
        return alist + []
    pivot, index = function(alist)
    #print("Pivot:",pivot)

    left = []
    right = []


    for value in range(len(alist)):
        if value == index:
            continue
        if alist[value] <= pivot:
            left.append(alist[value])
        else:
            right.append(alist[value])
    print("left:", left)
    print("right:", right)

    sortedleft = quick_sort( left, function )
    print("sortedleft", sortedleft)
    sortedright = quick_sort( right, function )
    print("sortedright", sortedright)

    completeList = sortedleft + [pivot] + sortedright

    return completeList

#main

alist = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]

x = quick_sort(alist, best_of_three)
print(x)

这是我最好的三个功能:

def best_of_three( bNlist, nine = False ):
   rightindex = 2
   middleindex = 1
   if nine == False:

      left = blist[0]
      rightindex = int(len(blist) - 1)
      rightvalue = int(blist[rightindex])
      middleindex = int((len(blist) - 1)/2)
      middlevalue = int(blist[middleindex])
      bNlist.append(left)
      bNlist.append(middlevalue)
      bNlist.append(rightvalue)
      BN = bNlist
      print("Values:",BN)
   left = bNlist[0]
   middle = bNlist[1]
   right = bNlist[2]

   if left <= middle <= right:
      return middle , middleindex
   elif left >= middle >= right:
      return middle, middleindex
   elif middle <= right <= left:
      return right, rightindex
   elif middle >= right >= left:
      return right, rightindex
   else:
      return left, 0

#main
bNlist = []
print('Best of Three')
blist = [54,26,93,17,77,31,44,55]
print("")
print( "List:   [54,26,93,17,77,31,44,55]" )
x, index = best_of_three(bNlist)

print("Pivot: ",x)
print("----------------------------")

我真的不知道为什么它会无限重复咒骂,

还有第三个函数叫做ninther

def ninther( bNlist ):


   stepsize = int(len(blist) / 9)
   left = 0
   middle = left + 2
   right = left + 2 * stepsize

   blist[left]
   blist[middle]
   blist[right]
   leftvalue = blist[left]
   rightvalue = blist[right]
   middlevalue = blist[middle]

   left2 = right + stepsize
   middle2 = left2 + 2
   right2 = left2 + 2 * stepsize

   blist[left2]
   blist[middle2]
   blist[right2]
   left2value = blist[left2]
   middle2value = blist[middle2]
   right2value = blist[right2]

   left3 = right2 + stepsize
   middle3 = left3 + 2
   right3 = left3 + 2 * stepsize

   blist[left3]
   blist[middle3]
   blist[right3]
   left3value = blist[left3]
   middle3value = blist[middle3]
   right3value = blist[right3]

   bN3list = []
   bN2list = []
   bNlist = []

   bNlist.append(leftvalue)
   bNlist.append(middlevalue)
   bNlist.append(rightvalue)

   bN2list.append(left2value)
   bN2list.append(middle2value)
   bN2list.append(right2value)

   bN3list.append(left3value)
   bN3list.append(middle3value)
   bN3list.append(right3value)

   BN3 = bN3list
   BN2 = bN2list
   BN = bNlist
   print("Ninter ")
   print("Group 1:", BN)
   print("Group 2:", BN2)
   print("Group 3:", BN3)

   x = best_of_three(bNlist, True)[0]
   c = best_of_three(bN2list, True)[0]
   d = best_of_three(bN3list, True)[0]
   print("Median 1:", x)
   print("Median 2:", c)
   print("Median 3:", d)

   bN4list = [x,c,d]
   print("All Medians:", bN4list)

   z = best_of_three(bN4list, True)


   return z[0], z[1]

#main

blist = [2, 6, 9, 7, 13, 4, 3, 5, 11, 1, 20, 12, 8, 10, 32, 16, 14, 17, 21, 46]
Y = ninther(blist)

print("Pivot", Y)
print("----------------------------")

我已经到处查看,我无法找出问题在哪里召唤最好的三个

1 个答案:

答案 0 :(得分:0)

总结:导致无限递归的主要错误是你没有处理best_of_three收到长度为2的列表的情况。第二个错误是best_of_three修改了您发送给它的列表。如果我更正了这两个错误,如下所示,您的代码就可以运行。

详细信息:best_of_three([1, 2])返回(2, 3),表示第三个索引的数据透视值为2,这是错误的。这会给出一个[1, 2]的左侧列表,然后在下一次递归quick_sort(left, function)调用时会产生完全相同的行为。

更一般地说,问题在于,对于长度为2的列表,从三个可能值中选择最佳索引的想法是不可能的,并且您还没有选择如何处理该特殊情况。

如果我将此特殊案例代码添加到best_of_three,则会处理长度为2的情况:

if len(bNlist) == 2:
    return bNlist[1], 1

功能best_of_three修改 bNlist。我不知道为什么你在这个函数中有bNlist.append(left)形式的行。

L = [15, 17, 17, 17, 17, 17, 17]
best_of_three(L)
print(L)  # prints [15, 17, 17, 17, 17, 17, 17, 54, 17, 55]

我删除了append行,因为best_of_three修改bNlist不太可能是你想要的,我不知道为什么那些行存在。但是,你应该问问自己,为什么他们会在那里开始。可能有一些我不知道的原因。当我这样做时,你计算的数量从未使用过,所以我也删除了计算这些数量的行。

然后我注意到你有代码

rightindex = 2
middleindex = 1
if nine == False:
    rightindex = int(len(blist) - 1)
    middleindex = int((len(blist) - 1)/2)
left = bNlist[0]
middle = bNlist[1]
right = bNlist[2]

这似乎没有任何意义,因为您将rightindexmiddleindex设置为其他值,但您仍然使用旧索引(分别为2和1)访问值。所以我删除了if nine == False块。再问一下,问问自己为什么要开始使用这个代码,也许还有其他一些方法可以修改它来解释我不知道的事情。

best_of_three的结果如下:

def best_of_three(bNlist):
    print(bNlist)
    if len(bNlist) == 2:
        return bNlist[1], 1
    rightindex = 2
    middleindex = 1
    left = bNlist[0]
    middle = bNlist[1]
    right = bNlist[2]

    if left <= middle <= right:
        return middle , middleindex
    elif left >= middle >= right:
        return middle, middleindex
    elif middle <= right <= left:
        return right, rightindex
    elif middle >= right >= left:
        return right, rightindex
    else:
        return left, 0

如果我使用它,你的代码不会无限递归,而是排序。

我不知道为什么你提到ninther,因为它似乎与你的问题无关。您应该编辑它以删除该代码。