Traverse two-dollar Tree at level
Problem Description: Enter a two-yuan tree, from top to bottom to print each node of the tree, in the same layer from left to right in order to print.
For example, enter:
Output
A node that defines a two-dollar tree (which is actually a two-dollar search tree but does not traverse the algorithm) is:
struct Bstreenode
{
int value;
Bstreenode *left;
Bstreenode *right;
};
Idea: Use the advanced first out of the queue, it is easy to realize. Each time the first element of the queue is fetched, the left and right children are placed in the queue. Until the queue is empty. Entering and exiting the queue in this way is exactly the two-dollar tree traversed by the layer.
Reference code:
function function: Traverse two-Dollar Tree
//function parameter by hierarchy: Proot point to root node
//return value: No
void Levelreverse (Bstreenode *proot)
{
if (proot = = NULL) return
;
Queue<bstreenode *> Nodequeue;
Nodequeue.push (proot);
while (Nodequeue.size ())
{
Bstreenode * pnode = Nodequeue.front ();//Fetch team first element
Nodequeue.pop ();//must be out of the queue
if (pnode->left)//left child
Nodequeue.push (pnode->left);
if (pnode->right)//Right child
Nodequeue.push (pnode->right);
cout<<pnode->value<< ';
}
}
Extension one: The code given above, all nodes are output in the same row. How do you modify the code if you want the same node to be output in the same row?
Train of thought: if we can know the last node of each layer, then more convenient, output the last node of each layer at the same time, output a line feed. Therefore, the key is how to mark the end of each layer. You can consider inserting an empty node after the last point in each layer. For example, the queue first put the root node, because the No. 0 layer has only one node, so put an empty node. Then the nodes in the queue are taken out, the children are placed in the queue, and if an empty node is encountered, the node in the current layer has been traversed, and the queue is exactly the next layer of all nodes. If the current queue is empty, indicating that the next layer has no nodes, it is said that all nodes have been traversed well. If not NULL, insert an empty node to mark the end of the next layer.
Reference code:
void Levelreverse (Bstreenode *proot)
{
if (proot = = NULL) return
;
Queue<bstreenode *> Nodequeue;
Nodequeue.push (proot);
Nodequeue.push (NULL); Place the empty node as the Terminator while
(Nodequeue.size ())
{
Bstreenode * pnode = Nodequeue.front () of the layer.//Take the first element
of the team Nodequeue.pop (); Queue
if (pnode)
{
if (pnode->left)//left child
Nodequeue.push (pnode->left)
must be out; if (pnode->right)//Right child
Nodequeue.push (pnode->right);
cout<<pnode->value<< ';
}
else if (nodequeue.size ())//If the node is empty and the queue is empty, all nodes have access to
{
nodequeue.push (NULL);
cout<<endl;}}}
Extension two: Before the discussion is from the top down, from left to right to traverse the binary tree, then if you want to go up, from left to right to traverse the binary tree, how to modify the code?
Train of thought: The simpler method is to first traverse the binary tree, save all nodes in an array, and simultaneously log each layer in the array at the beginning and end. Then, depending on the starting and ending position, you can print the nodes of the binary tree from the bottom up.
//each level starting and ending position struct Pos {int begin;
int end;
Pos (int b, int e): Begin (b), End (e) {}};
void Levelreverse (Bstreenode *proot) {if (Proot = = NULL) return; Vector<bstreenode*> VEC; Used for storing all nodes vector<pos> Pos;
Used to record the starting and ending position of each layer vec.push_back (proot); int level = 0;
layer of the tree int cur = 0;
int last = 1;
while (cur < vec.size ()) {last = Vec.size (); Pos.push_back (Pos (cur, last)); Records the starting and ending positions of the current layer while (cur < last)//traversing the nodes of the current layer, placing the children in the array {if (Vec[cur]->left)//first left and then right.
If you want to be free to the left, exchange order can vec.push_back (vec[cur]->left);
if (vec[cur]->right) vec.push_back (vec[cur]->right);
cur++; } level++;
Number of layers plus 1} for (int i = Level-1 i >= 0; i--)/Up traversal {for (int j = Pos[i].begin; J < Pos[i].end;
cout<<vec[j]->value<< ';
cout<<endl; }
}
Enter a two-dollar lookup tree to convert the tree to its mirror
Problem Description: Enter a two-yuan lookup tree, convert the tree to its mirror, that is, in the converted two-yuan lookup tree, the Zuozi node is greater than the right subtree node. The recursive and cyclic methods are used to complete the mirroring transformation of the tree.
For example, enter:
Output:
The node that defines the two-dollar lookup tree is:
struct Bstreenode
{
int value;
Bstreenode *left;
Bstreenode *right;
};
Train of thought: The topic requires two methods, recursion and loop, its essence is the same.
Solution One: recursive. Assuming that the current node is pnode, we simply need to exchange the left and right children of the node, then recursively solve the Saozi tree. The code is extremely simple.
Solution Two: Use the loop, need a secondary stack to complete, each take the top of the stack to exchange children, and then the left and right children into the secondary stack, when the stack element is empty, end loop. In fact, whether it is recursive or circular, is the use of the characteristics of the stack to complete.
Reference code:
/function function: Enter a two-yuan lookup tree to convert the tree to its mirror//function parameter: Proot is the root node//return Value: Root node Bstreenode * Mirror_solut
Ion1 (Bstreenode * proot) {if (proot!= NULL) {Bstreenode * pright = proot->right;
Bstreenode * Pleft = proot->left; Proot->left = Mirror_solution1 (pright); Convert right subtree Proot->right = Mirror_solution1 (pleft);
Convert left subtree} return proot;
} Bstreenode * Mirror_solution2 (Bstreenode * proot) {if (proot!= NULL) {stack<bstreenode *> Stk;//Secondary stack Stk.push (Proot);
Press into root node while (Stk.size ()) {Bstreenode *pnode = Stk.top ();
Bstreenode *pleft = pnode->left;
bstreenode* pright = pnode->right;
Stk.pop ();
if (pleft!= NULL) Stk.push (pleft);
if (pright!= NULL) Stk.push (pright); Pnode->left = Pright;
Exchange About children pnode->right = pleft;
} return proot; }
To determine whether an integer sequence is not a two-yuan lookup tree's sequential traversal results
Problem Description: Enter an array of integers to determine if the array is the result of the subsequent traversal of a two-dollar lookup tree. Returns False if it returns true.
For example, enter 5, 7, 6, 9, 11, 10, 8, because this sequence of integers is a sequential traversal of the following tree:
So returns True. If you enter 7, 4, 6, 5, no tree's subsequent traversal of the result is this sequence, so return false.
Train of thought: analysis of the characteristics of the subsequent traversal, the last number of sequences should be the root node, the remaining nodes are divided into two consecutive subsequence, the previous subsequence is less than the last number of values, the latter is more than the last number of subsequence. And then recursively solve these two subsequence.
If it is judged that the sequence traversal is simple, the root node becomes the first number, and the remaining nodes are divided into two consecutive subsequence. If the judgment is in the sequence traversal, more convenient, just scan once, check the sequence is not a good order, if not a good order, it is not the result of the sequence traversal.
turn the two-yuan lookup tree into a sorted two-way list
Problem Description: Enter a two-yuan lookup tree to convert the two-yuan lookup tree into a sorted two-way list. The request cannot create any new nodes, only the pointer is adjusted.
Convert to bidirectional linked list
Train of thought: using the idea of recursion to solve, adjust the left and right subtree of a certain node respectively, after adjusting, the left pointer of the node points to the Zuozi, the right pointer points to the smallest node of the right-hand subtree.
The code is as follows:
Bstreenode * Convert (bstreenode *node)
{
if (node = null) return
null;
Bstreenode *leftmax,*rightmin;
Leftmax = node->left;
Rightmin = node->right;
Find the maximum node for Zuozi while
(Leftmax!= null && leftmax->right!= null)
Leftmax = leftmax->right;
Find the smallest node of the right subtree while
(rightmin!= null && rightmin->left!= null)
rightmin = rightmin->left;
Recursive solution
Convert (node->right);
Convert (node->left);
The left and right subtree are connected at the same root, except for the sibling relationship
if (Leftmax!= NULL)
leftmax->right = node;
if (rightmin!= NULL)
rightmin->left = node;
Node->left = Leftmax;
Node->right = rightmin;
return node;
}
Test, you need to establish a two-fork search tree, the following to establish and traverse the binary tree code.
struct Bstreenode
{
int value;
Bstreenode *left;
Bstreenode *right;
};
Bstreenode * Insert (bstreenode *p, int x)
{
if (p = = NULL)
{
p = new Bstreenode;
P->value = x;
P->left = NULL;
P->right = NULL;
}
else
{
if (P->value > x)
p->left = Insert (p->left, x);
if (P->value < x)
p->right = Insert (p->right, x);
return p;
}
void Traverse (Bstreenode *p)//sequence traversal
{
if (p = = NULL) return
;
Traverse (p->left);
cout<<p->value<< ';
Traverse (p->right);
}
Find and all paths for a value in the two-Dollar Tree (tree)
Problem Description: Enter an integer and a tree of two yuan. A path is formed from the root node of the tree and down to all nodes that have passed through the leaf node. Prints all paths that are equal to the input integer.
For example, enter the integer 22 and the following two-dollar Tree
Then print out two paths: 10, 12 and 10, 5, 7.
The data structure of a binary tree node is defined as:
struct Binarytreenode
{
int data;
Binarytreenode *pleft;
Binarytreenode *pright;
};
Thinking: The thought of recursion. Many of the tree's problems are solved recursively, such as converting a two-yuan lookup tree into a sorted two-way list (tree). The recursive termination condition is either the current empty node or the value of the current node is greater than the remaining and. If the value of the current node equals the remaining sum and is a leaf node, then the print path. Otherwise, the value of the remaining and minus the current node is solved recursively. As for the path of the record, you can use the idea of the stack to achieve.
Code:
void Findpath (Binarytreenode *pnode,int sum,vector<int> &path)
{
//node is empty or value is greater than current and
if (Pnode = = NULL | | Pnode->data > Sum) return
;
Path.push_back (pnode->data);
Judge is not a leaf node
bool IsLeaf = (Pnode->pleft = = NULL && pnode->pright = null)? true:false;
Find a path to print
if (pnode->data = = Sum && isleaf)
{
Vector<int>::iterator iter = Path.begin ();
for (; Iter!= path.end (); iter++)
cout<<*iter<< ';
cout<<endl;
}
else
{
//ask for the remainder and
sum = sum-pnode->data;
Recursive solution
Findpath (pnode->pleft, sum, path);
Findpath (pnode->pright, sum, path);
Path.pop_back ();
}
To determine whether a binary tree is balanced
Problem Description: Enter the root node of a binary tree to determine whether the tree is a balanced binary tree. If the depth of the left and right subtree of any node in a binary tree is not more than 1, then it is a balanced binary tree. For example, the two-fork tree in the figure below is a balanced binary tree:
Train of thought: the first reaction to the tree's problem is recursion. For a tree with a node as its root, only the depth of its left and right subtree can be computed, and if the depth difference is less than 1, then recursion is judged to be a balanced tree, or it is not a balanced binary tree. The key to this problem is to calculate the depth of the tree, and if it is top-down, there will be a lot of repetitive computations. Calculating the depth of a tree with a root of 1 involves a subtree of 2 root and 3. Calculating the depth of a tree with a root of 2 involves a subtree of 4 root and 5. Because you want to traverse each node, determine whether the tree that is rooted at the node is a balanced binary tree. Therefore, the depth of a tree with a root of 1 is computed, and the depth of a tree with a root of 2 is computed repeatedly, with 4 as the root and 5 as the root of the subtree.
The elimination of repetition means that the depth of the previously computed subtree can be recorded, and the next time it is used, it is not recalculated. This requires a bottom-up calculation depth. Fortunately, the problem of solving the tree recursively is the bottom-up process. Because we need to derive the solution of the subtree in the recursive solution, the solution of the subtree will eventually be converted into the solution of the leaf node. You can use the method of subsequent traversal to traverse each node. First judged that its left and right subtree is not a balanced binary tree, while recording the depth of the left and right subtree, and then judge the node as the root of the tree is not a balanced binary tree, as the depth of the tree calculation is convenient, take the left and right subtree in the larger depth of +1 on it. The depth of the left and right subtree is already calculated in the recursive solution, and there is no need to repeat the computation.
Reference code:
struct Binarytreenode
{
int data;
Binarytreenode *pleft;
Binarytreenode *pright;
};
function function: To determine whether the binary tree is balanced
//function parameter: Proot is the root node, pdepth is the depth of the root node.
//Return value: is the balanced
bool isbalanced (binarytreenode *proot, int *pdepth)
{
if (proot = NULL)
{ c14/>*pdepth = 0;
return true;
}
int leftdepth, rightdepth; The depth of the left and right subtree
if (isbalanced (Proot->pleft, &leftdepth) &&
isbalanced (proot->pright, & rightdepth))
{
int diff = leftdepth-rightdepth;
if (diff = = 0 | | | diff = = 1 | | | diff = = 1)//difference is 0 or 1 or-1
{
*pdepth = 1 + (leftdepth > rightdepth? leftdepth:rig htdepth);
return true;
}
else return
false;
return false;