Beispiel #1
0
def test_eq_ne():
    '''Test __eq__ and __ne__ of the BST class.'''
    
    #Compare two basic, one-element trees.
    tree_one = build_tree([1])
    tree_two = build_tree([1])
    assert tree_one == tree_two, \
           '__eq__ did not work properly for one-element BST.'
    assert not tree_one != tree_two, \
           '__ne__ did not work properly for one-element BST.'
    
    #Start with two identical tree, make changes to one, and check if the 
    #changes are detected.
    tree_one = build_tree([2,1,3])
    tree_two = build_tree([2,1,3])
    assert tree_one == tree_two, \
           '__eq__ did not work properly for three-element BST.'
    
    tree_two.root.right.parent = 1
    assert not tree_one == tree_two, \
           '__eq__ did not detect different parent pointers between two BST.'
    
    tree_two.root.right.parent = tree_two.root
    assert tree_one == tree_two, \
           '__eq__ did not work properly for three-element BST.'
    
    bst.BST.insert(tree_two, 7)
    assert not tree_one == tree_two, \
           '__eq__ did not detect difference between two trees formed by \
           adding a node to one of two identical trees.'
    
    bst.BST.insert(tree_one, 7)
    assert tree_one == tree_two, \
           '__eq__ did not work properly.'           
    
    #Start with two different trees, change one so that it is identical to the
    #other, and check if they are detected as equal
    tree_one = build_tree([2,1,3])
    tree_two = build_tree([1,2,3])
    assert not tree_one == tree_two, \
           '__eq__ did not work properly for three-element BST.'
    
    bst.rotate_left(tree_two, tree_two.root)
    assert tree_one == tree_two, \
           '__eq__ did not work properly for three-element BST, or \
           bst.rotate_left is broken.'
    
    tree_three = build_tree([3,2,1])
    bst.rotate_right(tree_three, tree_three.root)
    assert tree_one == tree_three, \
           '__eq__ did not work properly for three-element BST, or \
Beispiel #2
0
def test_rotate_left_rotate_right():
    '''Test left and right rotation on non-root nodes of a tree.'''
    
    tree_one = build_tree([5,4,6,1,2,7])
    
    #Rotate left and right should not work on leaf nodes
    bst.rotate_left(tree_one, tree_one.root.right.right)
    assert tree_one == build_tree([5,4,6,1,2,7]), \
           'bst.rotate_left inproperly rotated a tree at a leaf node.'
    bst.rotate_right(tree_one, tree_one.root.right.right)
    assert tree_one == build_tree([5,4,6,1,2,7]), \
           'bst.rotate_right inproperly rotated a tree at a leaf node.' 
    
    #Test if rotate left and right work on random, non-root and non-leaf nodes.
    bst.rotate_right(tree_one, tree_one.root.left)
    assert tree_one == build_tree([5,1,4,2,6,7]), \
           'bst.rotate_right did not work properly.'
    bst.rotate_left(tree_one, tree_one.root.right)
    assert tree_one == build_tree([5,1,4,2,7,6]), \
           'bst.rotate_left did not work properly.'
    bst.rotate_right(tree_one, tree_one.root.left.right)
    assert tree_one == build_tree([5, 1, 2, 4, 7, 6]), \
           'bst.rotate_right did not work properly.'
    bst.rotate_left(tree_one, tree_one.root.left)
    assert tree_one == build_tree([5, 2, 1, 4, 7, 6]), \
           'bst.rotate_left did not work properly.'
    def test_rotate_subtree_right(self):
        '''Test left rotation on the root of a tree.'''

        # A full binary search tree.
        tree = build_tree([4, 2, 1, 3, 6, 5, 7])
        old_tree = build_tree([4, 2, 1, 3, 6, 5, 7])
        #tree.display()
        #print ""

        # The expected result.
        target_tree = build_tree([4, 2, 1, 3, 5, 6, 7])
        #target_tree.display()

        assert tree.root.parent == None, 'tree.parent should have been None.'
        assert bst.size(tree.root) == 7, 'tree size should be 7.'
        assert bst.is_valid_tree(tree.root), \
            'Valid tree was marked as invalid.'

        bst.rotate_right(tree, tree.root.right)
        #tree.display()
        assert bst.size(tree.root) == 7, 'tree size should be 7.'
        assert bst.is_valid_tree(tree.root), \
            'Valid tree was marked as invalid.'
        assert tree.root.right.data == old_tree.root.right.left.data, \
               '''incorrect rotate, tree's new right substree should start
               with 5'''
        assert tree.root.data == old_tree.root.data, \
               '''incorrect rotate, tree's root should not have changed'''
        assert tree.root.right.right.right.data == \
               old_tree.root.right.right.data, \
               '''incorrect rotate, subtree's rightmost leaf should not have
               changed'''
        #RL is right.left, and LR is left.right

        # This calls tree.__eq__(target_tree). Cool, huh? You need to write
        # the __eq__ method in class BST to do the tree comparison.
        assert tree == target_tree, '__eq__ did not work properly.'

        # This calls tree.__ne__(target_tree).
        assert not (tree != target_tree), '__ne__ did not work properly.'
