该程序用于快速排序,具有重复键。代码运行一次或两次,然后下次给出IndexError,尽管列表不为空。当我打印索引时,它们位于范围内。这是我的一个问题特别是计算机?
编辑添加了追溯
import random
def partition(n,lo,hi):
i=lo
lt=lo #index showing the start of all duplicate partitioning keys
gt=hi #index showing the end of all duplicate partitioning keys
x=n[lt]
while(i<=gt):
while(n[i]<=n[lt] and i<=gt):
if(x!=n[lt]):
print("alert!!!")
if(n[i]<n[lt]): #current alement not a duplicate of partitioning alement
if(lt<=i):
n[lt],n[i]=n[i],n[lt]
#print(n)
i+=1
lt+=1
else: #current element is a duplicate partitioning alement
#print(n[i],"=",n[lt])
i+=1
while(n[gt]>n[lt] and i<=gt):
gt-=1
if(i<gt):
n[i],n[gt]=n[gt],n[i]
gt-=1
#print(n)
return gt
def quickSort(n,lo,hi):
#print("called")
if(lo<hi):
print(n)
p=partition(n, lo, hi)
quickSort(n, lo, p-1)
quickSort(n, p+1, hi)
def main():
nums=[]
for i in range(30):
nums.append(random.randrange(100))
print("original array")
print(nums)
k=4
hi=len(nums)-1
#print(k,"th lowest number is ",quickSelect(nums, 0,hi,k))
print(nums)
quickSort(nums,0,hi)
print(nums)
if __name__ == "__main__":
main()
回溯:
Traceback (most recent call last):
File "C:\Users\S.reddy\workspace\sorter\src\selector\quickSelect.py", line 59, in <module>
main()
File "C:\Users\S.reddy\workspace\sorter\src\selector\quickSelect.py", line 55, in main
quickSort(nums,0,hi)
File "C:\Users\S.reddy\workspace\sorter\src\selector\quickSelect.py", line 43, in quickSort
quickSort(n, p+1, hi)
File "C:\Users\S.reddy\workspace\sorter\src\selector\quickSelect.py", line 41, in quickSort
p=partition(n, lo, hi)
File "C:\Users\S.reddy\workspace\sorter\src\selector\quickSelect.py", line 11, in partition
while(n[i]<=n[lt] and i<=gt):
IndexError: list index out of range
答案 0 :(得分:0)
问题出在第11行:
while(n[i]<=n[lt] and i<=gt):
您需要将其更改为:
while(i<=gt and n[i]<=n[lt]):
因为python首先检查第一个条件(在这种情况下它是i&lt; = gt)并且如果它是真的而不是他检查第二个(n [i]&lt; = n [lt])但是如果第一个条件是false然后python退出while循环而不检查第二个条件。
答案 1 :(得分:0)
由于您在内部while
循环中检查条件的顺序,您的代码有时会超出边界索引。
通常,调试此类问题的最简单方法是在代码中添加try
和except
块,except
块打印出有用的诊断值。我在你的循环中使用了这个变体来找出问题:
try:
while(n[i]<=n[lt] and i<=gt):
if(x!=n[lt]):
print("alert!!!")
if(n[i]<n[lt]): #current alement not a duplicate of partitioning alement
if(lt<=i):
n[lt],n[i]=n[i],n[lt]
#print(n)
i+=1
lt+=1
else: #current element is a duplicate partitioning alement
#print(n[i],"=",n[lt])
i+=1
except IndexError:
print(i, gt, len(n))
raise
您会发现,在某些情况下,gt
将为len(n) - 1
而i
将为len(n)
。在这种情况下,while(n[i]<=n[lt] and i<=gt):
中的第一个测试会引发IndexError
,因为n[i]
不是有效索引。
相反,您应该首先使用i <= gt
以其他顺序放置测试。如果该测试为False
,则and
将“短路”并且不评估第二个测试,这将导致异常。所以:使用while i <= gt and n[i] <= n[lt]:
(括号是不必要的,所以我删除它们并将术语与运算符间隔开。有关Python样式的更多建议,请参阅PEP 8。)