5

So far I've been drawing up a plan of attack to see how I could go about doing this and this is what I have:

bool isEmpty() const - returns true if empty, false if not

int getSize() - returns how many words are stored in the dictionary

void insert (String word) -insert word into dictionary if not already present, else update.

boolfind(String word, WordNode & x) - returns true if the word is present and place data in x.

void printSorted() - prints the words in the tree in lexicographic order (specified)

void remove (String word) -implements the lazy deletion of a node

I have the concept of what I want to do down, and I understand how AVL trees work. But I get completely stuck when it comes to actually writing the code, can anyone help me get started?

Bill the Lizard
  • 369,957
  • 201
  • 546
  • 842
  • You probably don't need to implement `remove`. The task of tallying word frequency doesn't need it. Check your assignment, though. – Joey Adams Jul 24 '11 at 19:16
  • remove, much like insert is needed to show how the AVL tree handles balancing itself when something is added or deleted. –  Jul 24 '11 at 20:00
  • The AVL tree doesn't "balance itself" per se; the `insert` and `remove` functions perform balancing as needed. From my experience, implementing `remove` is like implementing `insert` all over again, but harder. If you are required to implement `remove` anyway, make sure you have a way to test it. – Joey Adams Jul 24 '11 at 21:05
  • What do you have so far? I might be able to help if u show what you have to this point. –  Jul 24 '11 at 21:40

1 Answers1

2

Start by implementing a simple binary tree (that is, without balancing), along with the corresponding program to count words in a file. Get that working, so you'll have something to test with. Don't worry about balancing just yet; that's the really hard part.

Here's an insertion function (untested) for a simple binary tree:

/*
 * Insert a new key into a binary tree, or find an existing one.
 *
 * Return the new or existing node whose key is equal to the one requested.
 * Update *node with the new (sub)tree root.
 */
Node *insert(Node **node, String key)
{
    if (*node == NULL) {
        *node = new Node(key);
        return *node;
    }

    if (key < (*node)->key)
        return insert(&(*node)->left, key);

    if (key > (*node)->key)
        return insert(&(*node)->right, key);

    return *node;
}

Once you have a simple binary tree working and tested, re-implement the insertion function to perform balancing, which is the heart of the AVL algorithm.

Start by knowing the invariants of an AVL tree:

  • The balance factor of any node (the difference between the left child's height and the right child's height) is either -1, 0, or +1.
  • In-order traversal produces a dictionary order.

I recommend referring to the AVL tree insertion diagram on Wikipedia. It illustrates the four rotations you will need to implement and where they are needed.

A rotation is necessary when the balance factor of a node goes out of range—in other words, when the difference in height between the left subtree and right subtree is greater than 1.

How do you determine the balance factor of a node? Well, any of the following will work:

  1. Add a height member to the Node structure, and determine the balance factor of any given node by subtracting the right child's height from the left child's height.
  2. Add a balance member to the Node structure. This might be a little harder to figure out, but it yields simpler code (I think).
  3. Compute tree heights and balances by traversal. This is inefficient, so much so that it defeats the purpose of AVL. However, it's easier to understand and less bug-prone.

I recommend starting with the 3rd approach, so you can test your balancing code sooner.

To clarify what is meant by "height" and "balance factor", here are functions to compute them:

int height(Node *node)
{
    if (node == NULL)
        return -1;
    return std::max(height(node->left), height(node->right)) + 1;
}

int balanceFactor(Node *node)
{
    assert(node != NULL);
    return height(node->right) - height(node->left);
}

Figuring out how to update heights or balance factors incrementally is going to involve paper, pencil, simple algebra, and common sense.

I hope this helps!

Joey Adams
  • 37,814
  • 17
  • 79
  • 110
  • got it, really appreciate the help. put me in the right direction and now im nearly done. thanks :) –  Jul 25 '11 at 04:25