In the last blog, we detailed the tree and two-fork tree data structure and its characteristics, this time, we use C + + to implement the binary tree definition of binary tree node structure
The binary tree needs to define pointers to the nodes of the left child and the right child, as well as stored data; we'll write out the constructor here
Defines a binary tree node
template<typename t>
struct binarytreenode
{
T _data;//data
Binarytreenode <T> *_left;//left child
binarytreenode<t> *_right;//right child
binarytreenode (const t& x)//node constructor
: _data (x)
, _left (null)
, _right (null)
{}
};
define a binary tree structure
Here we define the structure of the binary tree, first implementing his constructs, destructors, copy constructors, and assignment operator overloads.
Implement the Create, Copy, and Destory three recursive functions by calling protected.
Define binary tree Template<typename t> class BinaryTree {typedef binarytreenode<t> node;//Rename to Node Public:binarytree
(): _root (NULL) {} BinaryTree (t* arr, const size_t Size,const t& = T ()) {assert (invalid);
size_t index = 0; _root = Createtree (arr, size, index, invalid);/////////////////////() Create tree in recursive form, protect member function by invoking Createtree ()}//Copy constructor BinaryTree (const BINARYTR
ee& b) {_root = Copy (b._root);
}///assignment operator overload binarytree&operator= (BinaryTree t) {if (this!= &t) {Std::swap (t._root, _root);
return *this;
}//destructor ~binarytree () {if (_root!= NULL) {destory (_root);
_root = NULL;
}//First-order traversal, in-sequence traversal, subsequent traversal of void Prevorder ();
void Inorder ();
void Postorder ();
Three kinds of ergodic methods are not recursive form void Prevordernonr ();
The recursive traversal of the sequence, only use the position of the press stack access element to the stack when Access can void Inordernonr ();
After the sequence is not recursive traversal void Postordernonr ();
Sequence traversal void Levelorder ();
To find the number of nodes of the binary tree size_t size ();
To find the depth of the binary tree size_t Depth ();
Find the leaf node of the binary tree size_t getleafsize (); To find the number of K-layer nodes Size_T Getklevelsize (size_t K);
protected:node* _root; Constructs a binary tree node* createtree (t* arr,const size_t size, size_t& index,const, t& invalid = T ()) {//array not complete and no
The illegal value if (Index < size && arr[index]!=invalid) {//Generation node recursively constructs node* root = new node (arr[index));
Root->_left = Createtree (arr,size,++index,invalid);
Root->_right = Createtree (arr, size, ++index, invalid);
Returns the generated node return root;
}//return null;
}///recursive destroy binary tree void Destory (node* root) {assert (root);
is not null, recursively destroys the left subtree if (root->_left!= NULL) destory (root->_left);
Destroy complete assignment is null root->_left = NULL;
is not null, recursively destroys the right subtree if (root->_right!= NULL) destory (root->_right);
Destroy complete assignment is null root->_right = NULL;
Destroys the current node delete[] root;
root = NULL;
Return
///Recursive copy two-fork tree node* copy (node* root) {//root is empty if (root = null) return null; Call node's constructor to generate a nodes node* NewNode = new node (ROOT->_data);
Recursive copy newnode->_left = copy (Root->_left);
Newnode->_right = Copy (root->_right);
return newnode;
}
};
recursive traversal method of two-fork tree (1) First Order
This is done recursively by calling the protected member function _prevorder to iterate through the
The void Prevorder ()
{
///adopts recursive method to call the _prevorder function within protected, as well as the preface and the subsequent sequence
_prevorder (_root);
cout << Endl;
}
Protected:
void _prevorder (node* root)
{
//node is NULL, returns
if (root = NULL) return
;
First access to the node cout << root->_data << "";
Recursive access to left subtree
_prevorder (root->_left);
Access the right subtree
_prevorder (root->_right) After Zuozi access is complete;
(2) middle order
Similarly, call the protected _inorder ()
void Inorder ()
{
_inorder (_root);
cout << Endl;
}
Protected:
void _inorder (node* root)
{
//node NULL returns
if (root = null) return
;
First access to the left subtree
_inorder (root->_left);
Access to the root node after access is complete
cout << root->_data << "";
Access to the right subtree
_inorder (root->_right);
}
(3) subsequent
void Postorder ()
{
_postorder (_root);
cout << Endl;
}
protected:
void _postorder (node* root)
{
if (root = NULL) return
;
First access to the left subtree
_postorder (root->_left);
Zuozi visited the right subtree
_postorder (root->_right);
Zuozi the right subtree is finished, access the node
cout << root->_data << "";
}
Traversal method of binary tree in non-recursive Way
(1) First Order
All recursive programs can be implemented by non recursive return;
A simple recursive program can be changed into a loop implementation;
All recursive programs can be implemented by stacks;
So now we're going to use the STL stack
Public:
void Prevordernonr ()
{
//define a stack and a pointer variable
stack<node*> s;
node* cur = _root;
In cur, or when the stack is empty while
(cur | |!s.empty ())
{
//recursively traverses the left word while
(cur)
{
//access element
cout << cur->_data << "";
Carry on the pressure stack
s.push (cur);
Point to left child
cur = cur->_left;
}
All the way to the left, at this time cur is empty
//Take the top of the stack
node* = S.top ();
Out Stack
s.pop ();
Access to the right child
cur = top->_right;
}
cout << Endl;
}
(2) Middle order
The same as using the stack, only to change the location of the access element
Public:
//In-sequence traversal of the non-recursive, only use the position of the press stack access elements to the stack when access can be
void Inordernonr ()
{
//define a stack and pointer variable cur
node* cur = _ root;
stack<node*> s;
To determine whether the end while
(cur | |!s.empty ())
{
//loop press the left word while
(cur)
{
s.push (cur);
In order, do not access element
cur = cur->_left;
}
First node* top = S.top ();
S.pop ();
At this point again access element
cout << top->_data << "";
cur = top->_right;
}
}
(3) subsequent
After the subsequent words, out need to determine the right subtree access, or you will be wrong
Public:
//sequential non-recursive traversal
void Postordernonr ()
{
///In comparison with the ordinal, first order, a prev pointer is defined to save the last accessed element
node* prev = NULL;
Defines a stack s and a temporary variable pointing to a node cur
node* cur = _root;
stack<node*> s;
Determine if End while
(cur | |!s.empty ())
{
//recursive left subtree while
(cur)
{
//Still not accessing element
S.push ( cur);
cur = cur->_left;
}
Take the top element of the stack to judge
node* tops = S.top ();
If the right subtree of the still element is empty or the right subtree has been accessed if
(top->_right = NULL | | top->_right = = prev)
{
//print root
cout << top->_data << "";
The element that has just been visited let Prev Save up
prev = top;
Out Stack
s.pop ();
}
Right subtree is not empty and has not been accessed
else
{
//access right word
cur = top->_right;
}
}}
(4) Sequence
Sequence traversal, we need to use another data structure---queue
Each time the root node into the stack, out of the stack after its children into the stack;
With this theory to push
Public:
//sequence traversal
void Levelorder ()
{
if (_root = NULL) return
;
Using queues to store nodes of each layer
queue<node*> q;
Pressing into the root node
q.push (_root);
Queue is empty, access ended while
(Q.empty () = False)
{
//Fetch team HEAD element, Access
node* tmp = Q.front ();
cout << tmp->_data << "";
The first element of the pop-up queue
q.pop ();
Which child is not empty, presses the child
if (tmp->_left!= NULL)
Q.push (tmp->_left);
if (tmp->_right!= NULL)
Q.push (tmp->_right);
}
cout << Endl;
}
Recursive depth, number of nodes, number of leaf nodes and number of K-layer nodes
Public://Find the number of nodes in the binary tree size_t size () {return _size (_root);
}//Find the depth of the binary tree size_t Depth () {return _depth (_root);
The leaf node of the binary tree size_t getleafsize () {size_t count = 0;
_getleafsize (_root,count);
return count;
The number of K-Layer nodes size_t getklevelsize (size_t k) {assert (K > 0);
Return _getklevelsize (_ROOT,K);
Protected: size_t _size (node* root) {if (root = NULL) return 0; Recursively solves the child problem.
Returns the number of nodes of the left subtree + the number of nodes in the right subtree + own return _size (root->_left) + _size (root->_right) + 1;
size_t _depth (node* root) {if (root = NULL) return 0;
The depth of the left subtree and the depth of the right subtree are obtained, and the return value is used to receive size_t leftdepth = _depth (root->_left);
size_t rightdepth = _depth (root->_right); Returns the largest + layer depth in the subtree 1 return leftdepth > rightdepth?
Leftdepth + 1:rightdepth + 1; ///through the incoming reference count to Count void _getleafsize (node* root,size_t &count) {if (root->_left= = NULL && Root->_right = null) {count++;
Return
} if (Root->_left!= NULL) _getleafsize (Root->_left,count);
if (root->_right!=null) _getleafsize (Root->_right,count);
//K-level node size_t _getklevelsize (node* root, size_t k) {if (root = NULL) return 0;
if (k = = 1) return 1;
Return _getklevelsize (root->_left,k-1) + _getklevelsize (root->_right,k-1); }