I'm having a problem in which the method outputs null instead of returning the (n+1)th item of the list. Is there anything that I'm overlooking .
public static ListElement getItem(ListElement head, int n){
if(n == 0){
return head;
}else if(head == null){
return null;
}else{
return getItem(head.getNext(),n+1);
}
}
This code doesn't make sense. If head is not null, it will call getItem(head.getNext(), n+1) but eventually, head will equal null (and n will never go to 0) and therefore it will return you null. Maybe you meant
return getItem(head.getNext(), n-1).
change from n+1 to n-1 (in order to get to the base case of the recursion, n == 0):
return getItem(head.getNext(),n-1);
You should be doing n-1, not n+1. n corresponds to the position of the element you want, and if you remove the top item in the list everything moves up down one position, not up.
Change to getItem(head.getNext(),n-1);
Related
I need help with my homework
My question is: How to complete the method findMaxItem below to return a pointer to the largest element of the linked list given by the parameter ptr, or return null if the list is empty. The solution must be a recursive one.
This my my answer but is not correct:
public static Node findMaxItem (Node ptr) {
if (ptr == null) {
return null;
} else {
if (ptr.next.data > ptr.data) {
Node n = ptr.next;
if (ptr.next.data >= n.data) {
n = ptr.next;
//ptr = n.next;
findMaxItem(n);
} else {
ptr = ptr.next;
findMaxItem(ptr);
}
ptr = n.next;
findMaxItem(ptr);
ptr = n;
}
// ptr = ptr.next;
// findMaxItem(ptr);
}
return ptr;
}
Thanks for help everyone :)
You've at least got the first part right: if the list is empty, return null. This is the base case of the recursion.
if (ptr == null) return null;
You're meant to use recursion for the rest of the cases. But how?
If the list is not empty, you can divide it into two parts: the first item, and the rest of the list. Would it help you "find the max item" in the rest of the list?
Node restOfTheList = ptr.next;
Node maxOfRestOfTheList = findMax(restOfTheList);
Now you have the first item, referenced by ptr, and the item with the greatest value in the rest of the list. If you compare the data in those, you can figure out which has the greatest value. And which ever it is, that is the node with the largest item. Does that make sense?
if data of "ptr" is greater than data of "maxOfRestOfTheList": return ptr
else: return maxOfRestOfTheList;
You'll also have to deal with the case where there is only one item in the list. In that situtation restOfTheList is empty.
One possible solution is to create a method that receive the array with the values -1 and the last value. Then check if the next last element is greater that the one you have or not, if it is, the new value is the current maximum remove it and call the same method by using the new array (with the removed value) and the current maximum.
The base case will be when there is only one element in the array, take or compare it with the last maximum value you passed to the recuerdo be función and return the greater value of these two. This last will be the maximum in a recursive way.
I have no possibility to write the code right now but in meta-code it should be something like this
private int finalMax
public void maxRecursive(arrayList<int>List, Int tempMax){
//Base case
Int newTempMax = tempMax
If (tempMax >list.get(list.size-1)){
newTempMax=list.get(list.size()-1)
}
If (list.size()>1){
List.remove(list.size()-1)
maxRecursive(list, newTemMax)
}else{
finalMax=newTempMax
}
}
As I said this is nothing more than pseudo-code that looks adapted to java, I cannot son anything better right now but AI think that you can get the Idea from here.
Best!
Beginner here using Java (first year student), and am unable to get the below function to work. The goal is to use recursion and a helper function to compute the size of a singly linked list. When running the code against test lists, it keeps returning List changed to [].
I'm struggling in general with Java, so any help is appreciated. Thank you
public class MyLinked {
static class Node {
public Node(double item, Node next) {
this.item = item;
this.next = next;
}
public double item;
public Node next;
}
int N;
Node first;
public int sizeForward() {
return sizeForwardHelper(first);
}
public int sizeForwardHelper(Node n) {
Node current = first;
if (current == null) {
return 0;
} else {
first = first.next;
return sizeForward() + 1;
}
}
I believe I have the first portion set up to return 0 if there are no elements in the List. I believe it's the second part that isn't setting up correctly?
Thanks
Because it’s important for your learning to not spoonfeed you, I’ll describe an approach rather than provide code.
Use this fact:
The length of the list from any given node to the end is 1 plus the length measured from the next node (if there is one).
Usually (as would work here), recursive functions take this form:
If the terminating condition is true, return some value
Otherwise, return some value plus the recursively calculated value
When writing a recursive function, first decide on the terminating condition. In this case, n == null is the obvious choice, and you’d return 0, because you’ve run off the end of the list and the length of nothing (ie no node) is nothing. This also handles the empty list (when first is null) without any special code.
Otherwise, return 1 (the length of one node) plus the length of next.
Put that all together and you’ll have your answer.
——
Hint: The body of the recursive helper method can be coded using one short line if you use a ternary expression.
Instead of calling your wrapper function call your helper function recursively. Try the following:
public int sizeForward () {
return sizeForwardHelper (first);
}
public int sizeForwardHelper(Node n) {
if (n == null) // base case
return 0;
return sizeForwardHelper(n.next) + 1; // count this node + rest of list
}
Your method that computes the size of the list actually modifies the list in the process (with first = first.next; you set the first element to the next, and since there is a recursion, the first element always end up being null which is equivalent to an empty list with your design). Your method will work once, but your list will be empty afterwards.
To illustrate this, I added a print next to the instruction first = first.next; and wrote the following main:
public static void main(String[] args) {
Node n2 = new Node(2d, null);
Node n1 = new Node(1d, n2);
Node n = new Node(0, n1);
MyLinked l = new MyLinked(n);
System.out.println("The first element is: "+l.first.item);
System.out.println("The size is: "+l.sizeForward());
System.out.println("The first element is: "+l.first);
}
It yields:
The first element is: 0.0
first is set to 1.0
first is set to 2.0
first is set to null
The size is: 3
The first element is: null
Clearly, you should not modify the list while computing its size. The helper method should return 0 if the node is null (empty list), and 1 plus the size of the rest of the list otherwise. Here is the code.
public int sizeForwardHelper(Node n) {
if (n == null)
return 0;
else
return sizeForwardHelper(n.next) +1;
}
The goal of the arg free method sizeForward() is just to call the helper. The helper should not use it though.
EDIT: Solved. Returning a 0 works, apparently!
Ok so long story short, I have to return an int value, but nothing when a Linked List is empty. How do I do it?
public int countDuplicates() {
int duplicates = 0;
ListNode current = front;
int num = current.data;
current = current.next;
while(current != null) {
if(current.data == num) {
duplicates++;
} else {
num = current.data;
}
current = current.next;
}
return duplicates;
}
When I try this:
if(front == null) {
return ;
}
This doesn't work. What can I do?
You can rather throw an IllegalArgumentException: -
if(front == null) {
throw new IllegalArgumentException("List is empty");
}
If your method returns an int you must determine an acceptable value to represent "nothing". Such as 0 or if valid results are >= 0, use a negative value such as -1 to indicate "nothing".
Alternatively, modify your method to return an Integer object in which case you can return null.
It is possible for you to either define a fixed value, such as Integer.MIN_VALUE, that would indicate that the list is empty, or change the declaration of your method to public Integer countDuplicates(), and return null when the list is empty.
To keep the code as you have it now, you must either return an int, throw an exception, or exit.
Return an int: You'll have to specify a certain int value as the "fail" value and make sure that it is never the case that this value is hit during "normal" execution.
Throw an exception: Detailed in another answer - you've already shot it down.
Exit the program... if it makes sense to do that.
The best option may be to change the code - make the function return an Integer, for example, so the null option is there. There are surely other ways to work around it, as well.
you can change the return value from int to object like this
public Object countDuplicates() {
if(////condition)
return ///int;
else
return null;
You could return a negative value or change the return type to string and parse the result to int.
If you don't want to (or can't) throw an exception, return some "exceptional value", such as a negative number. For example, Java has a lot of indexOf(Object somethingToLookFor) methods that return a -1 if the item isn't found.
In your example, -1 works as exceptional because there can never be -1 duplicates.
Personally, I would just return 0 for an empty List. An empty list has 0 duplicates. But if the spec insists on something exceptional, return -1.
public boolean isEmpty(){
if (head == null) return true;
else return false ;
}
I need to make a method that removes the last element of a LinkedList using recursion.
This is what I have so far but it doesn't seem to be removing the node...when i call list.size() it is still the same size with the same values. What am I doing wrong here?
This is for Java by the way
public void removeLastElement(Node curr){
if (curr == null)
return;
else{
if(curr.next == null)
curr = null;
else
removeLastElement(curr.next);
}
}
In a LinkedList to remove the last element you have to get the penultimate element and set
curr.next = null
You're in the right way to get the recurrent function to remove the last node. The problem is you're identifying the penultimate node with curr.next == null, if you got it, you nullify it, but that's your actual input! So, you must check if the actual node is the antepenultimate node on the list:
if (curr.next.next == null) {
curr.next = null; //Now you're modifying the data in your input.
}
With this change, there are more basic cases to check, but that's up to you, my friend.
Boolean deleteLast(Node n)
{
if(n.next == null)
return true;
if(deleteLast(n.next))
{
n.next = null;
return false;
}
return false;
}
Node deleteLast(Node n) {
if (n.next == null)
return null;
n.next = deleteLast(n.next);
return this;
}
The general idea is you ask the next node "hey, can you tell me where you are, and delete your last node?" The last node can then just say "I'm nowhere" and it'll all fall into place.
This is very similar to Aadi's answer, just using Nodes instead of booleans.
I have a binary tree made with the following constructor:
public Person(String name, int age, char gender, Person c1, Person c2)
where c1 is the left child and c2 is the right child.
I want to write a method that searches for a particular name within a maximum generation. So like a.depthFirstSearch(Eva, 1); where Eva is the name to search for and 1 is the maximum number of generations (or levels) I can look into.
Here's what I have:
EDIT:
public Person depthFirstSearch(String name, int maxGeneration)
{
{
Person temp;
if (maxGeneration>1){
if (this.name.equals(name)){
temp=this;
return temp;
}
else{
if (child1!=null)
temp=child1.depthFirstSearch(name, maxGeneration-1);
if (child2!=null)
temp=child1.depthFirstSearch(name, maxGeneration-1);
}
}
return null;
}
}
There's two problems here. I think depth gets reset to 0 every time the function calls itself, so I know I can either keep track of depth somewhere else or find an alternative. The other problem, I think, is that child2 is never really reached, since I return at child1. I'm not really sure how this works so if someone could explain that, that'd be great. Any suggestions for some fixes?
Also, I'm told that I have to search depth first, meaning looking into the deeper generations first. I'm not really sure what that means and how different it is from the logic I'm using in my implementation.
Since you decrement maxGeneration in each recursive call, you don't need the depth variable at all: when maxGeneration == 0 you simply don't search any more and return null.
As for your other problem, instead of directly returning the value of child1.depthFirstSearch(...), store the value in a temporary variable. If it is not null, you have found the node, so return it immediately, otherwise continue searching under child2.
Update:
It should be if (maxGeneration >= 1) ... (greater than or equal to), otherwise the last call with maxGeneration == 1 will always return null. Alternatively, you can just check for 0 and return null:
if (maxGeneration == 0)
return null;
// rest of your code
Also, you still aren't using the return value to check if the node was actually found in the left subtree or not. Right now, even if you find the node under child1, you still look under child2 and you will end up returning null, which is wrong. You need to search under child2 only if the left search returned null:
Person temp;
if (child1 != null) {
temp = child1.depthFirstSearch(name, maxGeneration-1);
if (temp != null)
return temp; // found the node, just return
}
// otherwise the following code will execute
if (child2 != null) {
temp = child2.depthFirstSearch(name, maxGeneration-1);
if (temp != null)
return temp; // found the node, just return
}
// didn't find node under either child
return null;