Why will my build_heap method not stop running?
<p>I have written a class for a <code>MinHeap</code> class and created a <code>build_heap</code> method. Whenever I call the <code>build_heap</code> function the program continues to run unless I keyboard interrupt it. The heap appears to built when I interrupt the function call, but I am curious as to why the function appears to be running infinitely.</p>

<p>MinHeap Class:</p>

<pre><code>class MinHeap:
    def __init__(self):
        self.heap_list = [0]
        self.current_size = 0

    def perc_up(self, index):
        while index // 2 &gt; 0:
            if self.heap_list[index] &lt; self.heap_list[index // 2]:
                temp = self.heap_list[index // 2]
                self.heap_list[index // 2] = self.heap_list[index]
                self.heap_list[index] = temp
            index = index // 2

    def perc_down(self, index):
        while (index * 2) &lt;= self.current_size:
            mc = self.min_child(index)
            if self.heap_list[index] &gt; self.heap_list[mc]:
                temp = self.heap_list[index]
                self.heap_list[index] = self.heap_list[mc]
                self.heap_list[mc] = temp
            i = mc

    def min_child(self, index):
        if (index * 2 + 1) &gt; self.current_size:
            return index * 2
        else:
            if self.heap_list[index * 2] &lt; self.heap_list[index * 2 + 1]:
                return index * 2
            else:
                return index * 2 + 1

    def insert(self, value):
        self.heap_list.append(value)
        self.current_size += 1
        self.perc_up(self.current_size)

    def peek(self):
        return self.heap_list[1]

    def del_min(self):
        ret_val = self.heap_list[1]
        self.heap_list[1] = self.heap_list[self.current_size]
        self.heap_list.pop()
        self.perc_down(1)
        return ret_val

    def is_empty(self):
        if self.current_size == 0:
            return True
        else:
            return False

    def size(self):
        return self.current_size

    def build_heap(self, a_list):
        i = len(a_list) // 2
        self.current_size = len(a_list)
        self.heap_list = [0] + a_list[:]
        while (i &gt; 0):
            self.perc_down(i)
            i = i - 1
</code></pre>

<p>Output when calling build_heap:</p>

<pre><code>&gt;&gt;&gt; heap = MinHeap()
&gt;&gt;&gt; lyst = [ 1, 3, 6, 19, 13, 4, 2]
&gt;&gt;&gt; heap.build_heap(lyst)
</code></pre>

<pre class="lang-none prettyprint-override"><code>Traceback (most recent call last):
  File "&lt;pyshell#13&gt;", line 1, in &lt;module&gt;
    heap.build_heap(lyst)
  File "C:/Users/frost_000/Documents/Python Files/MinHeap.py", line 62, in         build_heap
self.perc_down(i)
  File "C:/Users/frost_000/Documents/Python Files/MinHeap.py", line 16, in  perc_down
    while (index * 2) &lt;= self.current_size:
KeyboardInterrupt
</code></pre>

<pre class="lang-python prettyprint-override"><code>&gt;&gt;&gt; heap.heap_list
&gt;&gt;&gt; [0, 1, 3, 2, 19, 13, 4, 6]
</code></pre>

<p>The problem is <code>perc_down()</code> never returns when <code>build_help()</code> call it. This is because the condition <code>(index * 2) &lt;= self.current_size</code> never changes and is always <code>True</code> because it's not affected by any of the statements within the <code>while</code> loop.</p>

<p>With the change and addition shown, it seems to now work:</p>

<pre><code>class MinHeap:
    def __init__(self):
        self.heap_list = [0]
        self.current_size = 0

    def perc_up(self, index):
        while index // 2 &gt; 0:
            if self.heap_list[index] &lt; self.heap_list[index // 2]:
                temp = self.heap_list[index // 2]
                self.heap_list[index // 2] = self.heap_list[index]
                self.heap_list[index] = temp
            index = index // 2

    def perc_down(self, index):
        while (index * 2) &lt;= self.current_size:
            mc = self.min_child(index)
            if self.heap_list[index] &gt; self.heap_list[mc]:
                temp = self.heap_list[index]
                self.heap_list[index] = self.heap_list[mc]
                self.heap_list[mc] = temp
            index = mc  #### changed

    def min_child(self, index):
        if (index * 2 + 1) &gt; self.current_size:
            return index * 2
        else:
            if self.heap_list[index * 2] &lt; self.heap_list[index * 2 + 1]:
                return index * 2
            else:
                return index * 2 + 1

    def insert(self, value):
        self.heap_list.append(value)
        self.current_size += 1
        self.perc_up(self.current_size)

    def peek(self):
        return self.heap_list[1]

    def del_min(self):
        ret_val = self.heap_list[1]
        self.heap_list[1] = self.heap_list[self.current_size]
        self.heap_list.pop()
        self.current_size -= 1  #### added
        self.perc_down(1)
        return ret_val

    def is_empty(self):
        if self.current_size == 0:
            return True
        else:
            return False

    def size(self):
        return self.current_size

    def build_heap(self, a_list):
        i = len(a_list) // 2
        self.current_size = len(a_list)
        self.heap_list = [0] + a_list[:]
        while (i &gt; 0):
            print('i: {}'.format(i))
            self.perc_down(i)
            i = i - 1

heap = MinHeap()
lyst = [ 1, 3, 6, 19, 13, 4, 2]
heap.build_heap(lyst)
</code></pre>

python heap interrupt