Reputation: 3
I have been trying to write a Java function IntList get(int i)
that is supposed to return a reference to the i-th
element in a singly linked integer list.
My problem is that the function returns null
, even if I try to reference an existing element!
public class IntList {
private int info; //the int data of this list element
private IntList next; //the rest of the list
/**
* Sets up a new instance of IntList corresponding to the given info and next.
* @param info the int data of this list element
* @param next the rest of the list
*/
public IntList(int info, IntList next) {
this.info = info;
this.next = next;
}
/**
* A new list where the given info has been prepended.
* @param info the int data of the new list element
* @return a new instance of IntList
*/
/*
public IntList prepend(int info) {
return new IntList(info, this);
}
*/
/**
* A new list where the given info has been appended.
* @param info the int data of the new list element
* @return a new instance of IntList
*/
public IntList append(int info) {
if(next == null) {
return new IntList(this.info, new IntList(info, null));
} else {
return new IntList(this.info, next.append(info));
}
}
/**
* Commputes the sum of all elements of this list.
* @return the sum of all elements
*/
public int sum() {
if(next == null) {
return info;
} else {
return info + next.sum();
}
}
/**
* Auxiliary function for the reversal of this list.
* @param acc the list elements accumulated so far
* @return a new instance of IntList
*/
private IntList reverseAux(IntList acc) {
if(next == null) {
return new IntList(info, acc);
} else {
return next.reverseAux(new IntList(info, acc));
}
}
/**
* A new list with the elements of this list in reverse order.
* @return a new instance of the IntList
*/
public IntList reverse() {
return reverseAux(null);
}
/**
* String representation of this list.
*/
@Override
public String toString() {
if(next == null) {
return "" + info;
} else {
return info + " , " + next;
}
}
/**
* An integer array is converted to a list
* @param values is an array containing integer elements
* @return a new instance of IntList
*/
public static IntList fromArray(int[] values) {
int n = values.length;
IntList res = new IntList(values[0] , null);
for(int i = 1; i < n ; i ++) {
res = res.append(values[i]);
}
return res;
}
/**
* The length of a given IntList object is determined
* @return the length of the list
*/
public int length() {
int counter = 1;
while(next != null) {
counter = counter + 1;
next = next.next;
}
return counter;
}
public IntList get(int i) {
for(int k = 0 ; k < i - 1 ; k ++) {
if(next != null) {
next = next.next;
}
}
return next;
}
public static void main(String[] args) {
IntList lst = new IntList(1, null);
for(int i = 2 ; i < 10 ; i ++) {
lst = lst.append(i);
}
System.out.println(lst);
System.out.println(lst.reverse());
System.out.println(lst.sum());
int[] values = new int[4];
values[0] = 3;
values[1] = 4;
values[2] = 5;
values[3] = 8;
System.out.println(fromArray(values));
System.out.println(lst.length());
System.out.println(fromArray(values).length());
System.out.println(lst.get(2));
}
}
Since my implementation of the list does not require two separate classes for nodes and the list itself, I cannot find any valuable information on the web (most people use two classes).
Upvotes: 0
Views: 1593
Reputation: 3761
Your length
method modifies next. Make it recursive (or make a new variable to step through your list):
public int length() {
if(next != null) {
return 1 + next.length();
}
else {
return 1;
}
}
Your get
method also modifies the original list. Recursive solution is:
public IntList get(int i) {
if (i < 0) {
throw new IndexOutOfBoundsException("Index is negative!");
}
if (i == 0) {
return this;
} else if (next != null) {
return next.get(i - 1);
}
throw new IndexOutOfBoundsException("Index exceeds bounds");
}
Upvotes: 1
Reputation: 11308
This one works without checking for IndexOutOfBoundsException:
public IntList get(int i) {
IntList current = this;
for(int k = 0 ; k < i - 1 ; k ++) {
if(current.next != null) {
current = current.next;
}
}
return current;
}
Upvotes: 2
Reputation: 23321
I think you want something like this...
public IntList append(int info) {
if(next == null) {
return new IntList(info, this);
} else {
return new IntList(info, next);
}
}
Upvotes: 0