One of the hardest concepts I've found in programming has been recursion. I have been trying to convert this function into a recursive call for 2 days now, but I just can't get it to work. Its a delete function for a BST
public void deleteByMerging(T el) {
BSTNode<T> tmp, node, p = root, prev = null;
while (p != null && !p.el.equals(el)) { // find the node p
prev = p; // with element el;
if (el.compareTo(p.el) < 0)
p = p.right;
else p = p.left;
}
node = p;
if (p != null && p.el.equals(el)) {
if (node.right == null) // node has no right child: its left
node = node.left; // child (if any) is attached to its parent;
else if (node.left == null) // node has no left child: its right
node = node.right; // child is attached to its parent;
else { // be ready for merging subtrees;
tmp = node.left; // 1. move left
while (tmp.right != null) // 2. and then right as far as
tmp = tmp.right; // possible;
tmp.right = // 3. establish the link between
node.right; // the rightmost node of the left
// subtree and the right subtree;
node = node.left; // 4.
}
if (p == root)
root = node;
else if (prev.left == p)
prev.left = node;
else prev.right = node; // 5.
}
else if (root != null)
System.out.println("el " + el + " is not in the tree");
else System.out.println("the tree is empty");
}
I got it as far as to find the node, but steps 1 through 5 (in comments) really breaks my brain.
First of all, you need to "find" the node. Let's try to think in recursive way:
function find(el, p)
if p == null, not found! (return p, i.e. null)
if p.el == el, found! (return p)
if el < p.el, return find(el, p.right)
if el > p.el, return find(el, p.left)
This is recursive, right? So, BSTNode<T> node = find(el, root) will return either the node that matches el or return null which implies NOT FOUND.
The remaining delete by merge only manages object reference, so I'm not to comment.
I think there is some problem with the merging algorithm steps 3 and 4. Imagine you are deleting a node with left and right subtree. The empty space is replaced with a node that must satisfy the BST condition (ie. greater than left node and smaller than right node). That replacement node is found in the rightmost left subtree (Step 2 of comments). That node is pointed to by tmp. So now we have "node" which points to the node being deleted and "tmp" which points to the replacement node. In Step 3, this is where the linking happens.
tmp.right = node.right
tmp.left = node.left // missing from the algorithm
Now in Step 4, this is where the "node" variable is changed to point to the replacement node "tmp" so in Step 5, the previous node "prev" can link to the replacement node. I believe Step 4 should be
node = tmp;
instead of
node = node.left;
Please check if my analysis is correct. Maybe that's why you're not able to understand what's going on. The recursive part of the deleteByMerging() is the searching for the node to delete. Once found, the algorithm to merge the tree would not change.
Related
I've a network graph
Now I've some connected nodes and as you can see most of the nodes only have one connected node that is their degree is 1. Now I'd like to remove such nodes to clear the clutter. Unable to find how to since last 2 days. No such helper functions available in visjs documentation. Would appreciate help.
I believe the algorithm suggested by the 1st answer -by macramole- (before updates) would actually hide the non-connected nodes (degree 0), instead of the ones with degree 1.
I would probably just iterate over all the edges in the network while keeping 'degree' counters for each node that is an endpoint in the edge you are visiting (you can obtain these nodes by grabbing the edge.from and edge.to values, as shown above). You would increment the degree counter for a node, whenever the node is 'hit' in this search through the edges.
Eventually you'll end up with the degree value for each node in the network, at which point you can decide which ones to hide.
Updating this answer now to include my suggested code (note: nodes and edges are vis DataSet instances):
Example code:
var nodeToDegrees = {}; // keeps a map of node ids to degrees
var nodeFrom, nodeTo;
for (edge in edges) {
nodeFrom = edge.from;
nodeTo = edge.to;
nodeToDegrees[nodeFrom] = nodeToDegrees[nodeFrom] ? nodeToDegrees[nodeFrom] + 1 : 0;
nodeToDegrees[nodeTo] = nodeToDegrees[nodeTo] ? nodeToDegrees[nodeTo] + 1 : 0;
}
for (node in nodes) {
if (nodeToDegrees[node.id] = 1) nodes.update([{node.id, hidden: true}]);
}
This might work:
var DEGREES_HIDDEN = 1;
for ( var node of nodes ) {
node.cantLinks = 0;
for ( var link of links ) {
if ( link.from == node.id || link.to == node.id ) {
node.cantLinks++;
}
}
}
for ( var node of nodes ) {
if ( node.cantLinks <= DEGREES_HIDDEN ) {
node.hidden = true;
}
}
Nodes and links are arrays not vis.DataSet, I create the latter after doing that.
Doesn't look very nice perfomance wise but it does get the job done. Hope you find it useful.
I wanted to reflect a binary tree, such that all nodes on the left ended up on the right, and vice versa.
Something like :
A
/ \
B C
/ / \
D E F
would become
A
/ \
C B
/ \ \
F E D
I noticed that, while writing my solution, this code worked:
static Tree getReflection(Tree root) {
if(root == null) {
return null;
}
Tree reflect = root;
Tree subRight = getReflection(root.right);
Tree subLeft = getReflection(root.left);
reflect.left = subRight;
reflect.right = subLeft;
return reflect;
}
And yet, this one doesn't:
static Tree getReflection(Tree root) {
if(root == null) {
return null;
}
Tree reflect = root;
reflect.left = getReflection(root.right);
reflect.right = getReflection(root.left);
return reflect;
}
Can someone explain to me why? To me, they seem like identical methods, except one uses temporary tree variables.
Look at your first statement in each: when you assign
reflect = root
, the two variables now point to the same memory location. Now, let's look at the operation of the second routine:
Tree reflect = root;
// reflect and root now refer to exactly the same tree.
reflect.left = getReflection(root.right);
// reflect the right subtree; make that the new left subtree.
reflect.right = getReflection(root.left);
// Grab that new subtree, re-reflect it, and put it back on the right.
The original left subtree is lost, replaced by a reflection of the right.
In the first routine, you saved them in local variables until you'd done both reflections.
It is because in the second function (the one that doesn't work), you are assigning the reflected result to your left node and then using that as input to the reflection that you assign to your right node.
Tree reflect = root;
reflect.left = getReflection(root.right);
reflect.right = getReflection(root.left);
I have coded a table driven LR(1) parser and it is working very well however I am having a bit of a disconnect on the stage of turing a parse into a syntax tree/abstract syntax tree. This is a project that I m very passionate about but I have really just hit a dead end here. Thank you for your help in advance.
Edit: Also my parser just uses a 2d array and an action object that tells it where to go next or if its a reduction where to go and how many items to pop. I noticed that many people use the visitor pattern. Im not sure how they know what type of node to make.
Here is the pushdown automata for context
while (lexer.hasNext() || parseStack.size() > 0) {
Action topOfStack = parseStack.peek();
token = parseStack.size() > 0 ? lexer.nextToken() : new Token(TokenType.EOF, "EOF");
topOfStack.setToken(token);
int row = topOfStack.getTransitionIndex();
int column = getTerminalIndex(token.getLexeme());
column = token.getType() == TokenType.IDENTIFIER
&& !terminalsContain(token.getLexeme()) ? 0 : column;
Action action = actionTable[row][column];
if (action instanceof Accept) {
System.out.println("valid parse!!!!!!");
} else if (action instanceof Reduction) {
Reduction reduction = (Reduction) action;
popStack(parseStack, reduction.getNumberOfItemsToPop());
column = reduction.getTransitionIndex();
row = parseStack.peek().getTransitionIndex();
parseStack.push(new Action(gotoTable[row][column]));
lexer.backupTokenStream();
} else if (action != null) {
parseStack.push(actionTable[row][column]);
} else {
System.out.println("Parse error");
System.out.println("On token: " + token.getLexeme());
break;
}
Each reduction in the LR parsing process corresponds to an internal node in the parse tree. The rule being reduced is the internal AST node, and the items popped off the stack correspond to the children of that internal node. The item pushed for the goto corresponds to the internal node, while those pushed by shift actions correspond to leaves (tokens) of the AST.
Putting all that together, you can easily build an AST by createing a new internal node every time you do a reduction and wiring everything together appropriately.
Not the best title for the question, I agree. But I couldn't come up with something else. Sorry.
Writing a simple Singly Linked List code in Groovy, I want to add a method which takes in two lists and appends the right one to the left one. This is what I cam up with.
private static class Node {
Node next = null
def head
#TailRecursive
Node append(Node left = this, Node right) {
if (!right) return left
if (!left) return right
if (!left.next) left.next = right
else left.next = append(left.next, right)
return left
}
}
But I got the error,
LinkedList.groovy: 23: Recursive call could not be transformed by #TailRecursive. Maybe it's not a tail call.
# line 23, column 30.
else head.next = append(head.next, tail)
Is it because of the return statement in the end that it's not tail recursive? How do I fix this?
Based on the tip user2864740 gave, here's the tail recursive implementation. It should be as efficient as the non-tail-recursive one I posted in the question.
#TailRecursive
Node append(Node prevTail = this, Node tail = this?.next, Node right) {
if (!right) return left
if (!prevTail) return right
if (!tail) prevTail.next = right
else return append(tail, tail?.next, right)
}
Something like below would suffice?
import groovy.transform.TailRecursive
#TailRecursive
LinkedList mergeLinkedList(LinkedList left = [], LinkedList right = []) {
if ( !left ) {
right
} else if ( !right ) {
left
} else {
left.add( right.head() )
mergeLinkedList( left, right.tail() )
}
}
def left = (1..100) as LinkedList, right = (200..500) as LinkedList
assert mergeLinkedList( left, right ) == ((1..100) + (200..500)) as LinkedList
I want help in linked list implementation of a tree. A tree node has three child.
using pointers: Parent, Siblings and FirstChild.
I have tried making it but couldn't get it to work. I need help in inserting new nodes
void InsertFirstChild(Node newNode)
{
newNode.m_Parent = this;
newNode.m_NextSibling = m_FirstChild;
if (m_FirstChild != null)
m_FirstChild.m_PrevSibling = newNode;
else
m_LastChild = newNode;
m_FirstChild = newNode;
}