Discussion 2

advertisement
Discussion 2: PA1
Siarhei Vishniakou
CSE 100
Summer 2014
Files for PA1
•
BST.hpp
– Represents entire binary search tree
– Contains pointer to root node and a bunch of methods
•
BSTIterator.hpp
– Represents an iterator over the binary search tree
•
BSTNode.hpp
– Represents a single node of binary search tree
– Contains pointers to left child, right child, and parent, and contains a Data object
– Also has successor() method
•
test_BST.cpp
– Main script used for testing
•
Makefile
Understanding the code
• Start with test_BST.cpp
– See how the tree and iterators are being used
• Look at BSTIterator, BSTNode, BST
• Implementation (my recommendation)
– BSTIterator, BST, BSTNode, in that order
• successor function is hardest in my opinion
Inorder traversal
• Elements of the BST should be accessed in
increasing arithmetic order
3
• Insert order:
4
1
– 3, 4, 1, 100, -33
• Order should be
– -33, 1, 3, 4, 100
-33
100
Another example
• Insert order:
– 30, 20, 70, 10, 50, 40, 60
• Traversal in-order should be:
30
– 10, 20, 30, 40, 50, 60, 70
70
20
10
50
40
60
BST.hpp
• insert, find : return iterator
– Create a new iterator every time you return
• Code is almost identical!
Returning std::pair
• virtual std::pair<iterator,bool> insert(const
Data& item)
• An std::pair provides a way to return two
arguments from one function
To return an std::pair:
• return std::make_pair(iterator(node), true);
Iterators
• An iterator object has:
– A pointer to the object that it is iterating over
– A ++ operator so that you can go on to next object
• That’s about it
• Doesn’t really add any new functionality
• Provides a consistent way to iterate over objects
Iterators
• There is no object that contains a collection of
references to all of the created nodes
• BST:
– Contains pointer to root node
• BSTNode:
– Contains pointers to left, right children and parent
• BSTIterator:
– Contains ++ method and a reference to current object
Iterators
• Example traversal with iterators:
cout << "simple traversal test:" << endl;
for(BST<int>::iterator it = b.begin(); it != b.end(); ++it) {
cout << *it << "," << endl;
}
• When ++it executes, successor() function is called on the
current node
• Current node starts at the node with the minimum Data
value
• b.end returns a null pointer
Iterators
• You don’t really NEED iterators
cout << "simple traversal test:" << endl;
• Instead of
for(BST<int>::iterator it = b.begin(); it != b.end(); ++it) {
}
cout << *it << "," << endl;
,you could iterate over nodes directly by calling
“successor” method until it returns a null pointer
• You would have to modify few return types and
protection levels for some variables in this homework
• Iterators are a convenience feature
Iterators
• An iterator does not know
– What is a root node
– Where the iteration has been
– How many more times you can iterate
• An iterator does know
– What is the current object being examined
– What should be the next object to be examined
Tips on homework
•
•
•
•
test_BST is good, but write your own test code there as well
Add lots of cout statements
Example: just print out the tree, without any error checks
Segmentation fault – most likely you are trying to access a
null pointer
• Infinite loop – your tree traversal is incorrect
– Add return statements to break up the function and see which
piece of code causes it
gdb
• Use gdb if segmentation fault
• Turn off compiler optimizations:
• Change CXX flag from –O2 to –O0
in the Makefile
BSTIterator constructor
• Use keyword “this” to access the fields of
current object
• This will allow you to distinguish between
input argument and class field
Destructors
• I have not tested this, but this is how I would do it:
• Add a destructor for BSTNode
– Inside, delete left and right children if exist*
– According to Kacy, it’s OK to delete nullptr
• For clear method for BST:
– Delete root node, reset size
• Destructor for BST:
– Call “clear”
Updated: virtual?
• If destructor is virtual, then subclasses can override the
destructor for proper cleanup
• In the case of BSTNode for the current homework, it
does not matter if destructor is declared to be virtual
• If there are plans to inherit from BSTNode in future
classes, however, the destructor should be declared
virtual to allow override and therefore proper deletion
of future subclass objects
• In short, yes, make it virtual in case there is a subclass
BST functions: insert
Insert(new_data)
• If no root yet, insert at root
• Current = root
• While current.data not equal to new_data
30
– If new_data < current.data
• If left of current is null
– Insert here, return left of current (newly created)
20
• Else
– Current = left of current
– Similar for current.data < new_data
• Return current
10
70
BST functions: find
• Almost exactly like previous slide!
BST functions: begin
• Needs to return the smallest (<) element in
the tree
• Return leftmost child, starting from the root
node
• (probably a while loop)
BSTNode function: successor
Few cases to consider
• Does it have a right child?
– If so, keep taking lefts of it
• No right child:
• Has a parent?
30
– If not, this is the max element
70
20
• If it is left child of parent,
– parent is the successor
• If it is right child of parent:
10
50
– Keep going up until hit a left child link
40
60
Return typename
• Why is the reason to use “typename”?
• What is the difference between line 150 and 151?
• Either one compiles and runs correctly for me
• I will post this question on piazza, perhaps other
TA’s can clarify
Finally
• There are tons of resources online
– Lecture notes from other schools
– Applets and web apps for visualization
– Even source code
• Use them! This is how you would be doing
things at your job in the future
Download