Returning [None,None] of split array(Python)

Question:

Hi i am supposed to learn how to implement the heap sort function.

I have a singly linked list (my implementation as well):

import numpy as np
import math as mt

class list_node:

def __init__(self,obj,next_listnode):
    self.obj = obj
    self.next_listnode  = next_listnode

and

class linked_list:
    
    def __init__(self,list_node):
        self.list_node =list_node

    def add_node(self,obj):
        current = self.list_node
        while current.next_listnode is not None:
            current = current.next_listnode
        current.next_listnode = obj;

    def print_linkedlist(self):
        current  = self.list_node
        while current:
            print("",current.obj)
            print("n")
            current = current.next_listnode

    def delete_node(self,obj):
        current  = self.list_node
        if current.obj is  obj:
            target = current.next_listnode
            self.list_node = current.next_listnode
            del target
        else:
            while current.next_listnode.obj is not obj:
                current = current.next_listnode
            target = current.next_listnode
            current.next_listnode = current.next_listnode.next_listnode
            del target

And I am trying to perform the heap sort operation.
I have copied the list nodes to a array of list nodes.
The first step of the heap operation is to dismantle the full array of the list nodes into arrays of 2 elements then sort those small arrays and then work from the bottom to the top.

This is my function so far:

     def heap_sort(self):
        x = 0
        current = self.list_node
        while current:
            current = current.next_listnode
            x=x+1
        print(x)

        arr = [None]*x
        x = 0
        while current:
            arr[x] = current
            current = current.next_listnode
            x = x+1
        newarr= np.array_split(arr,mt.ceil(len(arr)/2))
        print(newarr)


A = list_node("John",None)
B = list_node("Mike",None)
C = list_node("Han",None)
D = list_node("Daisy",None)
E = list_node("Piggy",None)

liste = linked_list(A)
liste.add_node(B)
liste.add_node(C)
liste.add_node(D)
liste.add_node(E)
liste.heap_sort()

However this is printed:

> 5
[array([None, None], dtype=object), array([None, None], dtype=object), array([None], dtype=object)]

And it is wrong it must be [[A,B],[C,D],[E]]. Where am I wrong and how do I fix it?

Asked By: Volpina

||

Answers:

You didn’t reset current before your second loop in the heap_sort function so the loop never runs. This version of the function populates new_arr, though you may want arr[x] = current.obj perhaps?

    def heap_sort(self):
        x = 0
        current = self.list_node
        while current:
            current = current.next_listnode
            x=x+1
        print(x)

        arr = [None]*x
        x = 0
        current = self.list_node ## <-- NEW CODE HERE
        while current:
            arr[x] = current
            current = current.next_listnode
            x = x+1
        newarr= np.array_split(arr,mt.ceil(len(arr)/2))
        print(newarr)

You could also make this slightly more efficient by keeping track of the length of your linked list by adding a length variable to your linked_list class and incrementing/decrementing it every time you add or delete a node. This way you wouldn’t need that first loop in the heap_sort function 🙂

Answered By: Tom Wagg

If you have a list, you don’t need array_split to divide into two:

In [218]: alist = [1,2,3,4,5,6,7]; x,y=alist[:3], alist[3:]

In [219]: x,y
Out[219]: ([1, 2, 3], [4, 5, 6, 7])

compared to:

In [220]: np.array_split(alist,2)
Out[220]: [array([1, 2, 3, 4]), array([5, 6, 7])]
Answered By: hpaulj