class node: def __init__( self ): self.data = [None, None] self.next = [None, None, None] self.size = 0 def __str__(self ): return str( self.data ) + '(node has '+ str( self.size ) + ' item(s))' class tree23: def __init__( self ): self.head = None def insert( self, item ) : #special case: empty if self.head == None: self.head = node() self.head.data[0] = item self.head.size = 1 return # find leaf # leaf will ALWAYS have next[0] == None ptr = self.head myStack = [ ptr ] #keep a stack of nodes visited back up to the root while( ptr.next[0] != None ): if item < ptr.data[0]: nextIndex = 0 elif ptr.size == 2 and item > ptr.data[1]: nextIndex = 2 else: nextIndex = 1 ptr = ptr.next[ nextIndex ] myStack = myStack + [ptr] #pop the current node off the stack myStack.pop() print 'INSERT -- we have found a leaf:', ptr # now we are at a leaf. If we have room, just put it in if ptr.size == 1: insertIndex = 0 if item > ptr.data[0]: insertIndex = 1 #shift data, and put the new value in ptr.data = ptr.data[(-1*(insertIndex+1)):] + ptr.data[:(-1*(insertIndex+1))] ptr.data[insertIndex] = item ptr.size +=1 return print 'INSERT -- leaf is full, must split a node' # final case, node is full. # make a new sibling and parent. Set up the nodes # we are at a leaf, so we don't need to worry about pointers leftNode = node() leftNode.size = 1 rightNode = node() rightNode.size = 1 parNode = node() parNode.size = 1 # assign data and pointers if item < ptr.data[0]: leftNode.data[0] = item parNode.data[0] = ptr.data[0] rightNode.data[0] = ptr.data[1] elif item < ptr.data[1]: leftNode.data[0] = ptr.data[0] parNode.data[0] = item rightNode.data[0] = ptr.data[1] else: leftNode.data[0] = ptr.data[0] parNode.data[0] = ptr.data[1] rightNode.data[0] = item parNode.next[0] = leftNode parNode.next[1] = rightNode if len(myStack) == 0 : # we are splitting the root self.head = parNode return # At this point, we have made a new sub-tree by splitting a node. # parNode is the parent of the sub-tree # now merge the parnode with the parent. possibly recursively splitting done = False while len( myStack) > 0 and not done: theParent = myStack.pop() print'INSERT -- splitting back uip the tree at parent node:', theParent # if we have room in the parent node, merge it with parNode if( theParent.size == 1 ): insertIndex = 0 if parNode.data[0] > theParent.data[0]: insertIndex = 1 #shift data, and put the new value in theParent.data = theParent.data[(-1*(insertIndex+1)):] + theParent.data[:(-1*(insertIndex+1))] theParent.next[2] = theParent.next[1] theParent.data[insertIndex] = parNode.data[0] theParent.size +=1 theParent.next[insertIndex] = parNode.next[0] theParent.next[insertIndex+1] = parNode.next[1] done = True break else: # need to merge the nodes # Each time through here we already have the sub tree built # we are just merging its root node with the parent node that was # pointing at the subtee we are working on. # parnode is the node to be merged. Its children are already set # theParent is the node parNode must be merged with # promote node is the node of the data that will be promoted up since # we only get here if theParent is full promoteNode = node() if parNode.data[0] < theParent.data[0] : print 'small' promoteNode.data[0] = theParent.data[0] promoteNode.next[0] = parNode promoteNode.next[1] = theParent promoteNode.size = 1 theParent.data[0] = theParent.data[1] theParent.size = 1 theParent.next[0] = theParent.next[1] theParent.next[1] = theParent.next[2] parNode = promoteNode continue elif parNode.data[0] < theParent.data[1] : print 'med' promoteNode.data[0] = parNode.data[0] promoteNode.next[0] = theParent promoteNode.next[1] = parNode promoteNode.size = 1 theParent.size = 1 theParent.next[1] = parNode.next[0] parNode.data[0] =theParent.data[1] parNode.next[0] = parNode.next[1] parNode.next[1] = theParent.next[2] parNode.size = 1 parNode = promoteNode continue else: print 'big' promoteNode.data[0] = theParent.data[1] promoteNode.next[0] = theParent promoteNode.next[1] = parNode promoteNode.size = 1 theParent.size = 1 parNode = promoteNode continue # if we never set done, then we broke all the way up to the root node # so reset the root pointer if not done: self.head = parNode def printTree( self ): self.printRecursive( self.head, 0 ) def printRecursive( self, curr, depth ): # post order traversal # print right child, middle child, left child, then the current node # base case for recursion if curr == None: return # the following string will allow us to indent the nodes properly aString = ['\t']*depth # make a list of a bunch of tab characters aString = ''.join( aString ) #convert the list into a string for printing printedNodeDelimiter =False if curr.size == 2: # if it isa 2 node, handle the rightmnost pointer and right most data self.printRecursive( curr.next[2], depth+1 ) #recursively print the tree print aString, '~' # a character to mark the node printedNodeDelimiter = True print aString, curr.data[1] self.printRecursive( curr.next[1], depth+1 ) #recursively print the tree for the middle pointer if not printedNodeDelimiter: print aString, '~' # a character to mark the node print aString, curr.data[0] # print the left most data print aString, '^' # a character to mark the node self.printRecursive( curr.next[0], depth+1 ) #recursively print the tree for the left pointer t = tree23() t.insert( 1 ) t.printTree() print '---------------------' t.insert( 2 ) t.printTree() print '---------------------' t.insert( 3 ) t.printTree() print '---------------------' t.insert( 4 ) t.printTree() print '---------------------' t.insert( 5 ) t.printTree() print '---------------------' t.insert( 6 ) t.printTree() print '---------------------' t.insert( 7 ) t.printTree() print '---------------------' t.insert( 3.5 ) t.printTree() print '---------------------' t.insert( 3.7 ) t.printTree() print '---------------------' t.insert( 9 ) t.printTree() print '---------------------' t.insert( 1.2 ) t.printTree() print '---------------------' t.insert( 1.4 ) t.printTree() print '---------------------' t.insert( 3.1 ) t.printTree() print '---------------------' t.insert( 3.2 ) t.printTree() print '---------------------' t.insert( 3.3 ) t.printTree() print '---------------------' t.insert( 3.4 ) t.printTree() print '---------------------'