Home > Enterprise >  Functions for a binary search tree (BST) that stores strings
Functions for a binary search tree (BST) that stores strings

Time:11-22

I have created two classes, STNode and StringTree. In my class StringTree, I am having problems with the last three functions (count, max and remove). I have added comments to show what I would like my code to do that it currently is not. Ideally, I would like to only make changes to my StringTree class as I am perfectly fine with STNode.

To further explain the purpose of my code: Each node has three children: left, right and forward;

  • each node contains a character (the data of the node) and a non-negative integer (the multiplicity of the stored data).
  • the left child of a node, if it exists, contains a character that is smaller (alphabetically) than the character of the node
  • the right child of a node, if it exists, contains a character that is greater than the character of the node

Code:

class STNode:
    def __init__(self,d,l,m,r):
        self.data = d
        self.left = l
        self.right = r
        self.next = m
        self.mult = 0 #multiplicity to show end of word
          
    # prints the node and all its children in a string
    def __str__(self):  
        st = "(" str(self.data) ", " str(self.mult) ") -> ["
        if self.left != None:
            st  = str(self.left)
        else: st  = "None"
        if self.next != None:
            st  = ", " str(self.next)
        else: st  = ", None"
        if self.right != None:
            st  = ", " str(self.right)
        else: st  = ", None"
        return st   "]"
    
class StringTree:
        def __init__(self):
            self.root = None
            self.size = 0
            
        def __str__(self):
            return str(self.root)
    
        def add(self,st):
            if st == "":
                return None
            if self.root == None:
                self.root = STNode(st[0],None,None,None)
            ptr = self.root
            for i in range(len(st)):
                d = st[i]
                while True:
                    if d == ptr.data:
                        break
                    elif d < ptr.data:
                        if ptr.left == None:
                            ptr.left = STNode(d,None,None,None)
                        ptr = ptr.left
                    else:
                        if ptr.right == None:
                            ptr.right = STNode(d,None,None,None)
                        ptr = ptr.right
                if i < len(st)-1 and ptr.next == None:
                    ptr.next = STNode(st[i 1],None,None,None)
                if i < len(st)-1:
                    ptr = ptr.next
            ptr.mult  = 1
            self.size  = 1    
        
        def addAll(self,A):
            for x in A: self.add(x)
            
        def printAll(self):
            def printFrom(ptr,s):
                if ptr == None: return
                s0 = s   ptr.data
                for i in range(ptr.mult,0,-1): print(s0)
                if ptr.left != None: printFrom(ptr.left,s)
                if ptr.next != None: printFrom(ptr.next,s ptr.data)
                if ptr.right != None: printFrom(ptr.right,s)
    
            printFrom(self.root,"")   
      
        def _searchNode(self, ptr, d):
            while ptr != None:
                if d == ptr.data:
                    return ptr
                if d < ptr.data:
                    ptr = ptr.left
                else:
                    ptr = ptr.right
            return None        
    
    
        # should return the number of times that string d is stored in the tree
        def count(self, d):
            ptr = self.root
            count = 0
            while ptr != None:
                ptr = self._searchNode(ptr,d)
                if ptr != None:
                    count  = 1
                    ptr = ptr.right
            return count
        
        # should return the lexicographically largest string in the tree and if the tree is empty, should return None
        def max(self):
            last_seen_value = None
            ptr = self.root
            while ptr is not None:
                last_seen_value = ptr.data
                ptr = ptr.right
            return last_seen_value
    
        # should remove one occurrence of string i from the tree and return None
        # if string i does not occur in the tree then it should return without changing the tree
        # it should somehow update the size of the tree correctly
        def remove(self, i):
            if self.head == None:
                return None
            if i == '':
                val = self.head.data
                self.head = self.head.next
                self.length -= 1
                return val
            else:
                ptr = self.head
                while i>1 and ptr.next != None:
                    ptr = ptr.next
                    i -= 1
                if i == 1:
                    val = ptr.next.data
                    ptr.next = ptr.next.next
                    self.length -= 1
                    return val
                return None

Example Testing code:

