Are there any cycles in this tree?
Now I looked up this question by chance before the interview and the Internet in general and and Stackoverflow in specific wasn't very helpful; either being obstinate in stating that a tree by definition cannot have a cycle or some destructive or overly complicated solution.
Now when my interviewers referring to a binary-tree with a cycle, they were talking about something similar to figure 1 below. This tree have the normal 2 branch binary-tree structure, with 3 (possibly incorrect; I don't really care) branches that extend to previous nodes in the tree.
Now when my interviewers referring to a binary-tree with a cycle, they were talking about something similar to figure 1 below. This tree have the normal 2 branch binary-tree structure, with 3 (possibly incorrect; I don't really care) branches that extend to previous nodes in the tree.
![]() | |
| Figure 1 |
- We only have access to the root node of the tree and thus can't find the strongly connected components or some other algorithm that would find cycles in a graph.
![]() |
| Figure2 |
If we mark each node as we go along, when we reach that node again we believe there is a loop. This works for the very simple case above as well as any of the cycles shown below in figure 3.
![]() |
| Figure3 |
![]() | |
| Figure 4 |
![]() |
| Figure 5 |
![]() |
| Figure 6 |
For the below example how it should work. I will mark the tortoise as green and the hare as blue.
An example of a tree where this method won't work. When the first iteration is complete node 2 will be in both the fast and slow set, but the tree has no cycle.
Below is the code for both algorithms that I wrote in C++:
Stack Based:
typedef struct Node { Node* left; Node* right; Node() { left = 0; right = 0; } ~Node() { left->~Node(); right->~Node(); } } Node; vector<Node*> v; static bool has_cycle(Node* root) { if( !root ) { return false; } if( find(v.begin(),v.end(),root) != v.end() ) { return true; } v.push_back(root); if( root->left == 0 && root->right == 0 ) { v.pop_back(); } if( v.empty() ) { return false; } return has_cycle(root->left) || has_cycle(root->right); }
Marking based:
typedef struct Node { Node* left; Node* right; bool visited; Node() { left = 0; right = 0; visited = false; } ~Node() { left->~Node(); right->~Node(); } } Node; static bool has_cycle(Node* root) { if( root == 0 ) { return false; } if( root->visited ) { return true; } root->visited = true; if( !has_cycle(root->left) && !has_cycle(root->right) ) { root->visited = false; return false; } return true; }









No comments:
Post a Comment