Beispiel #4
0
 def test_rotation(self):
     Q = Tree_Node(1)
     P = Tree_Node(2)
     P.add_left(3)
     P.add_right(4)
     Q.left = P
     Q.add_right(5)
     first = []
     postorder(Q, lambda x: first.append(str(x)))
     second = []
     Q = rotate_right(Q)
     postorder(Q, lambda x: second.append(str(x)))
     self.assertEqual("".join(first), "12345")
     self.assertEqual("".join(second), "23145")
def process_user_command(game_tree, target_tree, curr, pic):
    '''Read and process one command from the user, modifying BTNode game_tree
    and current BTNode curr as appropriate and redrawing the new game_tree and
    BTNode target_tree on Picture pic.  Return the new value of curr.'''

    d = {'Left': 'l', 'Right': 'r', 'Up': 'u', 'a': 'L', 's': 'R', 'q': 'q'}
    cmd = d.get(KD.moving_by_keys().key, 'm')

    # Only listen to valid commands.
    if len(cmd) != 1 or cmd[0] not in 'qulrLR':
        return curr

    # Erase the old tree and redraw target_tree halfway across the window.
    media.add_rect_filled(pic, 0, 0, WIDTH, HEIGHT, media.white)
    draw(pic, target_tree.root, 0, WIDTH / 2, curr)

    # Process user commands.
    if cmd == 'q':
        media.close(pic)
        sys.exit(0)
    elif cmd == 'u' and curr != None and curr.parent != None:
        curr = curr.parent
    elif cmd == 'l' and curr.left != None:
        curr = curr.left
    elif cmd == 'r' and curr.right != None:
        curr = curr.right
    elif cmd == 'L' and curr.right != None:
        curr = bst.rotate_left(game_tree, curr)
    elif cmd == 'R' and curr.left != None:
        curr = bst.rotate_right(game_tree, curr)

    # The parent attribute of the nodes of the new tree must be corrected.
    # If curr is at the top, a rotation may have moved it there. Set the
    # game_tree root to curr if that happened.

    if curr.parent == None:
        game_tree.root = curr

    # Draw the new game tree.
    draw(pic, game_tree.root, 0, 0, curr)
    media.update(pic)

    return curr
Beispiel #6
0
def fix_rbtree(node):
    #assert !node.is_black

    #case root
    if is_root(node):
        return

    dad = node.parent

    # case 0
    if dad.is_black:
        return

    grandpa = node.parent.parent

    if grandpa.is_nil:  #dad is root
        dad.flip_color

    if dad == grandpa.left:
        uncle = grandpa.red
    else:
        uncle = grandpa.left

    #parent is red
    #case 1
    if uncle(node).is_red:
        dad.flip_color()
        uncle.flip_color()
        grandparent.flip_color()
        fix_rbtree(grandparent)
        return

    #case 2(uncle is black)
    if dad == grandpa.right:
        y = bst.rotate_left(grandpa)
        node.flip_color()
        fix_rbtree(y)
        return
    else:
        y = bst.rotate_right(grandpa)
        node.flip_color()
        fix_rbtree(y)
        return
def fix_rbtree(node):
    #assert !node.is_black

    #case root
    if is_root(node):
        return

    dad = node.parent

    # case 0
    if dad.is_black:
        return

    grandpa = node.parent.parent

    if grandpa.is_nil:      #dad is root
        dad.flip_color

    if dad == grandpa.left:
        uncle = grandpa.red
    else:
        uncle = grandpa.left

    #parent is red
    #case 1
    if uncle(node).is_red:
        dad.flip_color()
        uncle.flip_color()
        grandparent.flip_color()
        fix_rbtree(grandparent)
        return
        
    #case 2(uncle is black)
    if dad == grandpa.right:
        y = bst.rotate_left(grandpa)
        node.flip_color()
        fix_rbtree(y)
        return
    else:
        y = bst.rotate_right(grandpa)
        node.flip_color()
        fix_rbtree(y)
        return
Beispiel #8
0
def process_user_command(game_tree, target_tree, curr, pic):
    '''Read and process one command from the user, modifying BTNode game_tree
    and current BTNode curr as appropriate and redrawing the new game_tree and
    BTNode target_tree on Picture pic.  Return the new value of curr.'''

    cmd = raw_input(prompt)
    
    # Only listen to valid commands.
    while cmd not in 'shqulrLR':
        cmd = raw_input(prompt)
    
    # Erase the old tree and redraw target_tree halfway across the window.
    media.add_rect_filled(pic, 0, 0, WIDTH, HEIGHT, media.white)
    draw(pic, target_tree.root, 0, WIDTH / 2, curr)

    # Process user commands.
    if cmd == 'q':
        media.close(pic)
        return None
    elif cmd == 'h':
        solver.help_solve(game_tree, target_tree)
    elif cmd== 's':
        while game_tree != target_tree:
            solver.help_solve(game_tree, target_tree)
    elif cmd == 'u' and curr != None and curr.parent != None:
        curr = curr.parent
    elif cmd == 'l' and curr.left != None:
        curr = curr.left
    elif cmd == 'r' and curr.right != None:
        curr = curr.right
    elif cmd == 'L' and curr.right != None:
        curr = bst.rotate_left(game_tree, curr)
    elif cmd == 'R' and curr.left != None:
        curr = bst.rotate_right(game_tree, curr)
        
    # Draw the new game tree.
    draw(pic, game_tree.root, 0, 0, curr)
    media.update(pic)
    
    return curr