5

So I am implementing a Binary Search Tree but am confused as to whether I should have a Node class as well as a Bst class or just one class.

The reason why is because I know a BST is made up of nodes but at any point you can take a node and all the nodes beneath it and that essentially is a BST too.

If I have the following code where its one thing then I when inserting I can call my code like so self.left.insert(data)

class Bst():
def __init__(self, data):
    self.data = data
    self.left = None
    self.right = None

def insert(self, data):
    node_to_insert = Bst(data)
    if data < self.data:
        if self.left is None:
            self.left = Bst(data)
        else:
            self.left.insert(data)
    else:
        if self.right is None:
            self.right = Bst(data)
        else:
            self.right.insert(data)

If I do it the other way where they are two seperate things a Node and a BST then in my insert method I have self.insert(data, node.left):

class Node():
    def __init__(self, data):
        self.data = data
        self.left = None
        self.right = None

class Bst():
    def __init__(self, root=None):
        self.root = root

    def insert(self, data, node):
        node_to_insert = Node(data)

        if node is None:
            node = node_to_insert
        else:
            if data < node.data:
                if node.left is None:
                    node.left = node_to_insert
                else:
                    self.insert(data, node.left)
            else:
                if node.right is None:
                    node.right = node_to_insert
                else:
                    self.insert(data, node.right)

So my question is which is better code self.insert(data, node.left) or self.left.insert(data).

I would assume self.left.insert(data) as when the user is inserting they just have to write bst.insert(5) where as with the other one they say bst.insert(bst.root, 5)

  • I had to do a similar thing in Java not long ago. Only that my tree had to implement the `TreeModel` interface, which works like in your second example. I like the first way better though, so I ended up implementing my tree like in your first example and then provide a wrapper class that made it conform to the `TreeModel` interface. I realize this is not really and answer, just me saying I like one thing over the other(which is why I have posted this as a comment) – Andreas Vinter-Hviid Dec 18 '13 at 13:24

2 Answers2

1

The second is better I think. Algorithm separate with data structure, which brings more flexibility. For example the delete operation, which involves parent nodes, is easier to implement in the second than the first.

qiangwang
  • 41
  • 4
0

I have been thinking about why I like the first method since I posted my comment. I have come to the conclusion that the reason I like the first method, is that to me the only thing the second way does is add complexity. You move all the methods out of the Node class and into an other class.

qiangwant brings up a point about separating algorithm from data structure. I am not sure I completely see it, but even then, why a new class, why not just define the functions outside of the class?

Okay, the BST class keeps track of the root, but there is no guarantee that the nodes you are acting upon have anything to do with the root node stored by the BST object. So as I see it, instead of having a BST object and a node object to do an operation on, you could just as well have a node object called root and an other to do an operation on.

Of course, if you were to define the functions outside of the node class, you would have a bunch on functions on the form def function(node, other args...), which is exactly what class methods are for.

Andreas Vinter-Hviid
  • 1,482
  • 1
  • 11
  • 27