SE250:lab-6:dols008
Task 1
To determine the relationship between tree size and height, I decided to loop through a number of different tree sizes. For each tree size I would generate a random binary tree and record it's height. Here is some sample data:
Size Height 0 0 100 13 200 17 300 18 400 16 500 19 600 24 700 20 800 20 900 22 1000 24
To make my data more accurate, I decided to generate a number of trees of any particular size and average the heights. Here are the results after averaging 10 trees per size:
Size Height 0 0.000000 100 13.400000 200 16.000000 300 17.800000 400 18.400000 500 19.700000 600 20.100000 700 20.800000 800 20.700000 900 21.600000 1000 22.100000
I was disappointed to find that there is no given method for freeing binary trees.
Task 2
Implementing the minimum and maximum functions was straight forward, but testing them was a little tricky. I opted to do it by generating a few random trees, printing them out using show_tree and visually checking my minimum and maximum were correct. The output of show_tree was less than intuitive, it took me a while to figure out the tree is actually sideways. I also found that the root of my tree always had a key of 0, so I seeded rand() to get some more interesting data.
Here is my code for minimum and maximum:
Node* minimum( Node* node ) { if (node != empty && node->left != empty) return minimum(node->left); return node; } Node* maximum( Node* node ) { if (node != empty && node->right != empty) return maximum(node->right); return node; }
Task 3
Lookup wasn't hard either, but again it was a pain to test. I had to construct the tree by hand this time so that I knew which numbers were in it (though it occurs to me now I could have used the same seed each time). Here's the code:
Node* lookup( int key, Node* node ) { if (node == empty || key == node->key) return node; if (key > node->key) return lookup(key, node->right); else return lookup(key, node->left); }
Task 4/5
Preorder took a fair bit of thought. It didn't seem hard at first, but it took a couple of broken versions which got stuck down leaves before I got it right. Once I had a working version I tidied it up a bit and removed an extra variable.
Node* next_pre( Node* node ) { if (node == empty) return empty; if (node->left != empty) return node->left; if (node->right != empty) return node->right; while (node->parent != empty) { if (node->parent->right != empty && node->parent->right != node) return node->parent->right; node = node->parent; } return empty; }
I skipped ahead to next_in, because it seemed more interesting. This one took a couple of tries too. There's less in common between the functions than I expected.
Node* next_in( Node* node ) { if (node == empty) return empty; if (node->right != empty) { node = node->right; while (node->left != empty) node = node->left; return node; } while (node->parent && node->parent->right == node) node = node->parent; return node->parent; }
It's not getting much easier. next_post took some figuring out too.
Node* next_post( Node* node ) { if (node == empty || node->parent == empty) return empty; if (node->parent->right != empty && node->parent->right != node) { node = node->parent->right; while (node->left != empty) node = node->left; while (node->right != empty) node = node->right; return node; } return node->parent; }
I'm well over time now. I might come back to this later, it's good practice.