I'm trying to make a binary tree based on a list. The list contains on index 0 the node, and on the index 1 and 2, the left and right child. On index 3 is another node and on index 4 and 5 is left and right child for the node on index 3, and so on. I've tried something like this
public static HNode buildHTree(List<HNode> list) {
HNode node = lista.get(0);
HNode left = lista.get(1);
HNode right = lista.get(2);
list.remove(0);
list.remove(0);
list.remove(0);
if(list.size() > 0)
return buildHTree(list);
return node;
}
but this doesn't work. Can some of you give me some hint or some help in making this.
The HNode class contains:
private Symbol value;
private HNode left, right;
and setters and getters for this.
Thank you very much
I want to tell me what is wrong with my thinking and how can change my code to achieve my goal.
One thing that is wrong with your thinking is that you seem to think that you can write "some code" and then "change" it to make it right. That is not a good way to program.
The better / right way is to:
understand the requirements before you start designing,
understand the algorithm before you start coding it,
when you run into a problem, read the code you have written and try to understand what it actually does. Then compare that with what you are trying to achieve; i.e. what you intended to write.
And don't be afraid of throwing away stuff and starting again.
Specific hints:
Should you be starting from a List<HNode>? Shouldn't it really be a List<Symbol>?
Shouldn't you be setting the left / right fields to put the nodes into a tree structure?
Do you know if the list is sorted?
Related
I am struggling in a data structures course where my professor is either absent or not answering. I have an assignment due within a day or so and have no clue where to even start in terms of answering them. If somebody could explain what to do and how it'd be much appreciated. Also, I'm somewhat new to StackOverflow, if I misformatted my question or did something wrong please let me know before a downvote, I would just like some help, thanks.
Write the definition of the method nodeCount that returns the number of nodes in a binary tree. Add this method to the class BinaryTree and create a program (the main class with the main method) to test this method. (Note: To test your algorithm, first create a binary search tree).
Write a method, swapSubtrees, that swaps all of the left and right subtrees of a binary tree. Add this method to the class BinaryTree and create a program (the main class with the main method) to test this method. (Note: To test your algorithm, first create a binary search tree).
You can find a tutorial on how to implement a binary tree in java here.
To count the nodes in a tree you should try to use a recursive method that count's and summs up the size of the sub-trees. In pseudocode:
int count(TreeNode node):
if (node.hasNoMoreSubNodes):
return 1
else:
sum = count(node.left) + count(node.right) + 1
return sum
I'm not quite shure what's the point in the second question. You could do something like this (pseudocode):
void swapSubTrees(TreeNode node):
TreeNode tmp = node.left
node.left = node.right
node.right = tmp
This would swap the subtrees of the binary-tree, but after this the structure you have is no longer a binary-search-tree, but only a binary-tree. So this operation would be quite useless if it's executed on a binary-search-tree...
Hope this helps.
Dear Friends I am an intermediate java user. I am stuck in a following problem. I want to construct a unordered binary tree [or general tree having at most two nodes] from a multi line (let say 40 lines) text file. The text file is then divided into two halfs; let say 20:20 lines. Then for each half a specific (let say hash) value is calculated and stored in the root node. So each node contains four elements. Two pointers to the two children (left and right) and two hashes of the two halfs of the original file. Next for each half (20 lines) the process is repeated until at each leaf we have a single line of text. Let the node have
public class BinaryTree {
private BinaryTreeNode leftNode, rightNode;
private String leftHash,rightHash;
}
I need help for writing the tree construction and searching functions. Well searching is performed by entering a line. Then hash code is created for this query line and compared against the two hashes saved at each node. If the hash of query line is close to leftHas then leftNode is accessed and if the hash of query line is close to rightHash then rightNode is accessed. The process continues until an exact hash is found.
I just need the tree construction and search teachnique. The hash comparison etc are not a problem
You'll need to start by reading the file into a string.
The first character in the string could be used as the root. Root + 1 would be the left, root + 2 would be the right
Consider left node of the root (Root + 1), you could also consider this as Root + N. Meaning that the right node would be Root + N + 1.
You can now recursively solve this problem by establishing which Node you are currently on, and setting the left and right now respectively.
So lets think about it,
You have the root node, left node, and right node established. At this point you have used 3 letters/numbers (it really doesnt matter if it is unordered). The next step would be to move down one level and start filling the left, you have the root, you need left and right nodes. Then move to the right node, do the left and right node of this and so on and so forth.
Think about that for a little bit and see where you get.
Cheers,
Mike
EDIT:
To search,
Searching a binary tree is also a recursive theme. (I thought you previously said the tree was unordered, which may change how the tree is laid out if it is suppose to be order).
If it is unordered, you can simply recurse the tree in a manner such that
A.) Check root node
B.) Check left node
C.) Continue checking left nodes until either there is a match, or no more left nodes to check
D.) Recurse back 1, check right node
E.) Check left nodes,
F.) Recuse back, check right node
This theme will continue until eventually you have checked ALL left nodes first, and then the right nodes. The KEY to this, is at any point you have a root node, go left first, then right. (I forget what traversal type this is, but there are others if you wish to implement them over this, i personally think this is the easiest to remember).
You will then repeat for right child of Root node.
If at any time you get a match, exit.
Remember this is recursive, so make sure you think your way through this step by step. It is recursive by definition, in that you will always do steps x,y,z for each part of the tree.
To beat a dead horse, lets look at just 3 nodes to start.
(simplified)
First the root,
if(root == (what your looking for))
{
return root
}
else if(root.leftNode == (what your looking for))
{
return root.leftNode
}
else if(root.rightNode == (what your looking for))
{
return root.rightNode
}
else
{
System.out.println("Value not found")
}
If you have 5 nodes, that would be root would have a left and right, and the root.leftNode would have a left and right... You would repeat the steps above on root.leftNode also, then search root.rightNode
If you have 7 nodes, you would search ALL of root.leftNode and then recurse back to search root.leftNode.
I hope this helps,
pictures work much better in my opinion when talking about traversing trees.
Perhaps look here for a better visual
http://www.newthinktank.com/2013/03/binary-tree-in-java/
I am using a Breadth first search in a program that is trying to find and return the shortest path between two nodes on an unweighted digraph.
My program works like the wikipedia page psuedo code
The algorithm uses a queue data structure to store intermediate results as it traverses the graph, as follows:
Enqueue the root node
Dequeue a node and examine it
If the element sought is found in this node, quit the search and return a result.
Otherwise enqueue any successors (the direct child nodes) that have not yet been discovered.
If the queue is empty, every node on the graph has been examined – quit the search and return "not found".
If the queue is not empty, repeat from Step 2.
So I have been thinking of how to track number of steps made but I am having trouble with the limitations of java (I am not very knowledgeable of how java works). I originally was thinking that I could create some queue made up of a data type I made that stores steps and nodes, and as it traverses the graph it keeps track of the steps. If ever the goal is reached just simply return the steps.
I don't know how to make this work in java so I had to get rid of that idea and I moved on to using that wonky Queue = new LinkedList implementation of a queue. So basically I think it is a normal integer queue, I couldn't get my data type I made to work with it.
So now I have to find a more basic approach so I tried to use a simple counter, this doesn't work because the traversal algorithm searches down many paths before reaching the shortest one so I had an idea. I added a second queue that tracked steps, and I added a couple counters. Any time a node is added to the first queue I add to the counter, meaning I know that I am inspecting new nodes so I am not a distance further away. Once all those have been inspected I can then increase the step counter and any time a node is added to the first queue I add the step value to the step queue. The step queue is managed just like the node queue so that when the goal node is found the corresponding step should be the one to be dequeued out.
This doesn't work though and I was having a lot of problems with it, I am actually not sure why.
I deleted most of my code in panic and frustration but I will start to try and recreate it and post it here if anyone needs me to.
Were any of my ideas close and how can I make them work? I am sure there is a standard and simple way of doing this as well that I am not clever enough to see.
Code would help. What data structure are you using to store the partial or candidate solutions? You say your using a queue to store nodes to be examined, but really the objects stored in the queue should wrap some structure (e.g. List) that indicates the nodes traversed to get to the node to be examined. So, instead of simple Nodes being stored in the queue, some more complex object would be needed to make available the information necessary to know the complete path taken to that point. A simple node would only have information about itself, and it's children. But if you're examining node X, you also need to know how you arrived to node X. Just knowing node X isn't enough, and the only way (I know of) to know the path taken to node X is to store the path in the object that represents a "partial solution" or "candidate solution". If this is done, then finding the length of the path is trivial, because it's just the length of this list (or whichever data structure chosen). Hope I'm making some sense here. If not, post code and I'll take a look.
EDIT
These bits of code help show what I mean (they're by no means complete):
public class Solution {
List<Node> path;
}
Queue<Solution> q;
NOT
Queue<Node> q;
EDIT 2
If all you need is the length of the path, and not the path, per se, then try something like this:
public class Solution {
Node node; // whatever represents a node in you algorithm.
int len; // the length of the path to this node.
}
// Your queue:
LinkedList<Solution> q;
With this, before enqueuing a candidate solution (node), you do something like:
Solution sol = new Solution();
sol.node = childNodeToEnqueue;
sol.len = parentNode.len + 1;
q.add(sol);
The easiest solution in order to track distance during a traversal is to add a simple array (or a map if you vertices are not indexed by integers).
Here is pseudo code algorithm:
shortest_path(g, src, dst):
q = new empty queue
distances = int array of length order of g
for i = 0 to order: distances[i] = -1
distances[src] = 0
enqueue src in q
while q is not empty:
cur = pop next element in q
if cur is dst: return distances[dst]
foreach s in successors of cur in g:
if distances[s] == -1:
distances[s] = distances[cur] + 1
enqueue s in q
return not found
Note: order of a graph is the number of vertices
You don't need special data structures, the queue can just contains vertices' id (probably integers). In Java, LinkedList class implements the Queue interface, so it's a good candidate for your queue. For the distances array, if your vertices are identified by integers an integer array is enough, otherwise you need a kind of map.
You can also separate the vertex tainting (the -1 in my algo) using a separate boolean array or a set, but it's not really necessary and will waste some space.
If you want the path, you can also do that with a simple parent array: for each vertex you store its parent in the traversal, just add parent[s] = cur when you enqueue the successor. Then retrieving the path (in reverse order) is a simple like this:
path = new empty stack
cur = dst
while cur != src:
push cur in path
cur = parent[cur]
push src in path
And there you are …
I'm having issues implementing a merge sort for a linked list, specifically, the merge part. I'm trying to sort a linked list containing strings and sort them alphabetically. However, my merge code sometimes skips pointers for some reason depending on the order of the original list. Currently I have:
public node merge(node left, node right){
node result = null;
if(left == null){
return right;
}else if(right == null){
return left;
}
// The data in the node are stored as strings.
// Compare if the string in the left node is less that
// the string in the right.
if(left.info.compareTo(right.info) < 0){
result = left;
result.next = merge(left.next, right);
}else{
result = right;
result.next = merge(left, right.next);
}
return result;
}
If I had a list that consisted of for example, f->t->c->t->h, my merge will return h->t->t, where pointers are being missed. However, if my list consisted of b->a->t->t->c then it correctly display it alphabetically, a->b->c->t->t, and no pointers are missed.
Any help is appreciated.
Thanks.
I think it is because you are holding the old pointers to left and right which may no longer be the heads to the sub-lists.
Change
mergeSort(left);
mergeSort(right);
to
left = mergeSort(left);
right = mergeSort(right);
This probably isn't worth an answer, but here it is.
It's a bit hard to figure out what's going on there, I for one didn't notice any glaring mistakes in the implementation (although I wouldn't use recursion on the merge part, it's simpler to implement it "iteratively").
In my opinion, you need to figure out what's going on step by step. If you know a couple of examples that work and that don't work (seems like you do), call each method directly with the expected input.
For instance, to figure out for sure if your split is working, create a list and pass it to split, print the result. Then call split on the two lists created by split, and so on, to make sure what's happening. (Now would be a good time to use JUnit, but you can do that by "hand" if you want to).
If split works fine for the several cases you can think of, then call the merge routine with two lists, and analyze the result in the same fashion. If that works ok, then add some debugging output to your merge.
Basically, test each part of your algorithm independently, it'll me a lot faster to figure out the problem then looking at it as a whole.
Sorry for writing up a wall of text and still not answering the question, but this is how I would try to solve the problem.
So Currently I have a program that creates a huffman tree. the tree is made up of "Hnodes" with these fields: right (points to right child) left (points to left child) code (string of integers, ideally the 0's and 1's that will be the huffman code of this node) character (the character contained in the node).
I have created the huffman tree by adding nodes from a linked list - i know the tree was created correctly. As i created the tree, i told the node when i gave it a parent node, that if it was the parent's "right", its code string was 1, if left 0. However obviously after the entire tree is created, each node is only going to have either a 0 or 1, but not yet a string like 00100101. My question is, now that I have this tree, can can I traverse it? I understand the thought would be to give each child its parent's code + the child's own code, but I do not understand how to loop through the tree to accomplish this.
Thank you in advance.
Maybe this?
ExpandBinaryPaths(node, prefix)
1. if node is null then return
2. else then
3. node.binary = prefix concat node.binary
4. ExpandBinaryPaths(node.left, node.binary)
5. ExpandBinaryPaths(node.right, node.binary)
6. return
The idea is you would call this on the root with no prefix... ExpandBinaryPaths(root, "").