Professional Documents
Culture Documents
DATA STRUCTURES
AND
ALGORITHMS
Lecture Notes 10
Trees
Spring 2008
Depth 0
(root)
Depth 1
Depth 1
Depth 2
This is a
binary tree
Search algorithm:
1. if the tree is empty, return NULL
2. if target equals to root node’s data, return that data
3. if target < root node data, return search(left subtree)
4. otherwise return search(right subtree)
struct TreeNode {
. . .
Object element;
TreeNode *firstChild;
TreeNode *nextSibling;
}
Preorder:
a, b, d, g, e,
h, c, f, i, j
Inorder:
d, g, b, h, e,
a, i, f, j, c
Postorder:
g, d, h, e, b,
i, j, f, c, a
input is ab+cde+**
c, d, e are read
– for each a one-node tree
is created
– A pointer to the
corresponding tree is
pushed onto the stack.
input is ab+cde+**
+ is read
– two trees are merged
input is ab+cde+**
* is read
– pop two tree pointers
and form a new tree
with a * as root
// Constructor
BTNode(const Item_Type& the_data,
BTNode<Item_Type>* left_val = NULL,
BTNode<Item_Type>* right_val = NULL) :
data(the_data), left(left_val), right(right_val) {}
Function Behavior
Binary_Tree<Item_Type> get_left_subtree() Returns the left subtree.
const
Binary_Tree<Item_Type> get_right_subtree() Returns the right subtree.
const
const Item_Type& get_data() const Returns the data in the root.
bool is_leaf() const Returns true if this tree is a leaf.
bool is_null() const Returns true if this tree is an
empty tree.
string to_string() const Returns a string representation
of the tree.
static Binary_Tree<Item_Type> Constructs a binary tree by
read_binary_tree(std::istream& in) reading its data from input
stream in.
static Binary_Tree<Item_Type>
read_binary_tree(std::istream& in);
protected:
// Protected constructor
Binary_Tree(BTNode<Item_Type>* new_root) :
root(new_root) {}
// Data Field
BTNode<Item_Type>* root;
}; // End Binary_Tree
template<typename Item_Type>
Binary_Tree<Item_Type>
Binary_Tree<Item_Type>::get_right_subtree() const {
if (root == NULL) {
throw std::invalid_argument
("get_right_subtree on null tree");
}
return Binary_Tree<Item_Type>(root->right);
}
template<typename Item_Type>
bool Binary_Tree<Item_Type>::is_leaf() const {
if (root != NULL) {
return root->left == NULL && root->right == NULL;
} else
return true;
}
template<typename Item_Type>
std::string Binary_Tree<Item_Type>::to_string() const {
std::ostringstream os;
if (is_null())
os << "NULL\n";
else {
os << *root << '\n';
os << get_left_subtree().to_string();
os << get_right_subtree().to_string();
}
return os.str();
}
1. if root is NULL
2. item not in tree: return NULL
3. compare target and root->data
4. if they are equal
5. target is found, return root->data
6. else if target < root->data
7. return search(left subtree)
8. else
9. return search(right subtree)
template<typename Item_Type>
class Binary_Search_Tree : public Binary_Tree<Item_Type>
{
public:
// Constructor
Binary_Search_Tree() : Binary_Tree<Item_Type>() {}
template<typename Item_Type>
const Item_Type* Binary_Search_Tree<Item_Type>::find(
BTNode<Item_Type>* local_root,
const Item_Type& target) const {
if (local_root == NULL)
return NULL;
if (target < local_root->data)
return find(local_root->left, target);
else if (local_root->data < target)
return find(local_root->right, target);
else
return &(local_root->data);
}
template<typename Item_Type>
bool Binary_Search_Tree<Item_Type>::insert(
BTNode<Item_Type>*& local_root,
const Item_Type& item) {
if (local_root == NULL) {
local_root = new BTNode<Item_Type>(item);
return true;
} else {
if (item < local_root->data)
return insert(local_root->left, item);
else if (local_root->data < item)
return insert(local_root->right, item);
else
return false;
}
}
GIT – Computer Engineering Department 67
Removing from a Binary Search Tree
Item not present: do nothing
Item present in leaf: remove leaf (change to null)
Item in non-leaf with one child:
Replace current node with that child
Item in non-leaf with two children?
– Find largest item in the left subtree
– Recursively remove it
– Use it as the parent of the two subtrees
– (Could use smallest item in right subtree)
template<typename Item_Type>
bool Binary_Search_Tree<Item_Type>::erase(
BTNode<Item_Type>*& local_root,
const Item_Type& item) {
if (local_root == NULL) {
return false;
} else {
if (item < local_root->data)
return erase(local_root->left, item);
else if (local_root->data < item)
return erase(local_root->right, item);
else { // Found item
. . .
template<typename Item_Type>
void Binary_Search_Tree<Item_Type>::replace_parent(
BTNode<Item_Type>*& old_root,
BTNode<Item_Type>*& local_root) {
if (local_root->right != NULL) {
replace_parent(old_root, local_root->right);
} else {
old_root->data = local_root->data;
old_root = local_root;
local_root = local_root->left;
}
}
3
8 1 7 2 0 1 2 3 4 5
11 8 7 2 5 4
2 3 5 4 4 5
private:
Container the_data;
Compare comp;
};
0 1
0 e=103 0 1
10 a=64
0 1
110 d=32
0 1
struct Compare_Huffman_Trees
{
bool operator()(const Binary_Tree<Huff_Data>& left_tree,
const Binary_Tree<Huff_Data>& right_tree) {
double wLeft = left_tree.get_data().weight;
double wRight = right_tree.get_data().weight;
return wLeft > wRight;
}
};