I want to create a method that loops though a circular linked list, Essentially mimicking a token ring network. I create a random number of either 0 or 1, if it is 0, it deletes the first item in the list. If it is one it just says they are still logged on.
So i should have something like this..
User A Logged on
User B logged off
User A logged off
When list is clear it terminates
The problem is it seems to always leave one particular user....How can I make this work?
public void log(){
if(start==null)
System.out.println("List is empty..");
else{
Node temp=start;
System.out.print("->");
//get rid of each user with a similar method but with a random user removed....
while(temp.next!=null && count>0)
{
int r = rand.nextInt(2);
if(r==0)
{
deleteAt(0);
System.out.println(" OFF"+temp.data);
}
else if(r==1)
{
System.out.println(" ON "+temp.data);
}
temp=temp.next;
}
//System.out.println(counter);
}
}
public void deleteFirst() {
Node temp=start;
while(temp.next!=start){
temp=temp.next;
}
temp.next=start.next;
start=start.next;
count--;
}
public void deleteAt(int position){
Node current=start;
Node previous=start;
for(int i=0;i<position;i++){
if(current.next==start)
break;
previous=current;
current=current.next;
}
if(position==0)
deleteFirst();
else
previous.next=current.next;
count--;
}
Deleting the last element from a circular linked list is a special case, because you need to set start to null. So you need to cater for that in your delete routines: test whether start->next == start.
Besides that, looping through the list while deleting elements requires special care: temp in the outer loop in log() can point to the removed element, rather than an element in the list. Taking temp=temp->next then may not be valid.
Also, count is decremented twice in deleteAt(0).
Related
Could someone tell me what's missing in my code. I am trying to remove the first occurrence of a given node value.
It fails very few test cases, but I am not sure what I am missing. Here is my code :
public boolean remove(E obj) {
if (obj == null)
throw new IllegalArgumentException("Violation of precondition : remove(E obj)");
DoubleListNode<E> current = head;
for (int i = 0; i < size; i ++) {
if (current.getData().equals(obj)) {
E result = remove(i);
return true;
}
current = current.getNext();
}
size --;
return false;
}
That recursive call to remove() inside the if block looks wrong.
You are already inside the list, you identified the first matching object. So now your code has to really remove that matching object. Removing would mean to update both links accordingly.
Do these things on paper! Draw a double linked list with nodes and the links between them. Then ask yourself what removing a node that has one or two links coming in (and potentially going out) actually means. You will have to change the links from the previous node and the one following the node that is to removed!
I'm trying to implement Queues in JAVA. I'm a beginner. I dont understand why this isn't working. Push() works fine but pop() isn't working. Can someone please point out where im going wrong?
pop():
public void pop()
{
for(int i=0;i<length;i++)
{
while(i<(length-1))
{
arr[i]=arr[i+1];
}
}
}
push():
public void push(int x)
{
push:for(int i=0;i<length;i++)
{
if(arr[i]==null)
{
arr[i]=x;
break push;
}
}
}
show():
public void show()
{
int c=0;
for(int i=0;i<length;i++)
//if(arr[i]!=null)
{
System.out.println(arr[i]);
c++;
}
System.out.println("Current Capacity "+c+"/"+length);
}
main()
public static void main(String...i)
{
System.out.println("Stack Implementation");
Queue stack = new Queue();
System.out.println("Push");
stack.push(1);
stack.push(2);
stack.push(3);
stack.push(4);
stack.push(5);
stack.show();
System.out.println("Pop");
stack.pop();
stack.show();
}
The output doesn't show any data after pop() is run.
You don't increment i in pop() so the while loop will run endlessly.
In push you are using a for loop which increments i: :for(int i=0;i<length;i++ /*here*/)
You also don't initialize i in pop() so it will probably have the value of the last increment in push(). That value will be the index of the next empty element (if there's one left) and thus that's wrong anyways. However, you want to pop from the front, so you'd need to start at i = 0 - in that case another for loop would work as well, i.e. you just copy the value of element at i+1 to the index i and set the last element to null (for more efficiency you could stop once i+1 has a null element).
Edit: now that you've posted more code for pop() the situation is a little different. You are already using a for loop in pop() but another loop inside that. I assume you want to do if(i<(length-1)) instead of while(i<(length-1)) - but in that case you'd still have to handle the last element, i.e. once the queue was full you'd need to set the last element to null when you pop one and move the rest.
When you pushed the element you need to return from the method:
public void push(int x) {
for (int i = 0; i < length; i++) {
if (arr[i] == null) {
arr[i] = x;
return; // Exit from push when you added the element in the right position
}
}
}
Note that this code is not optimized. Push an element requires O(n), so can waste a lot of time for big queues, but this is the closest solution to your code. Anyway a simple optimization can be done introducing a variable holding the last used index. So you can use that variable to push and pop an element in O(1).
for(int i=1;i<list.size();i++)
{
if (x.nextNode!=null)
{
if (x.data=='C')
{
x.data='G';
} else if (x.data=='G') {
x.data='C';
} else if (x.data=='A') {
x.data='T';
} else if (x.data=='T') {
x.data='A';
}
}
x=x.nextNode;
}
I have created a list with char Nodes which only contains A G C T and a loop which checks every Node of the list and changes it. G should be changed to C, C should be changed to G, A should be changed to T, T should be changed to A.
My problem is that every Node.char item is changed except for the last Node of the list. How I should edit this code to also change the last Node?
You are starting from 1 so apparently skipping one node. so to traverse whole LinkList (seems like) you should to start from 0
for(int i=0;i<list.size();i++)
// ^
update : when if (x.nextNode!=null) is false mean you have reached the last node.
if (lastNode.nextNode!=null) will be false so no execution will take place ,so to execute the last node , use
if (x!=null)
When given an array of integers, I'm trying to change each element with the product of the integers before it.
For example, int[] array = {2,2,3,4}; is now: {2, 4, 12, 48};
I added each element to a LinkedList, and I'm trying to do this recursively.
This is what I have:
Node curr = list.getFirst();
product(curr);
public static void product(Node curr)
{
if(curr == null)
{
return;
}
else
{
int data = curr.getData() * curr.getNext().getData();
Node newNode = new Node(data);
curr.setNext(newNode);
// product(curr);
}
}
The first product works: {2,4}, but when I try to put in the recursion, I get a stackoverflow. Any suggestions??
Edit: So the reason that I'm either getting a stackoverflow or null pointer exception is because I'm updating the list, and then trying to get the next integer(but since there's only two elements in the list, there isn't a getNext()). I'm not sure how to fix this.
It looks like you were getting a bit tied up in the recursion. I modified your method to accept a Node along with the product from the previous iteration. At each step of the iteration I update the value in the already-existing List, so there is no need for using the new operator.
public static void product(Node curr, int value) {
if (curr == null) {
return;
}
else {
int data = value * curr.getData(); // compute current product
curr.setData(data); // update Node
product(curr.getNext(), data); // make recursive call
}
}
There are actually two issues with the code.
The recursion never ends, i.e. it is not actually moving to a smaller "subproblem" as the recursion is calling the same node again
and again.
After creating a new node and modifying the next we also need to connect the node "after" the next node otherwise the link will be
lost. Please check the below method which addresses both the issues.
Although I didn't do an excessive testing it is working for simple dataset.
Original List:
2->4->5->6->8->null
Multiplied List:
2->8->40->240->1920->null
public void product(Node curr) {
if (curr.getNext() == null) {
return;
} else {
int data = curr.getData() * curr.getNext().getData();
Node newNode = new Node();
newNode.setData(data);
Node nodeAfterNextNode = curr.getNext().getNext();
newNode.setNext(nodeAfterNextNode);
curr.setNext(newNode);
product(newNode);
}
}
It is because you call recursive method on the current node, so it is actually never move forward in the LinkedList. You can simply update the next node's data and call the recursive method on it. See the code below:
Node curr = list.getFirst();
product(curr);
public static void product(Node curr)
{
Node next = curr.getNext();
if(next == null)
{
return;
}
else
{
int data = curr.getData() * next.getData();
next.setData(data);
product(next);
}
}
I have created an arrayList treat to show 5 instances of a treatment room, I have also created a linkedList inTreatment for the treatment room to pass 5 patient objects into from queue, however when I pass multiple objects to the linkedList they constantly replace the first element added instead of moving to the next element available. I believe the problem lies with the inTreatment.add line but i'm not sure how to reference the next available index. All suggestions are more than welcome.
Below is my code for creating the array and adding to the inTreatment linkedList.
Creating treatment rooms array
public static void createTreatmentRooms() {
for (int i = 0; i < treat.length; i++) {
treat[i] = new TreatmentRoom();
treat[i].setAvailable(true);
}
}
Add to treatment rooms method
for (int i = 0; i < TreatmentRoom.treat.length; i++) {
if ((TreatmentRoom.treat[i].isAvailable())
&& (Queue.queue.size() != 0)
&& (Queue.queue.getFirst().getTriage() != Status.NOT_ASSESSED)) {
// add patient to inTreatment list for future sorting...
inTreatment.add(queue.getFirst());
System.out.println("taken to treatment queue");
// remove patient from front of queue
for (Patient p : queue) {
System.out.println(p.getFirstName());
}
queue.poll();
System.out.println("second queue");
for (Patient p : queue) {
System.out.println(p.getFirstName());
}
System.out.println("removed from queue");
// if free, add patient to treatment room
TreatmentRoom.treat[i].setPatient(inTreatment.getFirst());
System.out.println("sent to treatment room"
+ TreatmentRoom.treat[i]);
// System.out.println("patient added" +
// queue.get(i).getFirstName());
// set treatment room to unavailable
TreatmentRoom.treat[i].setAvailable(false);
System.out.println("treatment room busy");
} else {
System.out.println("Treatment room is not available");
}
}
}
The problem might come from here:
queue.remove(i);
You're removing the element at index i, but that i is in the range of the rooms, and has nothing to do with the queue, does it?
You might want to remove the first element instead.
Side note: there should be a poll() method that allows you to peek and remove the first element of your queue in one call by the way, but I'm unusure what type of queue you're using here, it does not look like java.util.Queue.