I've been trying to map out a binary search tree in C++, but I'm having some difficulty with my remove method. If it worked, it would basically use an inorder traversal to search the tree for a node with the value passed into the method, recursively calling itself so long as it's actually on a node that exists - if it's not, then it promptly returns itself and allows the method that's one "step up" in the recursion to check the area it's in, just like a normal inorder traversal. The problem is, my if statement checking to see if the current node exists seems to just not work, always returning true and causing it to infinitely iterate down the left branch that has a reasonable endpoint. Here's the code I'm using:
template<class T>
void binSTree<T>::remove(Node<T>*& nowOn, const T& input)
{
if(nowOn) //This is the part that breaks. My cout statement has proved that by repeating itself an infinite number of times.
{
cout << "So we know it's entering this.";
if(nowOn->left)
remove(nowOn->left, input);
if(nowOn->data == input)
{
if(!(nowOn->left) && !(nowOn->right))
{
delete nowOn;
}
if(nowOn->left && !(nowOn->right))
{
if(!(pred(nowOn)->left->data == input))
pred(nowOn)->left = nowOn->left;
else if(!(pred(nowOn)->right->data == input))
pred(nowOn)->right = nowOn->left;
delete nowOn;
}
if(nowOn->right && !(nowOn->left))
{
if(!(pred(nowOn)->left->data == input))
pred(nowOn)->left = nowOn->right;
else if(!(pred(nowOn)->right->data == input))
pred(nowOn)->right = nowOn->right;
delete nowOn;
}
if(nowOn->left && nowOn->right)
{
if(!(pred(nowOn)->left->data == input))
pred(nowOn)->left = nowOn->right;
else if(!(pred(nowOn)->right->data == input))
pred(nowOn)->right = nowOn->right;
delete nowOn;
}
}
if(nowOn->right)
remove(nowOn->right, input);
}
else
{
return;
}
return;
}
The pred method is a simple, non-recursive stack that runs through the entire tree to find something where either the left or right nodes are the input node. That's been tested and works just fine. As for the node, here's the code for it:
template < class T > class binTree; // forward declaration
template < class T > class binSTree; // forward declaration
template < class T > class Node {
friend class binTree < T >; // binTree is friend
friend class binSTree < T >; // binSTree is friend
public:
// default constructor
Node ( const T& x = T ( ), Node < T >* l = 0, Node < T >* r = 0 ) :
data ( x ), left ( l ), right ( r ) { }
private:
T data; // data component
Node < T > *left, *right; // left and right links
};
binTree is a different binary tree that can't delete, but has its own insert, height, size, and inorder traversal methods. binSTree, the class with the remove method, is a derived class of binTree. I'm reasonably certain that the error comes from me trying to check a Node<T>*&, the *& part specifically, with an if statement, but I can't figure out how to do anything about it. Anyone have any ideas?
Related
I want a function that traverses a binary tree with the Euler traversal (this is how it works). Of course this is easily achievable with recursion - I know how that works. But now I want to implement an iterative version of this algorithm using a stack instead of recursion. My idea was to store the direction we are traversing on the stack as well. My code is not working and I can somehow not wrap my mind around this problem. Can you give me any hints on how to tackle this issue? Here is my code so far:
#define LEFT (struct Node*) 0xBADF00D
#define RIGHT (struct Node*) 0xDEADBEEF
struct Node {
int data;
struct Node* parent;
struct Node* left;
struct Node* right;
};
void eulerTree(struct Node* root)
{
stack<struct Node*> s;
s.push(root);
s.push(RIGHT);
s.push(root);
s.push(LEFT);
while(!s.empty()) {
struct Node* direction = s.top(); s.pop();
struct Node* node = s.top(); s.pop();
visit(node);
if(direction == LEFT) {
if(node->left) {
s.push(node->left);
s.push(RIGHT);
s.push(node->left);
s.push(LEFT);
}
}
if(direction == RIGHT) {
if(node->right) {
s.push(node->right);
s.push(RIGHT);
s.push(node->right);
s.push(LEFT);
}
}
}
}
Think of a simple binary tree to start with :
1
2 3
Euler traversal for this is : 1 2 1 3 1
You see the pattern here:
root, root->left, root, root->right, root
So your stack order should be:
root
root->left
root
root->right
root
But what if your root is a leaf? then don't push anything just print the value.
Also once you push the nodes on left, right make sure you set them as 0 for the root so that you don't keep pushing them forever.
With that said, the code in cpp would be:
Edit:
The previous code I posted has a bug. The correct code is below:
void eulerTree(struct Node* root)
{
stack<struct Node*> s;
s.push(root);
while(!s.empty()) {
struct Node* node = s.pop();
visit(node);
if(node->right) {
s.push(node);
s.push(node->right);
}
if(node->left) {
s.push(node);
s.push(node->left);
}
node->left = 0;
node->right = 0;
}
}
Without destroying the tree:
But yes, even though the code is simple this destroys the tree which is not desired. To tackle this problem I am going to use two properties for leaves of the tree in a euler tree traversal.
If the leaf is left child of the parent and the right child of that parent is null
( or )
if the leaf is right child
-after this leaf is printed then print the parent nodes all the way up the root.
If the leaf is left child and the right child is not null
-after this leaf is printed then print only its immediate parent.
To illustrate look at the below tree.
1
2 3
4 5 6 7
If the leaf is 5 then after it is printed, then print all the parents upto 1.
If the leaf is 4 then after it is printed, then print just its immediate parent 2.
To simplify implementation I am going to use a parent stack in addition to the current stack.
void eulerTree(struct Node* root) {
stack<struct Node*> s;
s.push(root);
struct Node* original = root;
stack<struct Node*> p;
while(!s.empty()) {
struct Node* node = s.top();
s.pop();
visit(node);
if ( !node->right && !node->left && !p.empty() ) {
struct Node* pNode = p.top();
if ( pNode->left == node && !pNode->right || pNode->right == node ) {
while ( !p.empty() ) {
visit(p.top());
p.pop();
}
p.push(original);
} else {
visit(pNode);
}
}
if(node->left || node->right) {
p.push(node);
}
if(node->right) {
s.push(node->right);
}
if(node->left) {
s.push(node->left);
}
}
}
A recursive implementation might look like this:
void euler(Node *n) {
visit(n);
if (n->left) {
euler(n->left);
visit(n);
}
if (n->right) {
euler(n->right);
visit(n);
}
}
Now whenever this makes a recursive call, the call stack is used to remember where we are in the code and what we're doing. Then we start again at the top and when we're done, that information is popped of the stack and we continue where we left off.
If you're going to do it iteratively with your own stack, you have to do the same job yourself. You have to remember enough to continue where you left off.
We have to remember which node we were working on of course, but also there are two recursive calls so, so there are 2 possible places we might have to return to. When we return from a recursive call, then either:
We have just done the n->left call and should continue on to check n->right; OR
We have just done the n->right call and should continue with the final visit of n
We could store some extra information on the stack to distinguish these two cases, but that is not necessary for this particular algorithm. From the descriptions above, you can see that we can distinguish these cases based on the node we're returning from -- it's either n->left or n->right.
So, just storing the waiting node in the stack, we can write an iterative version like this:
int state=0; // 0 => initial visit, 1 => just did left, 2 => just did right
Node *n = root;
while (n) {
visit(n);
if (n->left && state<1) {
stack.push(n);
n=n->left;
state=0;
continue;
}
if (n->right && state<2) {
stack.push(n);
n=n->right;
state=0;
continue;
}
if (stack.empty())
break; // done
Node *child=n;
n = stack.pop();
state = (child == n->left ? 1 : 2);
}
I wanted to sort a linked list containing 0s, 1s or 2s. Now, this is clearly a variant of the Dutch National Flag Problem.
http://en.wikipedia.org/wiki/Dutch_national_flag_problem
The algorithm for the same as given in the link is:
"Have the top group grow down from the top of the array, the bottom group grow up from the bottom, and keep the middle group just above the bottom. The algorithm stores the locations just below the top group, just above the bottom, and just above the middle in three indexes. At each step, examine the element just above the middle. If it belongs to the top group, swap it with the element just below the top. If it belongs in the bottom, swap it with the element just above the bottom. If it is in the middle, leave it. Update the appropriate index. Complexity is Θ(n) moves and examinations."
And a C++ implementation given for the same is:
void threeWayPartition(int data[], int size, int low, int high) {
int p = -1;
int q = size;
for (int i = 0; i < q;) {
if (data[i] == low) {
swap(data[i], data[++p]);
++i;
} else if (data[i] >= high) {
swap(data[i], data[--q]);
} else {
++i;
}
}
}
My only question is how do we traverse back in a linked list like we are doing here in an array?
A standard singly-linked list doesn't allow you to move backwards given a linked list cell. However, you could use a doubly-linked list, where each cell stores a next and a previous pointer. That would let you navigate the list forwards and backwards.
However, for the particular problem you're trying to solve, I don't think this is necessary. One major difference between algorithms on arrays and on linked lists is that when working with linked lists, you can rearrange the cells in the list to reorder the elements in the list. Consequently, the algorithm you've detailed above - which works by changing the contents of the array - might not actually be the most elegant algorithm on linked lists.
If you are indeed working with linked lists, one possible way to solve this problem would be the following:
Create lists holding all values that are 0, 1, or 2.
Remove all cells from the linked list and distribute them into the list of elements that are equal to 0, 1, or 2.
Concatenate these three lists together.
This does no memory allocation and purely works by rearranging the linked list cells. It still runs in time Θ(n), which is another plus. Additionally, you can do this without ever having to walk backwards (i.e. this works on a singly-linked list).
I'll leave the complete implementation to you, but as an example, here's simple C++ code to distribute the linked list cells into the zero, one, and two lists:
struct Cell {
int value;
Cell* next;
}
/* Pointers to the heads of the three lists. */
Cell* lists[3] = { NULL, NULL, NULL };
/* Distribute the cells across the lists. */
while (list != NULL) {
/* Cache a pointer to the next cell in the list, since we will be
* rewiring this linked list.
*/
Cell* next = list->next;
/* Prepend this cell to the list it belongs to. */
list->next = lists[list->value];
lists[list->value] = list;
/* Advance to the next cell in the list. */
list = next;
}
Hope this helps!
As others have said, there is no way to "back up" in a linked list without reverse links. Though it's not exactly an answer to your question, the sort can be easily accomplished with three queues implementing a bucket sort with three buckets.
The advantage of queues (vice pushing on stacks) is that the sort is stable. That is, if there are data in the list nodes (other than the 0,1,2-valued keys), these will remain in the same order for each key.
This is only one of many cases where the canonical algorithm for arrays is not the best for lists.
There is a very slick, simple way to implement the queues: circularly linked lists where the first node, say p, is the tail of the queue and consequently p->next is is the head. With this, the code is concise.
#include <stdio.h>
#include <stdlib.h>
typedef struct node_s {
struct node_s *next;
int val;
int data;
} NODE;
// Add node to tail of queue q and return the new queue.
NODE *enqueue(NODE *q, NODE *node)
{
if (q) {
node->next = q->next;
q->next = node;
}
else node->next = node;
return node;
}
// Concatenate qa and qb and return the result.
NODE *cat(NODE *qa, NODE *qb)
{
NODE *head = qa->next;
qa->next = qb->next;
qb->next = head;
return qb;
}
// Sort a list where all values are 0, 1, or 2.
NODE *sort012(NODE *list)
{
NODE *next = NULL, *q[3] = { NULL, NULL, NULL};
for (NODE *p = list; p; p = next) {
next = p->next;
q[p->val] = enqueue(q[p->val], p);
}
NODE *result = cat(q[0], cat(q[1], q[2]));
// Now transform the circular queue to a simple linked list.
NODE *head = result->next;
result->next = NULL;
return head;
}
int main(void)
{
NODE *list = NULL;
int N = 100;
// Build a list of nodes for testing
for (int i = 0; i < N; ++i) {
NODE *p = malloc(sizeof(NODE));
p->val = rand() % 3;
p->data = N - i; // List ends up with data 1,2,3,..,N
p->next = list;
list = p;
}
list = sort012(list);
for (NODE *p = list; p; p = p->next)
printf("key val=%d, data=%d\n", p->val, p->data);
return 0;
}
This is now a complete simple test and it runs just fine.
This is untested. (I will try to test it if I get time.) But it ought to be at least very close to a solution.
Using a doubly linked list. If you have already implemented a linked list object and the related link list node object, and are able to traverse it in the forward direction it isn't a whole bunch more work to traverse in the reverse direction.
Assuming you have a Node object somewhat like:
public class Node
{
public Node Next;
public Object Value;
}
Then all you really need to do is change you Node class and you Insert method(s) up a little bit to keep track of of the Node that came previously:
public class Node
{
public Node Next;
public Node Previous;
public Object Value;
}
public void Insert(Node currentNode, Node insertedNode)
{
Node siblingNode = currentNode.Next;
insertedNode.Previous = currentNode;
insertedNode.Next = siblingNode;
if(siblingNode!= null)
siblingNode.previous = insertedNode;
currentNode.next = insertedNode;
}
PS Sorry, I didn't notice the edit that included the C++ stuff so it's more C#
Works for all cases by CHANGING NODES rather than NODE DATA.. Hoping its never too late!
METHOD(To throw some light on handling corner cases):
1. Keep three dummy nodes each for 0,1,2;
2. Iterate throught the list and add nodes to respective list.
3. Make the next of zero,one,two pointers as NULL.
4. Backup this last nodes of each list.
5. Now handle 8 different possible cases to join these list and Determine the HEAD.
zero one two
0 0 0
0 0 1
0 1 0
0 1 1
1 0 0
1 0 1
1 1 0
1 1 1
An implementation of this in C++.
Node* sortList(Node *head)
{
struct Node dummyzero,dummyone,dummytwo;
dummyzero.next = dummyone.next = dummytwo.next = NULL;
struct Node *zero =&dummyzero,*one = &dummyone,*two=&dummytwo;
Node *curr = head,*next=NULL;
while(curr)
{
next = curr->next;
if(curr->data==0)
{
zero->next = curr;
zero = zero->next;
}
else if(curr->data==1)
{
one->next = curr;
one = one->next;
}
else
{
two->next = curr;
two = two->next;
}
curr = next;
}
zero->next = one->next = two->next =NULL; //Since this dummynode, No segmentation fault here.
Node *zerolast = zero,*onelast = one,*twolast = two;
zero = dummyzero.next;
one = dummyone.next;
two = dummytwo.next;
if(zero==NULL)
{
if(one==NULL)
head = two;
else
{
head = one;
onelast->next = two;
}
}
else
{
head = zero;
if(one==NULL)
zerolast->next = two;
else
{
zerolast->next = one;
onelast->next = two;
}
}
return head;
}
The idea is to use dutch flag sorting algorithm, with a slight modification:
sort 0's and 1's as per dutch flag method,
But for 2's instead of adding them at the end of list, keep them in a separate linked list.
And finally append the 2's list to the sorted list of 0's and 1's.
Node * sort012_linked_list(Node * head) {
if (!head || !head->next)
return head;
Node * head_of_2s = NULL;
Node * prev = NULL;
Node * curr = head;
while (curr) {
if (curr->data == 0) {
if (prev == NULL || prev->data == 0) {
prev = curr;
curr = curr->next;
}
else {
prev->next = curr->next;
curr->next = head;
head = curr;
curr = prev->next;
}
}
else if (curr->data == 1) {
prev = curr;
curr = curr->next;
}
else { // curr->data == 2
if (prev == NULL) {
head = curr->next;
curr->next = head_of_2s;
head_of_2s = curr;
curr = head;
}
else {
prev->next = curr->next;
curr->next = head_of_2s;
head_of_2s = curr;
curr = prev->next;
}
}
}
if (prev)
prev->next = head_of_2s;
return head;
}
Assume you have a generic k-ary tree like this one or this one
Repeating the latter here:
template <typename T>
struct TreeNode
{
T* DATA ; // data of type T to be stored at this TreeNode
vector< TreeNode<T>* > children ;
void insert( T* newData ) ;
// runs f on this and all children of this
void preorder( function<void (T*)> f )
{
f( this->DATA ) ; // exec f on this
for( int i = 0 ; i < children.size(); i++ )
children[i]->preorder( f ) ; // exec f on each child
}
} ;
template <typename T>
struct Tree
{
TreeNode<T>* root;
// TREE LEVEL functions
void clear() { delete root ; root=0; }
void insert( T* data ) { if(root)root->insert(data); }
} ;
Now normally, you have pre-order and post-order traversals as recursive member functions of TreeNode as shown above. But say you don't want to be passing functions around, you want to visit each node in the tree from outside the class (ie just given a Tree object).
How can you do it?
I would approach this by defining a PreorderIterator class that maintained state about where it was in the traversal. It would have methods for returning the current node and for advancing one step in the traversal.
You would have to be careful if the tree structure could mutate during the life of the iterator. Perhaps the tree could maintain a modification count; the iterator could capture the count at the start and check for changes at each access (and throwing an exception if it found one).
One easy approach is to load the tree into a list and then walk the list when you need. The list would only be a list of pointers and therefore not that expensive. To do that you would use a modified version of the trie traversal algorithm:
void traverse(Node n){
if(null == n) return;
for( Node c: n.children){
visit( c );
traverse( c );
}
}
You would use the visit to actually load your list. So something like
List<Node> getListToIterate(Node n){
List<Node> result = new ArrayList<Node>();
traverse(n,resutl);
return result;
}
void traverse(Node n, List list){
if(null == n) return;
for( Node c: n.children){
list.add( c );
traverse( c );
}
}
Also, if you decide, you can wrap this algorithm in a TreeIterator class that would track where you are in the list.
Three types of tree traversals are inorder, preorder, and post order.
A fourth, less often used, traversal is level-order traversal. In a
level-order traveresal, all nodes at depth "d" are processed before
any node at depth d + 1. Level-order traversal differs from the other
traversals in that it is not done recursively; a queue is used,
instead of the implied stack of recursion.
My questions on above text snippet are
Why level order traversals are not done recursively?
How queue is used in level order traversal? Request clarification with Pseudo code will be helpful.
Thanks!
Level order traversal is actually a BFS, which is not recursive by nature. It uses Queue instead of Stack to hold the next vertices that should be opened. The reason for it is in this traversal, you want to open the nodes in a FIFO order, instead of a LIFO order, obtained by recursion
as I mentioned, the level order is actually a BFS, and its [BFS] pseudo code [taken from wikipedia] is:
1 procedure BFS(Graph,source):
2 create a queue Q
3 enqueue source onto Q
4 mark source
5 while Q is not empty:
6 dequeue an item from Q into v
7 for each edge e incident on v in Graph:
8 let w be the other end of e
9 if w is not marked:
10 mark w
11 enqueue w onto Q
(*) in a tree, marking the vertices is not needed, since you cannot get to the same node in 2 different paths.
void levelorder(Node *n)
{ queue < Node * >q;
q.push(n);
while(!q.empty())
{
Node *node = q.front();
cout<<node->value;
q.pop();
if(node->left != NULL)
q.push(node->left);
if (node->right != NULL)
q.push(node->right);
}
}
Instead of a queue, I used a map to solve this. Take a look, if you are interested. As I do a postorder traversal, I maintain the depth at which each node is positioned and use this depth as the key in a map to collect values in the same level
class Solution {
public:
map<int, vector<int> > levelValues;
void recursivePrint(TreeNode *root, int depth){
if(root == NULL)
return;
if(levelValues.count(root->val) == 0)
levelValues.insert(make_pair(depth, vector<int>()));
levelValues[depth].push_back(root->val);
recursivePrint(root->left, depth+1);
recursivePrint(root->right, depth+1);
}
vector<vector<int> > levelOrder(TreeNode *root) {
recursivePrint(root, 1);
vector<vector<int> > result;
for(map<int,vector<int> >::iterator it = levelValues.begin(); it!= levelValues.end(); ++it){
result.push_back(it->second);
}
return result;
}
};
The entire solution can be found here - http://ideone.com/zFMGKU
The solution returns a vector of vectors with each inner vector containing the elements in the tree in the correct order.
you can try solving it here - https://oj.leetcode.com/problems/binary-tree-level-order-traversal/
And, as you can see, we can also do this recursively in the same time and space complexity as the queue solution!
My questions on above text snippet are
Why level order traversals are not done recursively?
How queue is used in level order traversal? Request clarification with Pseudo code will be helpful.
I think it'd actually be easier to start with the second question. Once you understand the answer to the second question, you'll be better prepared to understand the answer to the first.
How level order traversal works
I think the best way to understand how level order traversal works is to go through the execution step by step, so let's do that.
We have a tree.
We want to traverse it level by level.
So, the order that we'd visit the nodes would be A B C D E F G.
To do this, we use a queue. Remember, queues are first in, first out (FIFO). I like to imagine that the nodes are waiting in line to be processed by an attendant.
Let's start by putting the first node A into the queue.
Ok. Buckle up. The setup is over. We're about to start diving in.
The first step is to take A out of the queue so it can be processed. But wait! Before we do so, let's put A's children, B and C, into the queue also.
Note: A isn't actually in the queue anymore at this point. I grayed it out to try to communicate this. If I removed it completely from the diagram, it'd make it harder to visualize what's happening later on in the story.
Note: A is being processed by the attendant at the desk in the diagram. In real life, processing a node can mean a lot of things. Using it to compute a sum, send an SMS, log to the console, etc, etc. Going off the metaphor in my diagram, you can tell the attendant how you want them to process the node.
Now we move on to the node that is next in line. In this case, B.
We do the same thing that we did with A: 1) add the children to the line, and 2) process the node.
Hey, check it out! It looks like what we're doing here is going to get us that level order traversal that we were looking for! Let's prove this to ourselves by continuing the step through.
Once we finish with B, C is next in line. We place C's children at the back of the line, and then process C.
Now let's see what happens next. D is next in line. D doesn't have any children, so we don't place anything at the back of the line. We just process D.
And then it's the same thing for E, F, and G.
Why it's not done recursively
Imagine what would happen if we used a stack instead of a queue. Let's rewind to the point where we had just visited A.
Here's how it'd look if we were using a stack.
Now, instead of going "in order", this new attendant likes to serve the most recent clients first, not the ones who have been waiting the longest. So C is who is up next, not B.
Here's where the key point is. Where the stack starts to cause a different processing order than we had with the queue.
Like before, we add C's children and then process C. We're just adding them to a stack instead of a queue this time.
Now, what's next? This new attendant likes to serve the most recent clients first (ie. we're using a stack), so G is up next.
I'll stop the execution here. The point is that something as simple as replacing the queue with a stack actually gives us a totally different execution order. I'd encourage you to finish the step through though.
You might be thinking: "Ok... but the question asked about recursion. What does this have to do with recursion?" Well, when you use recursion, something sneaky is going on. You never did anything with a stack data structure like s = new Stack(). However, the runtime uses the call stack. This ends up being conceptually similar to what I did above, and thus doesn't give us that A B C D E F G ordering we were looking for from level order traversal.
https://github.com/arun2pratap/data-structure/blob/master/src/main/java/com/ds/tree/binarytree/BinaryTree.java
for complete can look out for the above link.
public void levelOrderTreeTraversal(List<Node<T>> nodes){
if(nodes == null || nodes.isEmpty()){
return;
}
List<Node<T>> levelNodes = new ArrayList<>();
nodes.stream().forEach(node -> {
if(node != null) {
System.out.print(" " + node.value);
levelNodes.add(node.left);
levelNodes.add(node.right);
}
});
System.out.println("");
levelOrderTreeTraversal(levelNodes);
}
Also can check out
http://www.geeksforgeeks.org/
here you will find Almost all Data Structure related answers.
Level order traversal implemented by queue
# class TreeNode:
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
def levelOrder(root: TreeNode) -> List[List[int]]:
res = [] # store the node value
queue = [root]
while queue:
node = queue.pop()
# visit the node
res.append(node.val)
if node.left:
queue.insert(0, node.left)
if node.right:
queue.insert(0, node.right)
return res
Recursive implementation is also possible. However, it needs to know the max depth of the root in advance.
def levelOrder(root: TreeNode) -> List[int]:
res = []
max_depth = maxDepth(root)
for i in range(max_depth):
# level start from 0 to max_depth-1
visitLevel(root, i, action)
return res
def visitLevel(root:TreeNode, level:int, res: List):
if not root:
return
if level==0:
res.append(node.val)
else:
self.visitLevel(root.left, level-1, res)
self.visitLevel(root.right, level-1, res)
def maxDepth(root: TreeNode) -> int:
if not root:
return 0
if not root.left and not root.right:
return 1
return max([ maxDepth(root.left), maxDepth(root.right)]) + 1
For your point 1) we can use Java below code for level order traversal in recursive order, we have not used any library function for tree, all are user defined tree and tree specific functions -
class Node
{
int data;
Node left, right;
public Node(int item)
{
data = item;
left = right = null;
}
boolean isLeaf() { return left == null ? right == null : false; }
}
public class BinaryTree {
Node root;
Queue<Node> nodeQueue = new ConcurrentLinkedDeque<>();
public BinaryTree() {
root = null;
}
public static void main(String args[]) {
BinaryTree tree = new BinaryTree();
tree.root = new Node(1);
tree.root.left = new Node(2);
tree.root.right = new Node(3);
tree.root.left.left = new Node(4);
tree.root.left.right = new Node(5);
tree.root.right.left = new Node(6);
tree.root.right.right = new Node(7);
tree.root.right.left.left = new Node(8);
tree.root.right.left.right = new Node(9);
tree.printLevelOrder();
}
/*Level order traversal*/
void printLevelOrder() {
int h = height(root);
int i;
for (i = 1; i <= h; i++)
printGivenLevel(root, i);
System.out.println("\n");
}
void printGivenLevel(Node root, int level) {
if (root == null)
return;
if (level == 1)
System.out.print(root.data + " ");
else if (level > 1) {
printGivenLevel(root.left, level - 1);
printGivenLevel(root.right, level - 1);
}
}
/*Height of Binary tree*/
int height(Node root) {
if (root == null)
return 0;
else {
int lHeight = height(root.left);
int rHeight = height(root.right);
if (lHeight > rHeight)
return (lHeight + 1);
else return (rHeight + 1);
}
}
}
For your point 2) If you want to use non recursive function then you can use queue as below function-
public void levelOrder_traversal_nrec(Node node){
System.out.println("Level order traversal !!! ");
if(node == null){
System.out.println("Tree is empty");
return;
}
nodeQueue.add(node);
while (!nodeQueue.isEmpty()){
node = nodeQueue.remove();
System.out.printf("%s ",node.data);
if(node.left !=null)
nodeQueue.add(node.left);
if (node.right !=null)
nodeQueue.add(node.right);
}
System.out.println("\n");
}
Recursive Solution in C++
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode() : val(0), left(nullptr), right(nullptr) {}
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
* };
*/
class Solution {
public:
vector<vector<int>> levels;
void helper(TreeNode* node,int level)
{
if(levels.size() == level) levels.push_back({});
levels[level].push_back(node->val);
if(node->left)
helper(node->left,level+1);
if(node->right)
helper(node->right,level+1);
}
vector<vector<int>> levelOrder(TreeNode* root) {
if(!root) return levels;
helper(root,0);
return levels;
}
};
We can use queue to solve this problem in less time complexity. Here is the solution of level order traversal suing Java.
class Solution {
public List<List<Integer>> levelOrder(TreeNode root) {
List<List<Integer>> levelOrderTraversal = new ArrayList<List<Integer>>();
List<Integer> currentLevel = new ArrayList<Integer>();
Queue<TreeNode> queue = new LinkedList<TreeNode>();
if(root != null)
{
queue.add(root);
queue.add(null);
}
while(!queue.isEmpty())
{
TreeNode queueRoot = queue.poll();
if(queueRoot != null)
{
currentLevel.add(queueRoot.val);
if(queueRoot.left != null)
{
queue.add(queueRoot.left);
}
if(queueRoot.right != null)
{
queue.add(queueRoot.right);
}
}
else
{
levelOrderTraversal.add(currentLevel);
if(!queue.isEmpty())
{
currentLevel = new ArrayList<Integer>();
queue.add(null);
}
}
}
return levelOrderTraversal;
}
}
I'm writing an iterative function to search a binary tree for a certain value. This is localized to signed ints until I get into how to genericize classes.
Assume that my class is BinarySearchTree, and it has a pointer to the root node of the tree. Also assume that nodes are inserted through an insert function, and have pointers to two children. Here is a much abbreviated version of the Node struct:
struct Node
{
public:
Node *left_, *right_;
int value_
Node(int val) : value_(val), left_(0), right_(0) { }
//done in this manner to always make sure blank children are
//init to zero, or null
Node(int val, Node *left, Node *right) : value_(val), left_(0), right_(0)
{ left_ = left; right_ = right; }
}
So, you can safely assume that a node's uninit pointers will be NULL.
Here is my code:
int BinarySearchTree::search(int val)
{
Node* next = this->root();
while (next->left() != 0 || next->right () != 0)
{
if (val == next->value())
{
return next->value();
}
else if (val < next->value())
{
next = next->left();
}
else if (val > next->value())
{
next = next->right();
}
}
//not found
return 0;
}
This code is being rejected by a friend for two reasons:
1) If next has no children, both will evaluate to zero and I will prematurely exit the loop (I will never check the searched val against next's value).
2) If next has one child, but the data you are searching for should be on the empty side of the tree, next will be set to 0, and it will loop again, comparing next (which is 0) to the left and right trees like while(0->left()), resulting in undefined behavior.
I am told that the solution to both problems lies in the loop condition, but I can't see what I can do to easily remedy the situation. Can the community of Stack Overflow offer any insights?
I think you should be testing if next is not NULL in your loop like so:
int BinarySearchTree::search(int val)
{
Node* next = this->root();
while (next)
{
if (val == next->value())
{
return next->value();
}
else if (val < next->value())
{
next = next->left();
}
else if (val > next->value())
{
next = next->right();
}
}
//not found
return 0;
}
Try this:
while (next != NULL) ?
First of all, I'm not sure why you are returning an int. What if you are searching for 0 in the tree. You probably want something like this:
bool BinarySearchTree::Search(int val) {
Node* current = root();
while (current != NULL) {
// Check if it's here
if (val == current->value()) {
return true;
}
if (val < current->value()) {
current = current->left();
} else {
current = current->right();
}
}
// Not found
return false;
}
Notice that the loop invariant: at the beginning of each loop, you are at a non null node that you need to "process". First check if it's the node you want. If not, make a branch, and let the loop decide if the branch was "good" (ie - non null). Then you'll let the next loop iteration take care of testing.