I've got to build a complete MIN-HEAP implementation in Python, without using built-in heap functions.
So I've got definitions of parent, left child and right child, which take in account that python number list elements from 0:
from random import randint
import math
def parent(i):
x = int(l.index(l[i])) #########3
y = int(math.floor(x/2))
return y-1
def lchild(i):
x = int(l.index(l[i]))
y = int(math.floor(x*2))
return y-1
def rchild(i):
x = int(l.index(l[i]))
y = int(math.floor(x*2 + 1))
return y-1
then I have a part of code that generates (pseudo)random list for me into the list l:
l = []
dl = int(input)
for i in range (0, dl):
x = int(randint(1,100))
l.append(x)
and until this point everything works good. then I have a function bkop for making the table l into a min-heap.
def bkop(l):
j = 0
for i in range(0, len(l)):
if int(l[i]) < int(parent(l[i])): #########2
l[i], l[parent(i)] = l[parent(i)], l[i]
j = j+1
if j != 0:
bkop(l)
then I want to run a program and see the results:
bkop(l) #########1
print l
The program crashes with an error list index out of range pointing to the 3 lines, that i've marked with #########. I've started writing this about a month ago and i'm pretty sure, that parent, lchild and rchild worked at that time. Do you know, what's wrong?
EDIT1: Ok, so I've fixed the parent/lchild/rchild definitions. I've checked, they return correct values. Here is the code:
def parent(i):
x = i + 1
y = x//2
return y-1
def lchild(i):
x = i + 1
y = x*2
return y-1
def rchild(i):
x = i + 1
y = x*2 + 1
return y-1
The function generating random list is pretty much intact. Then I have this bkop function (that makes a min-heap out of the l list). I use print before and after on purpose, to se if it works... and it doesn't. It returns the same list both times, no compile errors or anything. Any idea how to fix it?
print(l)
def bkop(l):
j = 0
for i in range(0, len(l)):
if l[i] < parent(i):
l[i], l[parent(i)] = l[parent(i)], l[i]
j = j+1
if j != 0:
bkop(l)
bkop(l)
print l
EDIT2: Ok, so I've fixed bkop as you've suggested:
print bkop(l)
def bkop(l):
j = 0
for i in range(1, len(l)):
if l[i] < l[parent(i)]:
l[i], l[parent(i)] = l[parent(i)], l[i]
j = j+1
if j != 0:
bkop(l)
bkop(l)
print bkop(l)
But when I run it, I get this first a randomly-generated table (as I should), and instead of a min-heap table, I get None value, as below:
[34, 9, 94, 69, 77, 33, 56]
None
Any ideas? Maybe I should do it another way around, not comparing l[i] to parent, but l[i] to it's left and right children?
So I've got the whole thing working with the help from Wombatz (Thank you very much!). Here is the working code for the future users:
from random import randint
def parent(i):
x = i + 1
y = x//2
return y-1
def lchild(i):
x = i + 1
y = x*2
return y-1
def rchild(i):
x = i + 1
y = x*2 + 1
return y-1
l = []
dl = int(input())
for i in range (0, dl):
x = int(randint(1,100))
l.append(x)
print l
def bkop(l):
j = 0
for i in range(1, len(l)):
if l[i] < l[parent(i)]:
l[i], l[parent(i)] = l[parent(i)], l[i]
j = j+1
if j != 0:
bkop(l)
bkop(l)
print l
When run, I've put 13 in input for the list length and i've got the result:
13
[30, 62, 9, 100, 75, 73, 57, 82, 2, 76, 2, 50, 41] #before heapify
[2, 2, 30, 62, 9, 41, 57, 100, 82, 76, 75, 73, 50] #after heapify