I am learning algorithms and data structures and to train I am trying to design and implement a binary tree using objective-c.
So far I have the following Classes:
First of all, don't write your methods to take Node **
. It's just confusing.
Second, think about how it should work. Describe to yourself how it should work at a pretty abstract level. Translate that description directly into code, inventing new (not-yet-written!) messages where necessary. If there are steps you don't know how to do yet, just punt those off to new messages you'll write later. I'll walk you through it.
Presumably you want the public API of BinaryTree
to include this message:
@interface BinaryTree
- (void)insertValue:(int)value;
So how do you implement insertValue:
? Pretend you're the BinaryTree
object. What's your high-level description of what you need to do to insert a value? You want to create a new Node
. Then you want to insert that new Node
into yourself. Translate that description directly into code:
@implementation BinaryTree {
Node *root_; // root node, or nil for an empty tree
}
- (void)insertValue:(int)value {
Node *node = [[Node alloc] initWithData:value];
[self insertNode:node];
}
Now think about how you do the inserting. Well, if you are an empty tree, your root_
is nil and you can just set it to the new node. Otherwise, you can just ask your root node to insert the new node under himself. Translate that description directly into code:
- (void)insertNode:(Node *)node {
if (root_ == nil) {
root_ = node;
} else {
[root_ insertNode:node];
}
}
Now pretend you're a Node
. You've been asked to insert a new Node
under yourself. How do you do it? You have to compare the new node's value to your value. If the new node's value is less than your value, you want to insert the new node on your left side. Otherwise, you want to insert it on your right side. Translate that description directly into code:
@implementation Node
- (void)insertNode:(Node *)node {
if (node.data < self.data) {
[self insertNodeOnLeftSide:node];
} else {
[self insertNodeOnRightSide:node];
}
}
Now you're still a Node
, and you've been asked to insert a new node on your left side. How do you do it? Well, if you don't have a child on your left side yet, just use the new node as your left child. Otherwise, you ask your left child to insert the new node under himself. Translate that description directly into code:
- (void)insertNodeOnLeftSide:(Node *)node {
if (self.left == nil) {
self.left = node;
} else {
[self.left insertNode:node];
}
}
I'll leave the implementation of insertNodeOnRightSide:
as an exercise for the reader. ;^)