def testprint(t,message):
 print("\n" message,"tree is:",t)
 print("Count 'ca', 'can', 'car', 'cat', 'cats':",t.count("ca"),t.count("can"),
t.count("car"),t.count("cat"),t.count("cats"))
 print("Size is:",t.size,", max is:",t.max())
 t.printAll()

t = StringTree()
t.addAll(["car","can","cat","cat","cat"])
testprint(t,"Initially")
t.add("")
testprint(t,"After adding the empty string")
t.add("ca")
testprint(t,"After adding 'ca'")
t.remove("car")
testprint(t,"After removing 'car'")
t.remove("cat"); t.remove("cat");
testprint(t,"After removing 'cat' twice")
t.remove("ca"); t.add("cats")
testprint(t,"After removing 'ca' and adding 'cats'")
#removing the remaining strings
t.remove("can"); t.remove("cats"); t.remove(“cat”)
print(t, t.size) #None 0

What testing code should be producing:

Initially tree is: (c, 0) -> [None, (a, 0) -> [None, (r, 1) -> [(n, 1) -> [None, None, None], None, (t, 3) -> [None,
None, None]], None], None]
Count 'ca', 'can', 'car', 'cat', 'cats': 0 1 1 3 0
Size is: 5 , max is: cat
car
can
cat
cat
cat
After adding the empty string tree is: (c, 0) -> [None, (a, 0) -> [None, (r, 1) -> [(n, 1) -> [None, None, None], None,
(t, 3) -> [None, None, None]], None], None]
Count 'ca', 'can', 'car', 'cat', 'cats': 0 1 1 3 0
Size is: 5, max is: cat
car
can
cat
cat
cat
After adding 'ca' tree is: (c, 0) -> [None, (a, 1) -> [None, (r, 1) -> [(n, 1) -> [None, None, None], None, (t, 3) ->
[None, None, None]], None], None]
Count 'ca', 'can', 'car', 'cat', 'cats': 1 1 1 3 0
Size is: 6, max is: cat
ca
car
can
cat
cat
cat
After removing 'car' tree is: (c, 0) -> [None, (a, 1) -> [None, (t, 3) -> [(n, 1) -> [None, None, None], None, None],
None], None]
Count 'ca', 'can', 'car', 'cat', 'cats': 1 1 0 3 0
Size is: 5, max is: cat
ca
cat
cat
cat
can
After removing 'cat' twice tree is: (c, 0) -> [None, (a, 1) -> [None, (t, 1) -> [(n, 1) -> [None, None, None], None,
None], None], None]
Count 'ca', 'can', 'car', 'cat', 'cats': 1 1 0 1 0
Size is: 3, max is: cat
ca
cat
can
After removing 'ca' and adding 'cats' tree is: (c, 0) -> [None, (a, 0) -> [None, (t, 1) -> [(n, 1) -> [None, None, None],
(s, 1) -> [None, None, None], None], None], None]
Count 'ca', 'can', 'car', 'cat', 'cats': 0 1 0 1 1
Size is: 3, max is: cats
cat
can
cats

CodePudding user response:

For your remove function you can try to use a similar method to this that has both count and remove, https://ideone.com/3YljlF

 while (len(l) > 0): 
        """
            loop is continue as long as list l contain the elements
        """
        # create temporary variable that contain the current node
        temp = l[0]
 
        # remove current node from list after creating reference temp
        l.remove(l[0])
 
        if (temp.left != None): # if left child is not None append it to list
            l.append(temp.left) 
        if (temp.right != None): # if right child is not None append it to list
            l.append(temp.right)           
        # if both child is None, means it is leaf node increse the count
        if (temp.left == None and temp.right == None): 
            count  = 1
    return count 

CodePudding user response:

This may not be the best answer, but I will be listing to you some of the many problems I see with your code that prevents you from creating suitable functions for this specific BST.

  • All your functions will not run because you need to assign left and right sub nodes to your root node.
  • The remove function you have written takes as argument what looks like an index rather than a string.
  • Both max and count functions have not been tailored for the word tree you are dealing with
  • Your max function would be more appropriate perhaps in a case where you do not need specifically the lexicographically largest so you must change this
  • Related