过去几个小时我一直在看这个,但仍然无法理解我搞砸了哪里。我一直在索引超出范围的错误,如下所示:
我完成的每个小编辑或更改都让我遇到了另一个错误,然后我在尝试简化代码后再回到这里。
def quickSort(alist):
firstList = []
secondList = []
thirdList = []
if(len(alist) > 1):
#pivot = pivot_leftmost(alist)
#pivot = pivot_best_of_three(alist)
pivot = pivot_ninther(alist)
#pivot = pivot_random(alist)
for item in alist:
if(item < pivot):
firstList.append(item)
if(item == pivot):
secondList.append(item)
if(item > pivot):
thirdList.append(item)
sortedList = quickSort(firstList) + secondList + quickSort(thirdList)
return sortedList
else:
print("list:", alist)
print("sorted, nothing to do") #debug
print("") #debug
return alist
def pivot_ninther(alist):
listLength = int(len(alist))
third = int(listLength / 3)
leftList = alist[:third]
midlist = alist[third:(third * 2)]
lastlist = alist[(third * 2):(third * 3)]
leftBest = pivot_best_of_three(leftList)
midBest = pivot_best_of_three(midlist)
lastBest = pivot_best_of_three(lastlist)
pivots = [leftBest, midBest, lastBest]
return pivot_best_of_three(pivots)
我很确定一副新鲜的眼睛很容易找到它,但我已经好好看了几个小时。谢谢!
更新:(我的Best_of_three功能)
def pivot_best_of_three(alist):
leftmost = 0
middle = int(len(alist) / 2)
rightmost = len(alist) - 1
if (alist[leftmost] <= alist[middle] <= alist[rightmost] or alist[rightmost] <= alist[middle] <= alist[leftmost]):
return alist[middle]
elif (alist[middle] <= alist[leftmost] <= alist[rightmost] or alist[rightmost] <= alist[leftmost] <= alist[middle]):
return alist[leftmost]
else:
return alist[rightmost]
答案 0 :(得分:2)
当IndexError
尝试查找零项目列表的pivot_best_of_three
成员时,会发生rightmost
。解决这个问题的简单方法就是不要传递这样的列表。 :)
以下是这些功能的略微修改版本。我已经使用各种长度的列表测试了这些版本,长度为零,并且它们似乎正常运行。
def pivot_ninther(alist):
listLength = len(alist)
if listLength < 3:
return alist[0]
third = listLength // 3
leftList = alist[:third]
midlist = alist[third:-third]
lastlist = alist[-third:]
leftBest = pivot_best_of_three(leftList)
midBest = pivot_best_of_three(midlist)
lastBest = pivot_best_of_three(lastlist)
pivots = [leftBest, midBest, lastBest]
return pivot_best_of_three(pivots)
def pivot_best_of_three(alist):
leftmost = alist[0]
middle = alist[len(alist) // 2]
rightmost = alist[-1]
if (leftmost <= middle <= rightmost) or (rightmost <= middle <= leftmost):
return middle
elif (middle <= leftmost <= rightmost) or (rightmost <= leftmost <= middle):
return leftmost
else:
return rightmost
正如您所看到的,我简化了pivot_best_of_three
,因此它不会为同一个值多次索引alist
。
但是可以使用简单的sorting network:
进一步简化def sort3(a, b, c):
if c < b: b, c = c, b
if b < a: a, b = b, a
if c < b: b, c = c, b
return a, b, c
def pivot_best_of_three(alist):
leftmost = alist[0]
middle = alist[len(alist) // 2]
rightmost = alist[-1]
return sort3(leftmost, middle, rightmost)[1]
答案 1 :(得分:0)
尝试较小的计数(&lt; = 20)并检查在第三次== 0(在最深的递归级别)时pivot_ninther()中会发生什么?似乎它会创建空数组,然后尝试索引它们。
在调用pivot_ninther()之前,代码应该检查以确保长度&gt; = 9,然后在调用... best_of_three()时检查&gt; = 3。如果只有一两件商品,请选一件。
建议,在让quicksort工作后,备份源代码而不是创建新数组,pivot函数应该与原始数组和第一个/中间/最后一个索引一起使用。
你可以使用掉期来简化中间值3.这有助于像逆序数组开始一样。
// median of 3
i = lo, j = (lo + hi)/2, k = hi;
if (a[k] < a[i])
swap(a[k], a[i]);
if (a[j] < a[i])
swap(a[j], a[i]);
if (a[k] < a[j])
swap(a[k], a[j]);
pivot = a[j];
wiki文章: