I've got a basic binary search tree in Java. I'm trying to output the variable value, but all I get are addresses instead of the value itself. Also, can someone explain the relation between the code in my inOrderTraversal method and how it relates to the display() in my Node class even though I'm not calling it myself? All I'm calling in main is addNode and inorderTraversal.
The following is my code:
class Node {
int value;
Node leftChild;
Node rightChild;
Node(int value, String name) {
this.value = value;
this.name = name;
}
public int displayNode() {
return value;
}
}
InOrderTraversal Method:
public void inOrderTraverseTree(Node focusNode) {
if (focusNode != null) {
// Traverse the left node
inOrderTraverseTree(focusNode.leftChild);
// Visit the currently focused on node
System.out.print(focusNode + " ");
// Traverse the right node
inOrderTraverseTree(focusNode.rightChild);
}
}
Current Output: Node#7852e922 Node#4e25154f Node#70dea4e Node#5c647e05 Node#33909752 Node#55f96302
Desired Output: 5 10 15 20 25 30
I'm pretty familiar with C++, was just self-learning Java and ran into these peculiar issues.
I'm only getting addresses not values of the nodes
What is the link between inOrderTraversal and display()? I'm not even calling the display() method myself.
You're printing an object, not its inner value (in other words, you're calling toString() implicitly).
In order to print the value, you should get the value from Node object:
System.out.print(focusNode.displayNode() + " ");
Also I would recommend you to rename your displayNode() method to getValue(), as it is better explains what the method does.
And if you want your method to print something when calling System.out.println(object);, you should override toString() method in Node class:
#Override
public String toString() {
return this.value;
}
Then your code System.out.print(focusNode + " "); will display the node's value instead of object's address im memory.
public String recursiveToString()
{
DoubleLinkedListNode<T> current = first;
String list = "";
if(current == null)
{
return "";
}
else
{
list += current.info + ", ";
current = current.next;
return list + recursiveToString();
}
}
It is supposed to print out the list when I run the code but it just crashes every time it runs. This is everything that I've tried to do so far.
First off you'll want to pass the current position in the list back into the function each time, so change your signature to this:
public String recursiveToString(DoubleLinkedListNode<T> current)
Then alter your code a bit so it uses that and continues to pass it down, the list variable is also unnecessary, the recursion will take care of concatenating everything:
public String recursiveToString(DoubleLinkedListNode<T> current)
{
if(current == null)
{
return "";
}
else
{
return current.info + " " + recursiveToString(current.next);
}
}
If you would like to do it without changing the signature of the function, just rename the function I have above and create the definition for your parameterless function like so:
public String recursiveToString()
{
return aboveFunction(first);
}
I'm writing a program and I'm supposed to check and see if a certain object is in the list before I call it. I set up the contains() method which is supposed to use the equals() method of the Comparable interface I implemented on my Golfer class but it doesn't seem to call it (I put print statements in to check). I can't seem to figure out whats wrong with the code, the ArrayUnsortedList class I'm using to go through the list even uses the correct toString() method I defined in my Golfer class but for some reason it won't use the equals() method I implemented.
//From "GolfApp.java"
public class GolfApp{
ListInterface <Golfer>golfers = new ArraySortedList<Golfer> (20);
Golfer golfer;
//..*snip*..
if(this.golfers.contains(new Golfer(name,score)))
System.out.println("The list already contains this golfer");
else{
this.golfers.add(this.golfer = new Golfer(name,score));
System.out.println("This golfer is already on the list");
}
//From "ArrayUnsortedList.java"
protected void find(T target){
location = 0;
found = false;
while (location < numElements){
if (list[location].equals(target)) //Where I think the problem is
{
found = true;
return;
}
else
location++;
}
}
public boolean contains(T element){
find(element);
return found;
}
//From "Golfer.java"
public class Golfer implements Comparable<Golfer>{
//..irrelavant code sniped..//
public boolean equals(Golfer golfer)
{
String thisString = score + ":" + name;
String otherString = golfer.getScore() + ":" + golfer.getName() ;
System.out.println("Golfer.equals() has bee called");
return thisString.equalsIgnoreCase(otherString);
}
public String toString()
{
return (score + ":" + name);
}
My main problem seems to be getting the find function of the ArrayUnsortedList to call my equals function in the find() part of the List but I'm not exactly sure why, like I said when I have it printed out it works with the toString() method I implemented perfectly.
I'm almost positive the problem has to do with the find() function in the ArraySortedList not calling my equals() method. I tried using some other functions that relied on the find() method and got the same results.
Your equals method should take an Object argument, not a Golfer. The equals(Golfer) method is overloading the Comparable's equals(Object) method but does not implement it. It's simply an overloaded method no other code knows about, so it doesn't get called.
public boolean equals(Object obj)
{
if(!(obj instanceof Golfer)) return false;
Golfer golfer = (Golfer)obj;
String thisString = score + ":" + name;
String otherString = golfer.getScore() + ":" + golfer.getName() ;
System.out.println("Golfer.equals() has bee called");
return thisString.equalsIgnoreCase(otherString);
}
I need to understand the best way to display my linkedBinaryTree. right noe the driver is passing in integers as elements to each node of the tree, For the toString i have tried the following snippet of code but all it returns is for instance is javafoundations.ArrayIterator#ca0b6.
public String toString() {
String thing = "BinaryTreeNode: ";
if (root.getLeft() != null ) {
thing += root.getLeft().toString()+" ";
}
if (root.getRight() != null) {
thing += root.getRight().toString();
}
thing += "}";
return thing;
}
You just need to override the method
public String toString()
in the node class you are using. Doing that will replace the useless representation to a more sense one.
Of course you need to understand which is your data object inside the tree (I don't know if a node is a value of if it contains a value) so that you'll be able to call the correct toString method.
In any case you don't need to explicitly call it whenever you are using string concatenation operator eg "" + root.getLeft()
Ok so say I have a function that looks for a specific word in a custom LinkedList class:
public LinkedList find(String word) {
if (this.word.equals(word))
return this;
if (next==null)
return null;
if (next.find(word)==next)
return next;
return null;
}
This code works fine, however it returns the FIRST found object that matches the criteria. What if I wanted to return the LAST object found that matches the paramater? I'm having a hard time figuring this out. Keep in mind I want to use recursion.
EDIT: What would be wrong with this code:
public LinkedList findLast(String word) {
LinkedList temp=new LinkedList(word, null);
if (next==null && next.word.equals(word))
return next;
if (next==null && !next.word.equals(word))
temp=next.findLast(word);
return temp;
}
Well, think of it this way: you need to recurse right to the end of the list, and then let the return value bubble up.
So the start of your method should either be a recursive call to look further down the list, or noting that we're at the end of the list - which is equivalent to the "further" result being null.
Now when you're returning, there are three options:
You've already found a match later than the current point - so return that reference
You've not found a match (so the return value of the recursive call was null) and:
The current point's word matches - so return the current point
The current point doesn't match - so return null
Hopefully that should be enough to get you to an implementation - if not, please ask more questions. I'd rather not give a full implementation when this is presumably homework.
Store a reference to the latest one found and keep on calling itself until it returns null -- then return the latest-reference.
Note, for clarification: you're going to have to iterate through your entire linked-list (unless you have a doubly-linked-list) to achieve this -- store a reference every time you find a match (but just overwrite the same reference each time) -- then return whatever the reference holds once you reach the end of this list.
public class LinkedList {
private static int uniqueIdCounter = 0;
private final String word;
private int uniqueId;
private LinkedList next = null;
public LinkedList( String word ) {
this.word = word;
this.uniqueId = uniqueIdCounter++;
}
#Override
public String toString() {
return this.word + "(" + this.uniqueId + ")";
}
public void setNext( LinkedList next ) {
this.next = next;
}
public LinkedList find( String word ) {
return this.find( word, null );
}
public LinkedList find( String word, LinkedList result ) {
if( this.word.equals( word ) ) {
result = this;
}
if( this.next != null ) {
result = this.next.find(word, result);
}
return result;
}
public static void main(String[] args) {
LinkedList head = new LinkedList( "A");
System.out.println( "Head is: " + head );
LinkedList B = new LinkedList( "B" );
head.setNext( B );
System.out.println( "B is: " + B );
LinkedList A2 = new LinkedList( "A" );
B.setNext( A2 );
System.out.println( "A2 is: " + A2 );
LinkedList last = head.find( "A" );
System.out.println( "Last is: " + last );
}
}
And here's the output:
Head is: A(0)
B is: B(1)
A2 is: A(2)
Last is: A(2)
Every straight recursive function has two places for some useful actions: before further method call and after:
function(n){
doBefore(n);
function(n+1)
doAfter(n)
}
doBefore() is executed "on the way forward", doAfter() is executed "on the way back". Now your algorithm checks word equality on the way forward. You have to modify your algorithm so that this check is performed on the way back.
public LinkedList find(String word, LinkedList result) {
if (this.word.equals(word))
result = this;
if (next != null )
return next.find(word, result)
return result;
Two-liner:
public LinkedList find(String word, LinkedList result) {
result = this.word.equals(word) ? this : result;
return next == null ? result : next.find(word, result);
#fprime: Ya, explanation: remember the result, replace it with later result, return when at the end.
Method with one argument:
public LinkedList find(String word){
result = this.word.equals(word) ? this : null;
if(next != null)
previous = next.find(word);
return (previous != null) ? previous : result
else
return result;
Just run it backwards from the tail.
public LinkedList find(String word) {
if (this.word.equals(word))
return this;
if (prev==null)
return null;
if (prev.find(word)==prev)
return prev;
return null;
}
To start with, you initial find(String word) does not work correctly.
Your first if statement is perfect. It is you success base case.
Your second if statement is also perfect. It is your failure base case.
Your third is where you go off the rails. You have handled all (in this case both) base cases, now all that is left is the recursive case. You don't need to check anything here. next.find(word) will return the correct answer, success or fail.
For findLast(String word), I can't add much to what Jon Skeet said. About the only advice I can add it to never have the a node check its neighbor. Each node should only ever check itself. You should see plenty of this.word.equals(word) but never next.word.equals(word).
public LinkedList find(String word) {
if(this.word.equals(word)) return this;
return next==null?null:next.find(word);
}
public LinkedList rfind(String word) {
if(next != null) {
LinkedList res = next.rfind(word);
if(res != null) return res;
}
return this.word.equals(word)?this:null;
}