I am writing a program meant to find the average number of recursive calls it takes to run quickselect, and I have added a counter "calls" to keep track of the number of recursive calls. I have it incrementing every time quickselect is called again, but when I use a larger number for main the number of calls quickly goes into exponential territory. I would like for main to return the average number of calls, and I know the number I am getting is wrong but I cannot tell why. Any suggestions would be welcomed.
import numpy
import numpy as np
import random
def main(trials,k):
i = 0;
hold = []
calls = -1;
while i < trials:
generate(hold, 75)
calls = calls + quickselect(hold, k, calls)
i = i + 1
print(calls/trials)
def generate(l,n):
for i in range(n):
r=random.randint(0,n)
if r not in l:
l.append(r)
def quickselect(l, k, calls) :
#l is the list of the numbers
#we are finding the kth largest element
calls = calls + 1
length = len(l)
pivotselect = numpy.random.randint(0,length,1)
l = numpy.array(l)
#print(pivotselect)
#print(l[pivotselect])
pivot = l[pivotselect]
#print("this is the pivot", pivot)
# Pick a random pivot element from the list, each
# equally likely
l_small = []
l_big = []
smalltrack = 0
bigtrack = 0
i = 0
ispivot = 0
while i < length:
#print(i)
compare = l[i]
if compare < pivot:
l_small.append(compare)
smalltrack = smalltrack + 1
#print(l_small)
elif l[i] > pivot:
l_big.append(compare)
bigtrack = bigtrack + 1
else:
ispivot = ispivot + 1
#print(compare, "ispivot is now", ispivot)
i = i + 1
#print("ispivot is", ispivot)
#print(len(l_small), "small then big", len(l_big))
checker = len(l_small) + len(l_big)
#print(checker)
checker = checker + ispivot
#print(checker)
assert(length == checker)
l_big = numpy.array(l_big)
l_small = numpy.array(l_small)
#print("check 1")
if k <= len(l_big):
# kth largest must be in l_big
res = quickselect(l_big, k, calls)
#print("check 2")
#calls = calls + 1
return res
elif k > len(l_big) + 1:
# kth largest must be in l_small
res = quickselect(l_small, k - len(l_big) - 1, calls)
#print("check 3")
#calls = calls + 1
return res
else:
#print("check 4")
#print("calls", calls)
print(calls)
return calls