The goal of this assignment is to reinforce the tree data structure in C++. Spec
ID: 3599435 • Letter: T
Question
The goal of this assignment is to reinforce the tree data structure in C++. Specifically, the assignment is to do the following:
Construct a function that will display a binary tree by levels (each level on a separate line), using the included files (node2.h, node2.template, bintree.h, and bintree.template). If there is no node at a position in a level, then the function should display NULL. Only levels that contain at least 1 datum should be displayed.
---------------------------------------
node2.h
---------------------------------------
// FILE: node2.h (part of the namespace main_savitch_6B)
// PROVIDES: A template class for a node in a linked list, and list manipulation
// functions. The template parameter is the type of the data in each node.
// This file also defines a template class: node_iterator.
// The node_iterator is a forward iterators with two constructors:
// (1) A constructor (with a node* parameter) that attaches the iterator
// to the specified node in a linked list, and (2) a default constructor that
// creates a special iterator that marks the position that is beyond the end of a
// linked list. There is also a const_node_iterator for use with
// const node* .
//
// TYPEDEF for the node template class:
// Each node of the list contains a piece of data and a pointer to the
// next node. The type of the data (node::value_type) is the Item type
// from the template parameter. The type may be any of the built-in C++ classes
// (int, char, ...) or a class with a default constructor, an assignment
// operator, and a test for equality (x == y).
// NOTE:
// Many compilers require the use of the new keyword typename before using
// the expression node::value_type. Otherwise
// the compiler doesn't have enough information to realize that it is the
// name of a data type.
//
// CONSTRUCTOR for the node class:
// node(
// const Item& init_data = Item(),
// node* init_link = NULL
// )
// Postcondition: The node contains the specified data and link.
// NOTE: The default value for the init_data is obtained from the default
// constructor of the Item. In the ANSI/ISO standard, this notation
// is also allowed for the built-in types, providing a default value of
// zero. The init_link has a default value of NULL.
//
// NOTE about two versions of some functions:
// The data function returns a reference to the data field of a node and
// the link function returns a copy of the link field of a node.
// Each of these functions comes in two versions: a const version and a
// non-const version. If the function is activated by a const node, then the
// compiler choses the const version (and the return value is const).
// If the function is activated by a non-const node, then the compiler choses
// the non-const version (and the return value will be non-const).
// EXAMPLES:
// const node *c;
// c->link( ) activates the const version of link returning const node*
// c->data( ) activates the const version of data returning const Item&
// c->data( ) = 42; ... is forbidden
// node *p;
// p->link( ) activates the non-const version of link returning node*
// p->data( ) activates the non-const version of data returning Item&
// p->data( ) = 42; ... actually changes the data in p's node
//
// MEMBER FUNCTIONS for the node class:
// const Item& data( ) const <----- const version
// and
// Item& data( ) <----------------- non-const version
// See the note (above) about the const version and non-const versions:
// Postcondition: The return value is a reference to the data from this node.
//
// const node* link( ) const <----- const version
// and
// node* link( ) <----------------- non-const version
// See the note (above) about the const version and non-const versions:
// Postcondition: The return value is the link from this node.
//
// void set_data(const Item& new_data)
// Postcondition: The node now contains the specified new data.
//
// void set_link(node* new_link)
// Postcondition: The node now contains the specified new link.
//
// FUNCTIONS in the linked list toolkit:
// template
// void list_clear(node*& head_ptr)
// Precondition: head_ptr is the head pointer of a linked list.
// Postcondition: All nodes of the list have been returned to the heap,
// and the head_ptr is now NULL.
//
// template
// void list_copy
// (const node* source_ptr, node*& head_ptr, node*& tail_ptr)
// Precondition: source_ptr is the head pointer of a linked list.
// Postcondition: head_ptr and tail_ptr are the head and tail pointers for
// a new list that contains the same items as the list pointed to by
// source_ptr. The original list is unaltered.
//
// template
// void list_head_insert(node*& head_ptr, const Item& entry)
// Precondition: head_ptr is the head pointer of a linked list.
// Postcondition: A new node containing the given entry has been added at
// the head of the linked list; head_ptr now points to the head of the new,
// longer linked list.
//
// template
// void list_head_remove(node*& head_ptr)
// Precondition: head_ptr is the head pointer of a linked list, with at
// least one node.
// Postcondition: The head node has been removed and returned to the heap;
// head_ptr is now the head pointer of the new, shorter linked list.
//
// template
// void list_insert(node* previous_ptr, const Item& entry)
// Precondition: previous_ptr points to a node in a linked list.
// Postcondition: A new node containing the given entry has been added
// after the node that previous_ptr points to.
//
// template
// size_t list_length(const node* head_ptr)
// Precondition: head_ptr is the head pointer of a linked list.
// Postcondition: The value returned is the number of nodes in the linked
// list.
//
// template
// NodePtr list_locate(NodePtr head_ptr, SizeType position)
// The NodePtr may be either node* or const node*
// Precondition: head_ptr is the head pointer of a linked list, and
// position > 0.
// Postcondition: The return value is a pointer that points to the node at
// the specified position in the list. (The head node is position 1, the
// next node is position 2, and so on). If there is no such position, then
// the null pointer is returned.
//
// template
// void list_remove(node* previous_ptr)
// Precondition: previous_ptr points to a node in a linked list, and this
// is not the tail node of the list.
// Postcondition: The node after previous_ptr has been removed from the
// linked list.
//
// template
// NodePtr list_search
// (NodePtr head_ptr, const Item& target)
// The NodePtr may be either node* or const node*
// Precondition: head_ptr is the head pointer of a linked list.
// Postcondition: The return value is a pointer that points to the first
// node containing the specified target in its data member. If there is no
// such node, the null pointer is returned.
//
// DYNAMIC MEMORY usage by the toolkit:
// If there is insufficient dynamic memory, then the following functions throw
// bad_alloc: the constructor, list_head_insert, list_insert, list_copy.
#ifndef MAIN_SAVITCH_NODE2_H
#define MAIN_SAVITCH_NODE2_H
#include // Provides NULL and size_t
#include // Provides iterator and forward_iterator_tag
namespace main_savitch_6B
{
template
class node
{
public:
// TYPEDEF
typedef Item value_type;
// CONSTRUCTOR
node(const Item& init_data=Item( ), node* init_link=NULL)
{ data_field = init_data; link_field = init_link; }
// MODIFICATION MEMBER FUNCTIONS
Item& data( ) { return data_field; }
node* link( ) { return link_field; }
void set_data(const Item& new_data) { data_field = new_data; }
void set_link(node* new_link) { link_field = new_link; }
// CONST MEMBER FUNCTIONS
const Item& data( ) const { return data_field; }
const node* link( ) const { return link_field; }
private:
Item data_field;
node *link_field;
};
// FUNCTIONS to manipulate a linked list:
template
void list_clear(node*& head_ptr);
template
void list_copy
(const node* source_ptr, node*& head_ptr, node*& tail_ptr);
template
void list_head_insert(node*& head_ptr, const Item& entry);
template
void list_head_remove(node*& head_ptr);
template
void list_insert(node* previous_ptr, const Item& entry);
template
std::size_t list_length(const node* head_ptr);
template
NodePtr list_locate(NodePtr head_ptr, SizeType position);
template
void list_remove(node* previous_ptr);
template
NodePtr list_search(NodePtr head_ptr, const Item& target);
// FORWARD ITERATORS to step through the nodes of a linked list
// A node_iterator of can change the underlying linked list through the
// * operator, so it may not be used with a const node. The
// node_const_iterator cannot change the underlying linked list
// through the * operator, so it may be used with a const node.
// WARNING:
// This classes use std::iterator as its base class;
// Older compilers that do not support the std::iterator class can
// delete everything after the word iterator in the second line:
template
class node_iterator
: public std::iterator
{
public:
node_iterator(node* initial = NULL)
{ current = initial; }
Item& operator *( ) const
{ return current->data( ); }
node_iterator& operator ++( ) // Prefix ++
{
current = current->link( );
return *this;
}
node_iterator operator ++(int) // Postfix ++
{
node_iterator original(current);
current = current->link( );
return original;
}
bool operator ==(const node_iterator other) const
{ return current == other.current; }
bool operator !=(const node_iterator other) const
{ return current != other.current; }
private:
node* current;
};
template
class const_node_iterator
: public std::iterator
{
public:
const_node_iterator(const node* initial = NULL)
{ current = initial; }
const Item& operator *( ) const
{ return current->data( ); }
const_node_iterator& operator ++( ) // Prefix ++
{
current = current->link( );
return *this;
}
const_node_iterator operator ++(int) // Postfix ++
{
const_node_iterator original(current);
current = current->link( );
return original;
}
bool operator ==(const const_node_iterator other) const
{ return current == other.current; }
bool operator !=(const const_node_iterator other) const
{ return current != other.current; }
private:
const node* current;
};
}
#include "node2.template"
#endif
---------------------------------------
node2.template
---------------------------------------
---------------------------------------
bintree.h
---------------------------------------
// FILE: bintree.h (part of the namespace main_savitch_10)
// PROVIDES: A template class for a node in a binary tree and functions for
// manipulating binary trees. The template parameter is the type of data in
// each node.
//
// TYPEDEF for the binary_tree_node template class:
// Each node of the tree contains a piece of data and pointers to its
// children. The type of the data (binary_tree_node::value_type) is
// the Item type from the template parameter. The type may be any of the C++
// built-in types (int, char, etc.), or a class with a default constructor,
// and an assignment operator.
//
// CONSTRUCTOR for the binary_tree_node class:
// binary_tree_node(
// const item& init_data = Item( ),
// binary_tree_node* init_left = NULL,
// binary_tree_node* init_right = NULL
// )
// Postcondition: The new node has its data equal to init_data,
// and it's child pointers equal to init_left and init_right.
//
// MEMBER FUNCTIONS for the binary_tree_node class:
// const item& data( ) const <----- const version
// and
// Item& data( ) <----- non-const version
// Postcondition: The return value is a reference to the data from
// this binary_tree_node.
//
// const binary_tree_node* left( ) const <----- const version
// and
// binary_tree_node* left( ) <----- non-const version
// and
// const binary_tree_node* right( ) const <----- const version
// and
// binary_tree_node* right( ) <----- non-const version
// Postcondition: The return value is a pointer to the left or right child
// (which will be NULL if there is no child).
//
// void set_data(const Item& new_data)
// Postcondition: The binary_tree_node now contains the specified new data.
//
// void set_left(binary_tree_node* new_link)
// and
// void set_right(binary_tree_node* new_link)
// Postcondition: The binary_tree_node now contains the specified new link
// to a child.
//
// bool is_leaf( )
// Postcondition: The return value is true if the node is a leaf;
// otherwise the return value is false.
//
// NON-MEMBER FUNCTIONS to maniplulate binary tree nodes:
// tempate
// void inorder(Process f, BTNode* node_ptr)
// Precondition: node_ptr is a pointer to a node in a binary tree (or
// node_ptr may be NULL to indicate the empty tree).
// Postcondition: If node_ptr is non-NULL, then the function f has been
// applied to the contents of *node_ptr and all of its descendants, using
// an in-order traversal.
// Note: BTNode may be a binary_tree_node or a const binary tree node.
// Process is the type of a function f that may be called with a single
// Item argument (using the Item type from the node).
//
// tempate
// void postorder(Process f, BTNode* node_ptr)
// Same as the in-order function, except with a post-order traversal.
//
// tempate
// void preorder(Process f, BTNode* node_ptr)
// Same as the in-order function, except with a pre-order traversal.
//
// template
// void print(const binary_tree_node* node_ptr, SizeType depth)
// Precondition: node_ptr is a pointer to a node in a binary tree (or
// node_ptr may be NULL to indicate the empty tree). If the pointer is
// not NULL, then depth is the depth of the node pointed to by node_ptr.
// Postcondition: If node_ptr is non-NULL, then the contents of *node_ptr
// and all its descendants have been written to cout with the << operator,
// using a backward in-order traversal. Each node is indented four times
// its depth.
//
// template
// void tree_clear(binary_tree_node*& root_ptr)
// Precondition: root_ptr is the root pointer of a binary tree (which may
// be NULL for the empty tree).
// Postcondition: All nodes at the root or below have been returned to the
// heap, and root_ptr has been set to NULL.
//
// template
// binary_tree_node* tree_copy(const binary_tree_node* root_ptr)
// Precondition: root_ptr is the root pointer of a binary tree (which may
// be NULL for the empty tree).
// Postcondition: A copy of the binary tree has been made, and the return
// value is a pointer to the root of this copy.
//
// template
// size_t tree_size(const binary_tree_node* node_ptr)
// Precondition: node_ptr is a pointer to a node in a binary tree (or
// node_ptr may be NULL to indicate the empty tree).
// Postcondition: The return value is the number of nodes in the tree.
#ifndef BINTREE_H
#define BINTREE_H
#include // Provides NULL and size_t
namespace main_savitch_10
{
template
class binary_tree_node
{
public:
// TYPEDEF
typedef Item value_type;
// CONSTRUCTOR
binary_tree_node(
const Item& init_data = Item( ),
binary_tree_node* init_left = NULL,
binary_tree_node* init_right = NULL
)
{
data_field = init_data;
left_field = init_left;
right_field = init_right;
}
// MODIFICATION MEMBER FUNCTIONS
Item& data( ) { return data_field; }
binary_tree_node* left( ) { return left_field; }
binary_tree_node* right( ) { return right_field; }
void set_data(const Item& new_data) { data_field = new_data; }
void set_left(binary_tree_node* new_left) { left_field = new_left; }
void set_right(binary_tree_node* new_right) { right_field = new_right; }
// CONST MEMBER FUNCTIONS
const Item& data( ) const { return data_field; }
const binary_tree_node* left( ) const { return left_field; }
const binary_tree_node* right( ) const { return right_field; }
bool is_leaf( ) const
{ return (left_field == NULL) && (right_field == NULL); }
private:
Item data_field;
binary_tree_node *left_field;
binary_tree_node *right_field;
};
// NON-MEMBER FUNCTIONS for the binary_tree_node:
template
void inorder(Process f, BTNode* node_ptr);
template
void preorder(Process f, BTNode* node_ptr);
template
void postorder(Process f, BTNode* node_ptr);
template
void print(binary_tree_node* node_ptr, SizeType depth);
template
void tree_clear(binary_tree_node*& root_ptr);
template
binary_tree_node* tree_copy(const binary_tree_node* root_ptr);
template
std::size_t tree_size(const binary_tree_node* node_ptr);
}
#include "bintree.template"
#endif
---------------------------------------
bintree.template
---------------------------------------
Explanation / Answer
Algorithm to print the binary tree level by level is geven below:
For each node, first the node is visited and then it’s child nodes are put in a FIFO queue.
printLevelorder(tree)
1) Create an empty queue q
2) temp_node = root /*start from root*/
3) Loop while temp_node is not NULL
a) print temp_node->data.
b) Enqueue temp_node’s children (first left then right children) to q
c) Dequeue a node from q and assign it’s value to temp_node
Following is the C++ code as required:
template <class Item>
void print_LevelOrder(binary_tree_node* root)
{
// Base Case
if (root == NULL) return;
// Create an empty queue for level order tarversal
queue<Node *> q;
// Enqueue Root and initialize height
q.push(root);
q.push(NULL); //For end of level
while (q.empty() == false)
{
// Print front of queue and remove it from queue
Node *node = q.front();
if (node == NULL)
{ cout<<endl;
q.push(NULL);
}
else
{
cout << node->data() << " ";
}
q.pop();
/* Enqueue left child */
if (node->left() != NULL)
q.push(node->left();
/*Enqueue right child */
if (node->right() != NULL)
q.push(node->right();
}
}
Related Questions
drjack9650@gmail.com
Navigate
Integrity-first tutoring: explanations and feedback only — we do not complete graded work. Learn more.