I am having issues trying to figure out how to display all elements in a LinkedList. I could solve this by having an arraylist to track the index of every element, however I would want to solve this without the use of arraylist or arrays.
The following is what I currently have,
public void displayItems()
{
ArrayList<Node> links = new ArrayList<Node>();
links.add(head);
for (int x = 0; x < count; x++)
{
links.add(links.get(x).getLink());
System.out.println(links.get(x).getData());
}
is there a way to display all elements, in a similar method as mentioned above but without the need for arrays or ListIterator?
A few examples how to loop through LinkedList in Java (including one you don't like - using Iterator):
LinkedList<Node> links = new LinkedList<Node>();
links.add(firstNode);
links.add(secondNode);
links.add(thirdNode);
/* For loop */
for(int i = 0; i < links.size(); i++) {
System.out.println(links.get(i).getLink());
}
/* For-each loop */
for(Node node: links) {
System.out.println(node.getLink());
}
/* While Loop*/
int i = 0;
while (links.size() > i) {
System.out.println(links.get(i++).getLink());
}
/* Iterator */
Iterator<Node> it = links.iterator();
while (it.hasNext()) {
System.out.println(it.next().getLink());
}
You can use an integer as a global variable, while inserting data into Linked List increment this variable.
Write a method in LinkedList class with parameter position. Here loop upto the position, get the data and return the same.
Related
I am trying to add a reverse linked list back to a linked list from an array.
public void reverse(){
//Calling function to take a linked list and put it inside an array
int[] myArray = this.toArray();
//Populate list using array
for (int i= 0; i < myArray.length; i++){
this.addHead(myArray[i]);
}
System.out.println(this.toString());
}
Here is my method this works fine but it only set the linked list to the last index and stops.
EX.
[1,7,7,6]
lS.reverse()
=> [6]
Here is the to array function
//Return int array of list values
public int[] toArray(){
//Creating a array of the size of linkedList
//New copy of head
int f[] = new int[this.size()];
Node newHead = head;
int arrayIndex = 0;
while(newHead != null){
//Set the current Index to the data at head location
f[arrayIndex] = newHead.data();
//Moves the head to next postion
newHead = newHead.next();
//Increment index
arrayIndex = arrayIndex + 1;
}
return f;
}
The result I am looking to acheive is after reverse() is called I will get from
[1,7,7,6]
To A linked list
6,7,7,1
Don't know what you are trying to achieve, but if the initial list is given, there is no need for an array conversion. You can implement something along these lines:
public <T> List<T> reverseList( List<T> list )
{
List<T> newList = new ArrayList<T>();
for( int i = 0; i < list.size(); i++ )
{
newList.add( list.get( list.size() - ( i + 1 ) ) );
}
return newList;
}
If arrays are absolutely needed for some reason, you can use this analogously. Create an array, fill up by reversing index order.
so this method performs daily checks that adds one day to the displayedDays in order to determine the freshness of an item, so the method adds a day then check if it's rotten by calling the method isRotten() and if it's rotten it removes it the array
for (int i = 0; i < numItems; i++) {
items[i].displayedDays++;
}
for (int i = 0; i < numItems;) {
if (items[i].isRotten()) {
if (removeItem(i)) {
if (i > 0) {
i--;
}
continue;
}
}
i++;
}
this is also another method that uses the same loop and if's
so this method is supposed to remove the sweets from the array ( the array has two types of items bread and sweets)
double totalSweetsPrice = 0;
int count = numItems;
for (int i = 0; i < count;) {
Item item = items[i];
if (item instanceof Sweet) {
totalSweetsPrice += item.getPrice();
if (removeItem(i)) {
if (i > 0) {
i--;
}
continue;
}
}
i++;
}
and I don't understand the middle part and was hoping that there is a different loop or something whilst getting the same result
this was how a wrote the daily check method
for (int i = 0; i < numItems; i++) {
items[i].displayDays++ ;
if(items[i].isRotten())
removeItem(i); }
and the output was wrong
Most of the code stems from the fact you change the elements positions in an array you're enumerating. A different kind of data structure, more suited to the removal of elements, such as a linked list, would simplify greatly your code and would be more efficient.
As FooBar said, you can’t both iterate an ArrayList and remove items from that same ArrayList. So you need to separate the conditions. For example:
for (int i = 0; i < items.size(); i++) {
items.get(i).displayedDays++;
}
int i = 0:
while (i < items.size()) {
if(items.get(i).isRotten()) {
items.remove(i);
// don’t increment our counter here because now
// we’ve changed what object exists in the ArrayList
// at this index position
} else {
// only increment our counter if the item in that index
// is good, so we can now move on to check the next item
i++;
}
}
Why not use ArrayList.removeAll(Collection c)? This way, you can create a Collection, such as an ArrayList, iterate through the original list, add all rotten items to your new collection, then call removeAll on the original ArrayList after iterating through the entire list? That way, you don't have to worry about modifying the list while you're iterating through it.
So the original code is
// An (unsorted) integer list class with a method to add an
// integer to the list and a toString method that returns the contents
// of the list with indices.
//
// ****************************************************************
public class IntList {
private int[] list;
private int numElements = 0;
//-------------------------------------------------------------
// Constructor -- creates an integer list of a given size.
//-------------------------------------------------------------
public IntList(int size) {
list = new int[size];
}
//------------------------------------------------------------
// Adds an integer to the list. If the list is full,
// prints a message and does nothing.
//------------------------------------------------------------
public void add(int value) {
if (numElements == list.length) {
System.out.println("Can't add, list is full");
} else {
list[numElements] = value;
numElements++;
}
}
//-------------------------------------------------------------
// Returns a string containing the elements of the list with their
// indices.
//-------------------------------------------------------------
public String toString() {
String returnString = "";
for (int i = 0; i < numElements; i++) {
returnString += i + ": " + list[i] + "\n";
}
return returnString;
}
}
and
// ***************************************************************
// ListTest.java
//
// A simple test program that creates an IntList, puts some
// ints in it, and prints the list.
//
// ***************************************************************
import java.util.Scanner ;
public class ListTest {
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
IntList myList = new IntList(10);
int count = 0;
int num;
while (count < 10) {
System.out.println("Please enter a number, enter 0 to quit:");
num = scan.nextInt();
if (num != 0) {
myList.add(num);
count++;
} else {
break;
}
}
System.out.println(myList);
}
}
I need to change the add method to sort from lowest to highest. This is what I tried doing.
// An (unsorted) integer list class with a method to add an
// integer to the list and a toString method that returns the contents
// of the list with indices.
//
// ****************************************************************
public class IntList {
private int[] list;
private int numElements = 0;
//-------------------------------------------------------------
// Constructor -- creates an integer list of a given size.
//-------------------------------------------------------------
public IntList(int size) {
list = new int[size];
}
//------------------------------------------------------------
// Adds an integer to the list. If the list is full,
// prints a message and does nothing.
//------------------------------------------------------------
public void add(int value) {
if (numElements == list.length) {
System.out.println("Can't add, list is full");
} else {
list[numElements] = value;
numElements++;
for (int i = 0; i < list.length; i++) {
if (list[i] > value) {
for (int j = list.length - 1; j > i; j--) {
list[j] = list[j - 1];
list[i] = value;
break;
}
}
}
for (in i = 0; i < list.length; i++) {
}
}
}
//-------------------------------------------------------------
// Returns a string containing the elements of the list with their
// indices.
//-------------------------------------------------------------
public String toString() {
String returnString = "";
for (int i = 0; i < numElements; i++) {
returnString += i + ": " + list[i] + "\n";
}
return returnString;
}
}
The outcome is very wrong. Any one able to steer me in the right direction? I can sort of see why what I have doesn't work, but I can't see enough to fix it.
So I realize I was not very descriptive here the first time. With the exception of the add method modifications the code was not my doing. My assignment is to only touch the add method to sort the array to print out smallest to largest. This is a beginners class and we do little to no practice my only tools for this are some basic understandings of loops and arrays.
I tried redoing it again and came up with this:
if(list[numElements-1] > value){
for(int i=0; i<numElements; i++){
if(list[i]>value){
for(int j = numElements; j>i; j-- ){
list[j] = list[j-1];
}
list[i] = value;
break;
}
}
numElements++;
}
else
{
list[numElements] = value;
numElements++;
}
my input was:8,6,5,4,3,7,1,2,9,10
the output was: 1,10,1,9,10,1,1,2,9,10
this thing is kicking my butt. I understand I want to check the input number to the array and move all numbers higher than it up one space and enter it behind those so it is sorted on entry, but doing so is proving difficult for me. I apologize if my code on here is hard to follow formatting is a little odd on here for me and time only allows for me to do my best. I think break is not breaking the for loop with i like i thought it would. Maybe that is the problem.
The biggest bug I see is using list.length in your for loop,
for(int i = 0; i <list.length; i++)
you have numElements. Also, I think it's i that needs to stop one before like,
for(int i = 0; i < numElements - 1; i++)
and then
for (int j = numElements; j > i; j--)
There are two lines that have to be moved out of the inner loop:
for (int i = 0; i < list.length; i++) {
if (list[i] > value) {
for (int j = list.length - 1; j > i; j--) {
list[j] = list[j - 1];
// list[i] = value;
// break;
}
list[i] = value;
break:
}
}
In particular, the inner break means that the loop that is supposed to move all larger elements away to make room for the new value only runs once.
You might want to include Java.util.Arrays which has its own sort function:
http://www.tutorialspoint.com/java/util/arrays_sort_int.htm
Then you can do:
public void add(int value) {
if (numElements == list.length) {
System.out.println("Can't add, list is full");
}
else {
list[numElements] = value;
numElements++;
Arrays.sort(list);
//Or: Java.util.Arrays.sort(list);
}
}
As Eliott remarked, you are getting confused between list.length (the capacity of your list) and numElements (the current size of your list). Also, though, you do not need to completely sort the list on each addition if you simply make sure to insert each new element into the correct position in the first place. You can rely on the rest of the list already to be sorted. Here's a simple and fast way to do that:
public void add(int value) {
if (numElements == list.length) {
System.out.println("Can't add, list is full");
} else {
int insertionPoint = Arrays.binarySearch(list, 0, numElements);
if (insertionPoint < 0) {
insertionPoint = -(insertionPoint + 1);
}
System.arrayCopy(list, insertionPoint, list, insertionPoint + 1,
numElements - insertionPoint);
list[insertionPoint] = value;
numElements += 1;
}
}
That will perform better (though you may not care for this assignment), and it is much easier to see what's going on, at least for me.
Here are some hints.
First, numElements indicates how many elements are currently in the list. It's best if you change it only after you have finished adding your item, like the original method did. Otherwise it may confuse you into thinking you have more elements than you really do at the moment.
There is really no need for a nested loop to do proper adding. The logic you should be following is this:
I know everything already in the list is sorted.
If my number is bigger then the biggest number (which is the one indexed by numElements-1, because the list is sorted) then I can just add my number to the next available cell in the array (indexed by numElements) and then update numElements and I'm done.
If not, I need to start from the last element in the array (careful, don't look at the length of the array. The last element is indexed by numElements-1!), going down, and move each number one cell to the right. When I hit a cell that's lower than my number, I stop.
Moving all the high numbers one cell to the right caused one cell to become "empty". This is where I'm going to put my number. Update numElements, and done.
Suppose you want to add the number 7 to this array:
┌─┬──┬──┬─┬─┐
│3│14│92│-│-│
└─┴──┴──┴─┴─┘
⬆︎ Last element
You move everything starting from the last element (92) to the right. You stop at the 3 because it's not bigger than 7.
┌─┬─┬──┬──┬─┐
│3│-│14│92│-│
└─┴─┴──┴──┴─┘
(The second element will probably still contain 14, but you're going to change that in the next step so it doesn't matter. I just put a - there to indicate it's now free for you to enter your number)
┌─┬─┬──┬──┬─┐
│3│7│14│92│-│
└─┴─┴──┴──┴─┘
⬆︎ Updated last element
This requires just one loop, without nesting. Be careful and remember that the array starts from 0, so you have to make sure not to get an ArrayIndexOutOfBoundsException if your number happens to be lower than the lowest one.
One problem I spotted is that: you are trying to insert the newly added number into the array. However your loop:
for (int i = 0; i < list.length; i++) {
if (list[i] > value) {
for (int j = list.length - 1; j > i; j--) {
list[j] = list[j - 1];
list[i] = value;
break;
}
}
}
is always looped through the total length of the array, which is always 10 in your test, rather than the actual length of the array, i.e. how many numbers are actually in the array.
For example, when you add the first element, it still loops through all 10 elements of the array, although the last 9 slots does not have value and are automatically assigned zero.
This caused your if statement always returns true:
if (list[i] > value)
if you have to write the sort algorithm yourself, use one of the commonly used sorting algorithm, which can be found in Wikipedia.
If any one was curious I finally worked it out. Thank you to everyone who replied. This is what i ended up with.
public void add(int value)
{
if(numElements == 0){
list[numElements] = value;
numElements++;
}
else{
list[numElements] = value;
for(int check = 0; check < numElements; check++){
if(list[check] > value){
for(int swap = numElements; swap> check; swap--){
list[swap] = list[swap-1];
}
list[check] = value;
break;
}
}
numElements++;
}
}
so my original is the same but we have to make another class
A Sorted Integer List
File IntList.java contains code for an integer list class. Save it to your project and study it; notice that the only things you can do are create a list of a fixed size and add an element to a list. If the list is already full, a message will be printed. File ListTest.java contains code for a class that creates an IntList, puts some values in it, and prints it. Save this to your folder and compile and run it to see how it works.
Now write a class SortedIntList that extends IntList. SortedIntList should be just like IntList except that its elements should always be in sorted order from smallest to largest. This means that when an element is inserted into a SortedIntList it should be put into its sorted place, not just at the end of the array. To do this you’ll need to do two things when you add a new element:
Walk down the array until you find the place where the new element should go. Since the list is already sorted you can just keep looking at elements until you find one that is at least as big as the one to be inserted.
Move down every element that will go after the new element, that is, everything from the one you stop on to the end. This creates a slot in which you can put the new element. Be careful about the order in which you move them or you’ll overwrite your data!
Now you can insert the new element in the location you originally stopped on.
All of this will go into your add method, which will override the add method for the IntList class. (Be sure to also check to see if you need to expand the array, just as in the IntList add() method.) What other methods, if any, do you need to override?
To test your class, modify ListTest.java so that after it creates and prints the IntList, it creates and prints a SortedIntList containing the same elements (inserted in the same order). When the list is printed, they should come out in sorted order.
I have an array of objects of my custom class and i want to delete a random object(chosen by some criteria). how do i do this and keep the array ordered? naturally, there would be shifting of elements towards the left but i don't quite get the deleting the element part and need help formulating the logic. this is what i am doing but for it doesn't work correctly :(
public static void deleteRecord(Customer[] records, int AccId){
int pos=0; // index
boolean found = false;
for (int i=0; i<count; i++){ // count is the number of elements in the array
if (records[i].get_accountid()==AccId){
found = true;
pos = i;
break;
}
}
if (!found)
System.out.println("The Record doesn't exist");
for (int j=pos+1; j<count; j++) {
records[j-1]= records[j];
}
You can just shift the elements to the left as this will overwrite the item to be deleted.
public void remove(Object[] a, int index) {
for (int i = index + 1; i < a.length && a[i] != null; i++) {
a[i - 1] = a[i];
}
}
Assuming that the first null indicates the end of the elements.
Of course, this is O(n) time and there are data structures like LinkedList that can remove elements in O(1) time.
Unfortunately, you can't just delete an element from an array, not without either leaving empty indices or creating a new array. I would create a new array and use System.arraycopy to simplify copying over your elements. Something like:
Object[] newArr = new Object[arr.length-1];
System.arraycopy(arr,0,newArr,0,index);
System.arraycopy(arr,index+1, newArr, index, newArr.length - index);
return newArr;
Where arr is your original array and index is the random index to remove. Basically, it copies all elements up to the index to remove, and then copies all elements after the index. You can wrap this up in a separate method for simplicity. (Instead of using arraycopy, you could use two for-loops to accomplish the same thing).
I strongly suggest as others have to use a List, which simplifies adding and removing elements.
use List collection e.g:
List<String> list = new ArrayList<String>();
int toDelete = getRandomIndex(lst.size()); //your own implementation
if (toDelete >= 0) {
list.remove(toDelete); // it'll remove and shift elements
}
documentation about List.remove(int):
Removes the element at the specified
position in this list (optional
operation). Shifts any subsequent
elements to the left (subtracts one
from their indices). Returns the
element that was removed from the
list.
i have this script, but i can't increment
LinkedList<Card> deckOfCards = new LinkedList<Card>();
for (int count = 0; count < deckOfCards.size(); count++) {
deckOfCards[count].add(new Card(Rank.values()[count % 13].toString(),Suit.values()[count / 13].toString(), number[count % 13],Image[count % 52]));
}
i get an error on deckOfCards[count], so my doubt is how i can do this
(The type of the expression must be an array type but it resolved to LinkedList)
i previous code is an array, and works
deckOfCards = new Card[number_cards];
for (int count = 0; count < deckOfCards.length; count++) {
deckOfCards[count] = new Card(Rank.values()[count % 13].toString(),Suit.values()[count / 13].toString(), number[count % 13],Image[count % 52]);
}
}
//suppose to get na name, value of card, but the result is [null, null, null, etc]
public Card[] giveCardPlayer1() {
String name1 = Arrays.toString(deckOfCards);
nameF = name1;
String suit_1 = deckOfCards.toString();
suit1 = suit_1;
return deckOfCards;
}
public int totalValuePlayer1() {
return currentTotal1;
}
public String name1() {
return nameF;
}
public String suit_1() {
return suit1;
}
thanks!!!!
Just call deckOfCards.add(...).
You can't index a Java List the same way you would an array. You have to use its add() method instead. This appends the specified element to the end of the list.
There is also another add() method which takes an int index parameter. However, since lists are not of fixed size, you can't just directly set the nth element of the list by calling deckOfCards.add(count, new Card(...)) - you need to ensure first that the specified element exists in the list, otherwise you get an IndexOutOfBoundsException. It is also worth mentioning that accessing linked lists by index is a slow operation (compared to e.g. ArrayLists) for any list of nontrivial size.
Update
Ah, and you need to fix your loop invariant too. The current version
for (int count = 0; count < deckOfCards.size(); count++) { ...
will never execute the loop body, since the initial size of your list is 0. Change it to
for (int count = 0; count < number_cards; count++) { ...
In addition to Peter's post; if you need to index a list like you try to do here, you can use ArrayList instead.