I need to build a double threaded tree from a regular binary tree, using recursion if possible.
This is the definition that we are usig: The threaded tree of a binary tree is obtained by setting every null left child to the predecessor of the node in the inorder traversal and every null right child to the successor of the node in the inorder traversal.
I cant find a solution to this and there are a couple of posts similar to this one here but without a solution. I just need the algorithm, it can be in any language
This are the constructors, the 2nd one is the one I need to do:
public ThreadedNode(T theElement, ThreadedNode<T> lt, ThreadedNode<T> rt)
{
element = theElement;
left = lt;
right = rt;
}
public ThreadedNode( BinaryNode<T> root)
{
// implement it
}
//the fields
private T element;
private boolean lThread = false;
private ThreadedNode<T> left;
private boolean rThread = false;
private ThreadedNode<T> right;
}
my initial approach is to call a helper method, recursively, like this:
ThreadNode<T> helper(BinaryNode<T> n, BinaryNode<T> predecessor, BinaryNode<T> successor)
, initially predecessor and successor are null, but then as I go down traversing the tree in_order I set them using the current node and its parent, depending on whether it is a left or right child but I think it does not work for all the cases and I cant see how to improve it
thank you in advance
Since you mentioned that it can be any language, here is a C implementation provided along with very good explanation.
Related
Given two binary search trees, print the nodes in ascending order with time complexity O(n) and space complexity: O(1)
The trees cannot be modified. Only traversal is allowed.
The problem I am facing is with the O(1)space solution. Had there not been this constraint, it could have been easily solved.
The only way this can be done in space O(1) is if the nodes know their parent.
Otherwise you cannot even traverse the tree unless there is some additional aid.
However with this constraint it's again easy and back to tree-traversal, but without recursion. The tricky part is probably knowing which tree-path you came from when you go from a node to its parent (p) and cannot store this information as this would require O(log N) space.
However, you know the last value you outputted. If it is smaller than the one of p, go the right, otherwise go to p’s parent.
if we're talking about BST's as defined by wikipedia:
The left subtree of a node contains only nodes with keys less than the node's key.
The right subtree of a node contains only nodes with keys greater than the node's key.
Both the left and right subtrees must also be binary search trees.
with the additional perk that every node knows his parent, then the following C code does the trick (I hope you like C, I have put quite some effort in these 300 lines of demo application :D)
http://pastebin.com/MiTGqakq
(note that I didn't use recursion, because recursion is technically never O(1)space. The reason for this that every function call uses copies of the passed parameters, thus allocating additional space, making O_space dependent on the number of calls -> not in O(1)space.)
EDIT: ok, fixed version is linked. have fun.
I have solution of this problem.
I have coded my solution in C#, because it is my strongest language, but I hope that you will catch a main idea. Let's suppose, that each tree node has 3 references: to left, right and parent nodes.
So we have BinaryTree. How could we print it? Obviously:
this._tree.Print();
That wasn't very difficult. But how could we build Print method, if we should avoid recursion (because the last one involves O(log(n)) memory)? Have you ever read about lazy lists (or streams)? Lazy list doesn't hold the whole list in memory, but knows how to calculate next item based on current item. In every moment lazy list allocates O(1) memory. So, suppose we have managed to describe lazy list for tree. Then Print method is very simple:
public static void Print<T>(this BinaryTree<T> tree)
where T : IComparable<T>
{
var node = new TreeNodeWalker<T>(tree.Root, WalkerState.FromParent);
while (node != null)
{
node = node.WalkNext();
}
}
During this code snippet you could find out one unfamiliar entity: TreeNodeWalker. This object holds tree node that should be walked, state that signals in what moment of traversing this walker was created and method which gives next walker. In short walker performs next actions:
If we drop in any subtree from parent node, we should walk left subtree.
If we emerges from left subtree, we should print node value and walk right subtree.
If we emerges from right subtree we should walk parent.
It could be represented in code in the next way:
public class TreeNodeWalker<T>
where T:IComparable<T>
{
// Tree node, for which walker is created.
private readonly BinaryTreeNode<T> _node;
// State of walker.
private readonly WalkerState _state;
public TreeNodeWalker(BinaryTreeNode<T> node, WalkerState state)
{
this._node = node;
this._state = state;
}
public TreeNodeWalker<T> WalkNext()
{
if (this._state == WalkerState.FromParent)
{
// If we come to this node from parent
// we should walk left subtree first.
if (this._node.Left != null)
{
return new TreeNodeWalker<T>(this._node.Left, WalkerState.FromParent);
}
else
{
// If left subtree doesn't exist - return this node but with changed state (as if we have already walked left subtree).
return new TreeNodeWalker<T>(this._node, WalkerState.FromLeftSubTree);
}
}
else if (this._state == WalkerState.FromLeftSubTree)
{
// If we have returned from left subtree - current node is smallest in the tree
// so we should print it.
Console.WriteLine(this._node.Data.ToString());
// And walk right subtree...
if (this._node.Right != null)
{
//... if it exists
return new TreeNodeWalker<T>(this._node.Right, WalkerState.FromParent);
}
else
{
// ... or return current node as if we have returned from right subtree.
return new TreeNodeWalker<T>(this._node, WalkerState.FromRightSubTree);
}
}
else if (this._state == WalkerState.FromRightSubTree)
{
// If we have returned from right subtree, then we should move up.
if (this._node.Parent != null)
{
// If parent exists - we compare current node with left parent's node
// in order to say parent's walker which state is correct.
return new TreeNodeWalker<T>(this._node.Parent, this._node.Parent.Left == this._node ? WalkerState.FromLeftSubTree : WalkerState.FromRightSubTree);
}
else
{
// If there is no parent... Hooray, we have achieved root, which means end of walk.
return null;
}
}
else
{
return null;
}
}
}
You could see a lot of memory allocation in code and make decision that O(1) memory requirement is not fulfilled. But after getting next walker item, we don't need previous one any more. If you are coding in C++ don't forget to free memory. Alternatively, you could avoid new walker instance allocation at all with changing internal state and node variables instead (you should always return this reference in corresponding places).
As for time complexity - it's O(n). Actually O(3*n), because we visit each node three times maximum.
Good luck.
Suppose that I have a tree to traverse using a Depth First Search, and that my algorithm for traversing it looks something like this:
algorithm search(NODE):
doSomethingWith(NODE)
for each node CHILD connected to NODE:
search(CHILD)
Now in many languages there is a maximum depth to recursion, for example if the depth of recursion is over a certain limit, then the procedure will crash with a stack overflow.
How can this function be implemented without the recursion, and instead with a stack? In many cases, there are a lot of local variables; where can they be stored?
You change this to use a stack like so:
algorithm search(NODE):
createStack()
addNodeToStack(NODE)
while(stackHasElements)
NODE = popNodeFromStack()
doSomethingWith(NODE)
for each node CHILD connected to NODE:
addNodeToStack(CHILD)
As for your second question:
In many cases, there are a lot of local variables; where can they be stored?
These really can be kept in the same location as they were originally. If the variables are local to the "doSomethingWith" method, just move them into that, and refactor that into a separate method. The method doesn't need to handle the traversal, only the processing, and can have it's own local variables this way that work in its scope only.
For a slightly different traversal.
push(root)
while not empty:
node = pop
doSomethingWith node
for each node CHILD connected to NODE:
push(CHILD)
For an identical traversal push the nodes in reverse order.
If you are blowing your stack, this probably won't help, as you'll blow your heap instead
You can avoid pushing all the children if you have a nextChild function
Essentially you new up your own stack: char a[] = new char[1024]; or for type-safety, node* in_process[] = new node*[1024]; and put your intermediate values on this:
node** current = &in_process[0];
node* root = getRoot();
recurse( root, ¤t) ;**
void recurse( node* root, node** current ) ;
*(*current)++ = root; add a node
for( child in root ) {
recurse( child, current );
}
--*current; // decrement pointer, popping stack;
}
I have to make a method for making a list with all the paths in a graph.My graph has only one start node and one finish node. Each node has a list whith its children and other list whith its parents. I have to make another list containing all the paths (each of them in another list)
Any suggestion??
It depends on whether it is acyclic or not. Clearly a cycle will result in infinity paths (once round the loop, twice round, 3 times round... etc etc). If the graph is acyclic then you should be able to do a depth-first seach (DFS) (http://en.wikipedia.org/wiki/Depth-first_search) and simply count the number of times you encounter the destination node.
First familiarize yourself with basic graph algorithms (try a textbook, or google). Figure out which one best suits the problem you are solving, and implement it. You may need to adapt the algorithm a little, but in general there are widely known algorithms for all basic graph problems.
If you have a GraphNode class that looks something like this:
public class GraphNode
{
public IEnumerable<GraphNode> Children { get; set; }
// ...
}
Then this sould do the work:
public static class GraphPathFinder
{
public static IEnumerable<IEnumerable<GraphNode>> FindAllPathsTo(this GraphNode startNode, GraphNode endNode)
{
List<IEnumerable<GraphNode>> results = new List<IEnumerable<GraphNode>>();
Stack<GraphNode> currentPath = new Stack<GraphNode>();
currentPath.Push(startNode);
FindAllPathsRecursive(endNode, currentPath, results);
return results;
}
private static void FindAllPathsRecursive(GraphNode endNode, Stack<GraphNode> currentPath, List<IEnumerable<GraphNode>> results)
{
if (currentPath.Peek() == endNode) results.Add(currentPath.ToList());
else
{
foreach (GraphNode node in currentPath.Peek().Children.Where(p => !currentPath.Contains(p)))
{
currentPath.Push(node);
FindAllPathsRecursive(endNode, currentPath, new List<IEnumerable<GraphNode>>());
currentPath.Pop();
}
}
}
}
It's a simple implementation of the DFS algorithm. No error checking, optimizations, thread-safety etc...
Also if you are sure that your graph does not cycles, you may remove the where clause in the foreach statement in the last method.
Hope this helped.
You could generate every possible combination of vertices (using combinatorics) and filter out the paths that don't exist (where the vertices aren't joined by an edge or the edge has the wrong direction on it).
You can improve on this basic idea by having the code that generates the combinations check what remaining vertices are available from the current vertex.
This is all assuming you have acyclic graphs and wish to visit each vertex exactly once.
I'm having a hell of a time trying to figure this one out. Everywhere I look, I seem to be only running into explanations on how to actually traverse through the list non-recursively (the part I actually understand). Can anyone out there hammer in how exactly I can go through the list initially and find the actual predecessor/successor nodes so I can flag them in the node class? I need to be able to create a simple Binary Search Tree and go through the list and reroute the null links to the predecessor/successor. I've had some luck with a solution somewhat like the following:
thread(node n, node p) {
if (n.left !=null)
thread (n.left, n);
if (n.right !=null) {
thread (n.right, p);
}
n.right = p;
}
From your description, I'll assume you have a node with a structure looking something like:
Node {
left
right
}
... and that you have a binary tree of these set up using the left and right, and that you want to re-assign values to left and right such that it creates a doublely-linked-list from a depth first traversal of the tree.
The root (no pun intended) problem with what you've got so far is that the "node p" (short for previous?) that is passed during the traversal needs to be independent of where in the tree you currently are - it always needs to contain the previously visited node. To do that, each time thread is run it needs to reference the same "previous" variable. I've done some Python-ish pseudo code with one C-ism - if you're not familiar, '&' means "reference to" (or "ref" in C#), and '*' means "dereference and give me the object it is pointing to".
Node lastVisited
thread(root, &lastVisisted)
function thread(node, lastVisitedRef)
if (node.left)
thread(node.left, lastVisitedRef)
if (node.right)
thread(node.right, lastVisitedRef)
// visit this node, reassigning left and right
if (*lastVisitedRef)
node.right = *lastVisitedRef
(*lastVisitedRef).left = node
// update reference lastVisited
lastVisitedRef = &node
If you were going to implement this in C, you'd actually need a double pointer to hold the reference, but the idea is the same - you need to persist the location of the "last visited node" during the entire traversal.
I am developing a Trie data-structure where each node represents a word. So words st, stack, stackoverflow and overflow will be arranged as
root
--st
---stack
-----stackoverflow
--overflow
My Trie uses a HashTable internally so all node lookup will take constant time. Following is the algorithm I came up to insert an item into the trie.
Check item existence in the trie. If exist, return, else goto step2.
Iterate each character in the key and check for the existence of the word. Do this until we get a node where the new value can be added as child. If no node found, it will be added under root node.
After insertion, rearrange the siblings of the node under which the new node was inserted. This will walk through all the siblings and compare against the newly inserted node. If any of the node starts with same characters that new node have, it will be moved from there and added as child of new node.
I am not sure that this is the correct way of implementing a trie. Any suggestions or improvements are welcome.
Language used : C++
The trie should look like this
ROOT
overflow/ \st
O O
\ack
O
\overflow
O
Normally you don't need to use hash tables as part of a trie; the trie itself is already an efficient index data structure. Of course you can do that.
But anyway, your step (2) should actually descend the trie during the search and not just query the hash function. In this way you find the insertion point readily and don't need to search for it later as a separate step.
I believe step (3) is wrong, you don't need to rearrange a trie and as a matter of fact you shouldn't be able to because it's only the additional string fragments that you store in the trie; see the picture above.
Following is the java code for insert algorithm.
public void insert(String s){
Node current = root;
if(s.length()==0) //For an empty character
current.marker=true;
for(int i=0;i<s.length();i++){
Node child = current.subNode(s.charAt(i));
if(child!=null){
current = child;
}
else{
current.child.add(new Node(s.charAt(i)));
current = current.subNode(s.charAt(i));
}
// Set marker to indicate end of the word
if(i==s.length()-1)
current.marker = true;
}
}
For a more detailed tutorial, refer here.