I am trying to traverse a trie in preorder in Java. I need to do some operations if i have found a leaf. I call the Method with the root of the tree and a empty String "" that i can go into the recursion. I have stored a String in every Node and mark words as leaf. For example "the" would be find through the following nodes: ""-->"t"-->"th"-->"the". Thats what I have so far:
void traverse(TrieNode current, String prefix){
for (TrieNode temp : current.getChildren()) {
if (temp == null) continue;
String s = temp.getKey();
traverse(temp, s);
if (temp.getIsLeaf()) {
//do operations
}
}
}
Can someone help me to find a working Solution?
A preorder means you first visit the root, then the children. I didn't understand your use of String prefix (it's available thru current.getKey() anyway)
void traverse(TrieNode current, String prefix){
// do what you need with the key...
String currentValue = current.getKey();
// do what you need if leaf
if (current.getIsLeaf()) {
// do operations
}
for (TrieNode temp : current.getChildren()) {
traverse(temp);
}
}
Related
I am creating inorder traversal of expression tree but it is not considering the middle element. Below is my code. Can you please let me know where i am wroong and code i have missed.
e.g if the prefix notation of expression tree is * 1 + 2 3 then the output of inorder tree along with paranthesis should be (1+(2*3)) but i am getting output (1(23)+)*
public String toStringPrettyInFix(){
return printInorder(root)+")";
}
String printInorder(FCNSTreeNode root)
{
String s="";
if (root == null)
return "";
if(root.firstChild!=null) {
s=s+"("+printInorder(root.firstChild);
}
if(root.nextSibling!=null) {
s=s+printInorder(root.nextSibling)+")";
}
System.out.println(s);
return s;
}
In order traverse left then visit middle then go right.Here you missed the middle part
if(root.firstChild!=null) {
s=s+"("+printInorder(root.firstChild);
}
s = s+root.value //value is whatever stored in node
if(root.nextSibling!=null) {
s=s+printInorder(root.nextSibling)+")";
}
I wrote these method for my program and i felt that it is hard to read as there are too many loops, is there any other alternative to this code to make it look cleaner and easier to read
public static void printRoutingTable(Map <Node, List<Edge>> adj, Node Root)
{
for (Node thisNode : adj.keySet())
{
Node currentNode = thisNode;
String nextHop;
if(currentNode.getParent() != null){
do{
if(currentNode.getParent() != Root){
currentNode = currentNode.getParent();
nextHop = currentNode.getAddr();
}
else{
nextHop = currentNode.getAddr() ;
}
}
while(currentNode.getParent() != Root);
}
else
{
nextHop = ""+currentNode.getAddr();
}
nextHop = nextHop.trim();
}
}
I've not tried, but this should be a functional and recursive version of your code.
String getNextAddr(Node node, StringBuilder sb, Node root) {
sb.add(node.getAddr());
if (node.getParent() != null && node.getParent() != root) {
return getNextAddr(node.getParent(), sb);
}
return sb.toString();
}
String nextHopList =
adj.keySet()
.stream()
.map(k -> getNextAddr(k, new StringBuilder(), Root))
.collect(Collectors.toList())
It's difficult to tell what your code is trying to achieve. At the moment it's not actually doing anything because the nextHop variable is local and nothing seems to be accumulated in the loop. I'm assuming you intend to join the strings your are generating.
there's no point passing in a map if you aren't going to use it. Better to pass a collection (or, better, Stream) of nodes.
generally the root node is the only one with a null parent. So it's likely you also don't need to pass in a reference to the root node.
if parent is optional I suggest you return Optional<Node> from getParent rather than Node.
an easy way to make the code easier to read is to break the parts into separate methods that are named after exactly what they do.
So taking these suggestions into account, something like the following:
String getRoutingTable(Stream<Node> nodes) {
return nodes
.flatMap(this::getRoutingForNode)
.map(Node::getAddr)
.collect(joining(";"));
}
private Stream<Node> getRoutingForNode(Node node) {
Stream.Builder<Node> pathToRoot = Stream.builder();
for (Node c = node; c.getParent().isPresent(); c = node.getParent().get()) {
pathToRoot.accept(c);
}
return pathToRoot.build();
}
Note that in Java 9 the getRoutingForNode will become much more readable as you will be able to dispense with the Builder:
return Stream.iterate(node,
n -> node.getParent().isPresent(),
n -> n.getParent().get());
class Link{
private int value;
private Link next;
}
I am asked to write a recursive method to delete last occurrence of a certain value, say 4.
before 2->3->4->5->4->2
after 2->3->4->5->2
The last occurrence only. I know how to delete all occurrence but I can't tell if its the last occurrence. No helper method is allowed.
The one to delete all occurrence
public Link deleteAll(){
if (next == null){
return value==4? null:this;
}else{
if (value == 4){
return next.deleteAll();
}
next = next.deleteAll();
return this;
}
}
You can declare a pointer to the last occurred node and delete that node when reached the last element in list. Following steps explains that -
Declare two pointers one is next as in your above code another can be temp.
Iterate through list using next like you doing in deleteAll method above.
If you find the node you looking for assign that node to temp.In your case 4.
When next is null you reached the end of list now delete, whatever node is in temp delete that node. If temp is still null than no node found in given key.
EDIT:
Possible pseudo Code in case of recursion:
public void deleteLast(Node node,Node temp,Node prev, int data)
{
if(node==null)
{
if(temp!=null && temp.next.next!=null){
temp.next = temp.next.next;}
if(temp.next.next==null)
temp.next = null;
return;
}
if(node.data==data)
{
temp = prev;
}
prev = node;
deleteLast(node.next, temp, prev, int data);
}
Above code should be able to solve your problem. I made some edit in my approach which should be obvious from the code but let me describe it below
I added a prev pointer. Because if we want to delete a particular node we need to assign its next to prev node's next.So, we need the prev node not the node that we want to delete.
I think this change will follow in iterative approach too.
Not really answering your exact question, but as an alternative option, you might consider the following.
Write a recursive method to delete the first occurrence of a specified value, something like this:
public Link deleteFirst(int target) {
if (value == target) {
return next;
}
next = (next == null) ? null : next.deleteFirst(target);
return this;
}
Then you could write a reverse() method as either an iterative or recursive method as you see fit. I haven't included this, but googling should show some useful ideas.
Finally the method to remove the last occurrence of a value from the linked list could then be written like this:
public Link deleteLast(int target) {
return reverse().deleteFirst(target).reverse();
}
Note that as long as your reverse() method is linear complexity, this operation will be linear complexity as well, although constants will be higher than necessary.
The trick is to do the work on the way back -- there is no need for additional parameters, helpers or assumptions at all:
Link deleteLast(int target) {
if (next == null) {
return null;
}
Link deleted = next.deleteLast(target);
if (deleted == null) {
return value == target ? this : null;
}
if (deleted == next) {
next = deleted.next;
}
return deleted;
}
This problem is not for an assignment, although it's a somewhat typical "assignment-like" problem that I'm trying to solve in a different way.
I want to write a method that will recursively go through a binary tree using a depth-first search algorithm to find a match for a character. Once it finds the matching character, I want it to return a string that maps the position of the character in the tree using 0s and 1s. "001",for example, would indicate that the character is found by going to the left node of the root node, the left node of that node, and then to the right node of that node.
Here is the code I have so far:
private static String encryptSearch(char c, BinaryNode curNode, String result)
{
char data = (char) curNode.getData();
if (data != c)
{
if (curNode.hasLeftChild())
{
result = result + "0";
encryptSearch(c, curNode.getLeftChild(), result);
}
if (curNode.hasRightChild())
{
result = result + "1";
encryptSearch(c, curNode.getRightChild(), result);
}
result = result.substring(0, result.length()-1);
}
return result;
}
The method is initially sent the character to be searched for, the root node, and null for the result. This method returns nothing except 0s. I think there are multiple problems with my code, but the largest one is that when the search reaches a leaf node, it returns. I've been unable to think of a way around this problem while still returning a string. I could easily write a void method that acts on the result string as an external variable, but I don't want to do that for the purpose of the exercise. Any help is appreciated!
Use the mutable StringBuilder instead of String. Also there should be a way to know that you got the result from left one (if any) before searching right one. So I suggest following changes.
private static boolean encryptSearch(char c, BinaryNode curNode, StringBuilder result) {
char data = curNode.getData();
if (data != c) {
boolean found = false;
if (curNode.hasLeftChild()) {
found = encryptSearch(c, curNode.getLeftChild(), result);
if (found) {
result.insert(0, "0");
return true;
}
}
if (curNode.hasRightChild()) {
found = encryptSearch(c, curNode.getRightChild(), result);
if (found) {
result.insert(0, "1");
return true;
}
}
return false; //no result
}
return true;
}
I am trying to change my recursive insert method of the BST into non-recursive( maybe While loop)
The reason for this changing because I want to see if it is possible.
Here is the code of insertion:
public void insert(String value)
{
//The node is stored in the root
root = insert(value,root);
}
private Character insert(String value,Character current)
{
if(current == null)
{
//Add the root if the tree empty
current = new Character(value);
}
else
//If the value that we want to insert < root value, then keep going to left till
//it's empty then inserted at left end. Done by recursion
if(value.compareTo(current.getElement())<=-1)
{
current.setLeft(insert(value,current.getLeft()));
}
else
//If the value that we want to insert > root value, then keep going to right till
//it's empty then inserted at right end. Done by recursion
if(value.compareTo(current.getElement())>=1)
{
current.setRight(insert(value,current.getRight()));
}
else
{
//Else, the number we want to insert in already in the tree
System.out.println("Duplicate numbers inserted" + current.getElement());
}
//returning the node tree so that we store it in the root
return current;
}
Could I change this code into non recursive ?
Cheers
Yes, but you need to alter the data structure a little bit to make it works.
The node has to know its left child and right child.
The algorithm looks like this:
current = root;
while(current != null){
if(value.compareTo(current.getElement())<=-1)
{
current = current.left_child;
}else if(value.compareTo(current.getElement())>=1){
current = current.right_child;
}else{
// Duplication
}
}
Actually there are some good examples before, you may want to check those out first:
Write a non-recursive traversal of a Binary Search Tree using constant space and O(n) run time
Nonrecursive/Iterative Binary Search Tree in C (Homework)
Yes, you could define your insert function non-recursively.
However, to do this, your insert function will have to define in-order traversal iterator for BST, which is recursively defined.
I believe there is a way to define in-order traversal non-recursively, but depending on implementation this can be very inefficient.
BST itself is basically recursively defined, and it is always efficient to define your insert function recursively. (I could write some pseudo-code if you really need it, but I think it is kind of meaningless and I do not know about the implementation detail of your in-order traversal iterator)
Please don't forget to select this as an answer :-)
Insert using while loop
public Node insert(Node root,int n) {
while (true) {
if (root.data>n) {
if (root.left==null) {
root.left= new Node(n);
return (root.left);
}
root=root.left;
}
else if (root.data<n) {
if (root.right == null) {
root.right= new Node(n);
}
}
}
}