Josephus Algorithm Glitch using a circular linked list - java

I have to write a program that gives the output of the last man standing, according to the Josephus problem, utilizing a circular list. It seems to work the majority of the time, However, when I enter a series 7(people) 1(starting position), 3(kill count). It gets thrown off half way through the killing.(approximately when the list is 2357) I have looked through the code several times following the numbers and cannot figure out why in this iteration it kills 3 instead of 5.
import java.util.Scanner;
class Link{
public int itemData;
public Link next;
public Link(int itemNumber){
//initialize's data
itemData = itemNumber;
}
public void displayLink(){
System.out.print("{" + itemData + "}");
}
}
class LinkList{
private Link first; //first link
private Link last;
private Link current;
public LinkList getCurrent;
public LinkList(){
first = null;
last = null;
current = null;
}
public boolean isEmpty(){
return(first == null);
}
public void setCurrent(){
current = current.next;
}
public Link getCurrent(){
return current;
}
public void fillList(int listSize){
for(int i=1; i < listSize + 1; i++){
Link newLink = new Link(i);
if(isEmpty()){
first = newLink;
current = first;
}
else{
current.next = newLink;
newLink.next = first;
last = newLink;
setCurrent();
}
}
}
public Link find(int holder, int listSize){
Link marker = first;
for(int i = 0; i < listSize; i++){
if(marker.itemData == holder){
break;
}
else{
marker = marker.next;
}
}
return marker;
}
public void deleteEvery(int holder, int pass, int listSize){
while(listSize!= 1){
Link current = find(holder, listSize);
Link previous = first;
for(int i = 1; i < pass; i++){
current = current.next;
}
previous = current;
current = current.next;
if(current == first){
first = first.next;
}
else{
previous.next = current.next;
}
holder = current.next.itemData;
displayList(--listSize);
}
}
public void displayList(int listSize){
System.out.print("List:");
Link current = first;
for(int i = 1; i < listSize+1; i++){
current.displayLink();
current = current.next;
}
System.out.print("");
}
}
class Josephus{
public static void main(String[] args){
LinkList people = new LinkList();
Scanner input = new Scanner(System.in);
System.out.print("Please enter 3 integers (size, holder, passing).");
int listSize = input.nextInt();
int holder = input.nextInt();
int pass = input.nextInt();
people.fillList(listSize);
people.displayList(listSize);
people.deleteEvery(holder, pass, listSize);
}
}

Nevermind I figured it out in the deleteEvery() function my if statement also needed to follow through with the deletion of the position, it was changing the first element and the continuing to the next iteration.

Related

How to get length and isEmpty methods as a return value to get method used for my Circular Linked List?

There is a problem I came across when I have seen two methods never used in the Linked List:
New Update!!!
public class CircularLinkedList {
private ListNode last;
private int length;
private static class ListNode {
private ListNode next;
private final int data;
public ListNode(int data) {
this.data = data;
}
}
public static void main(String[] args) {
CircularLinkedList cll = new CircularLinkedList();
CircularLinkedList insertBeg = new CircularLinkedList();
CircularLinkedList insertEnd = new CircularLinkedList();
System.out.println("creating a traverse list");
cll.createCircularLinkedList();
cll.display();
System.out.println("Insert Starting Node");
insertBeg.insertFirst(10);
insertBeg.insertFirst(15);
insertBeg.insertFirst(20);
insertBeg.insertFirst(25);
insertBeg.display();
insertEnd.insertLast(25);
insertEnd.insertLast(20);
insertEnd.insertLast(15);
insertEnd.insertLast(10);
// I just need to print out the isEmpty amd length
System.out.println(insertEnd.isEmpty());
System.out.println(insertEnd.length());
insertEnd.display();
}
public CircularLinkedList () {
last = null;
length = 0;
}
public void display() {
if(last == null) {
return;
}
ListNode first = last.next;
while(first != last) {
System.out.print(first.data + " --> ");
first = first.next;
}
System.out.println(first.data);
}
public void insertFirst(int data) {
ListNode temp = new ListNode(data);
if (last == null) {
last = temp;
} else {
temp.next = last.next;
}
last.next = temp;
length++;
}
public void insertLast(int data) {
ListNode temp = new ListNode(data);
if (last == null) {
last = temp;
last.next = temp;
} else {
temp.next = last.next;
last.next = temp;
last = temp;
}
length++;
}
public int length () {
ListNode temp = last.next;
int count = length;
while (temp != last) {
count++;
temp = temp.next;
}
return count;
}
public boolean isEmpty(){
return length == 0;
}
public void createCircularLinkedList() {
ListNode first = new ListNode(1);
ListNode second = new ListNode(5);
ListNode third = new ListNode(10);
ListNode fourth = new ListNode(15);
first.next = second;
second.next = third;
third.next = fourth;
fourth.next = first;
last = fourth;
}
}
I try to fix this problem for my Circular Linked List by trying to void the method. However, I want to test and see if I can get the method working by printing out the value for the length and isEmpty. Is there a way to work around this issue on IntelliJ?
Return value of the method is never used for both length and isEmpty
It's just a warning, that some other code is calling the method but ignoring the result.
The solution is to fix that other code.

Adding to the tail of a linked list

I have an append method for my linked list where I want to add to the tail, however when a new node is added to the list, headNode and tailNode both become the newly inserted node. How do I keep headNode to stay as the first node that was entered into the list and not have it become the same thing as tailNode.
public static void append()
{
for(int x = 0; x < gradeArray.length; x++)
{
if(gradeArray[x] < 70)
{
StudentNode newNode = new StudentNode(nameArray[x], gradeArray[x], null);
if(headNode == null)
{
headNode = newNode;
}
else
{
tailNode.nextNode = newNode;
}
tailNode = newNode;
}
}
}
I am not sure what mistake are you doing but see below this code is working perfectly fine.
public class Grades {
public static String[] nameArray = new String[50];
public static int[] gradeArray = new int[50];
public static StudentNode headNode;
public static StudentNode tailNode;
public static void append() {
for (int x = 0; x < gradeArray.length; x++) {
if (gradeArray[x] < 70) {
String name = nameArray[x];
int grade = gradeArray[x];
StudentNode newNode = new StudentNode(name, grade, null);
if (headNode == null) {
headNode = newNode;
} else {
tailNode.nextNode = newNode;
}
tailNode = newNode;
}
}
}
public static void main(String[] args) throws java.lang.Exception {
for (int i = 0; i < 50; i++) {
nameArray[i] = "name-" + i;
gradeArray[i] = i;
}
append();
for(int i=0; i<50; i++) {
nameArray[i] = "name-" + (i + 50);
gradeArray[i] = i + 50;
}
append();
System.out.println(headNode.toString());
System.out.println(tailNode.toString());
}
}
class StudentNode {
public int grade;
public String name;
public StudentNode nextNode;
public StudentNode(String n, int g, StudentNode sn) {
name = n;
grade = g;
nextNode = sn;
}
public String toString() {
return name + ", " + grade;
}
}
Even if you change grade and name arrays and run append again it still keeps the head correct.
Ideone link for running code
Why did you append this statement ? tailNode = newNode;
Imagine, thread goes through by if(headNode == null) he assign newNode adress to headNode . After that, tailNode = newNode; is executed and tail pointing to newNode.
Finally, tailNode and headNode point to the same object : newNode.
I think you have to delete this statement tailNode = newNode;

LinkedList isn't taking input

I seem to be having some problems with inserting values into a linked list. I am trying to create a program for the Josephus problem and I am suppose to take 3 numbers from the user. The first number is how many "people" there are, say its 4 you would have a list of 1,2,3,4. This is where I am stuck. Every time I enter in the 3 ints my program returns saying the List is empty and I can't figure out why. If anyone could help explain it would be greatly appreciated, thanks!
Main
public static void main(String[] args)
{
Scanner input = new Scanner(System.in);
long[] numbers = new long[3];
LinkedList circle = new LinkedList();
System.out.println("Please enter 3 numbers");
for (int i = 0; i < 3; i++)
{
numbers[i] = input.nextLong();
}
for (int i = 0; i < numbers[0]; i++)
{
circle.insertLink();
circle.move();
}
circle.getCurrent();
}
Link
class Link
{
public long dData;
public Link next;
public Link(long dd)
{
dData = dd;
}
public Link(int d, Link n)
{
this(d);
next = n;
}
public void displayLink()
{
System.out.print(dData + " ");
}
}
Linked List
class LinkedList
{
private Link current;
private int id;
public LinkedList()
{
current = null;
id = 1;
}
public void move()
{
current = current.next;
}
public boolean isEmpty()
{
if(current == null)
System.out.println("The List is empty");
return current == null;
}
public Link getCurrent()
{
return current;
}
public void setCurrent(int id)
{
while(current.dData != id)
move();
}
public Link getNext()
{
return current.next;
}
public void insertLink()
{
if(!isEmpty())
{
Link newlink = new Link(id++, current.next);
current.next = newlink;
}
else
{
Link newlink = new Link(id++);
newlink.next = newlink;
current = newlink;
}
}
public Link deleteLink()
{
Link temp = current.next;
if(current != current.next)
current.next = current.next.next;
else
current = null;
return temp;
}
}
when first time you call insertLink() methos you always will get The List is empty print. because at initialization the current variable of your linked list class is null. just remove System.out.println("The List is empty"); from your code.
public boolean isEmpty()
{
return current == null;
}
override toString() method to see your list
You are taking three inputs from user and iterating with first element of numbers array, i think it should be
for (int i = 0; i < numbers.length; i++)
{
circle.insertLink();
circle.move();
}
And at the first time when you insert the link, isEmpty() method checks your current variable is null or not if it is then it print the "The list is empty". so just remove that line.
System.out.println("The List is empty");

How to display a string in linked list using nodes

I created a basic node linked list that displays the size of the list in number (ie: 0 - 9 )
Now I'm trying to alter what i have to display a list of names. I'm confused on what I need to change and what is going to be different. The names are going to be in string format. Eventually I'm going to read in a list of names from a txt file. For now I'm using just 3 names and test data.
import java.util.*;
public class Node {
public int dataitems;
public Node next;
Node front;
public void initList(){
front = null;
}
public Node makeNode(int number){
Node newNode;
newNode = new Node();
newNode.dataitems = number;
newNode.next = null;
return newNode;
}
public boolean isListEmpty(Node front){
boolean balance;
if (front == null){
balance = true;
}
else {
balance = false;
}
return balance;
}
public Node findTail(Node front) {
Node current;
current = front;
while(current.next != null){
//System.out.print(current.dataitems);
current = current.next;
} //System.out.println(current.dataitems);
return current;
}
public void addNode(Node front ,int number){
Node tail;
if(isListEmpty(front)){
this.front = makeNode(number);
}
else {
tail = findTail(front);
tail.next = makeNode(number);
}
}
public void printNodes(int len){
int j;
for (j = 0; j < len; j++){
addNode(front, j);
} showList(front);
}
public void showList(Node front){
Node current;
current = front;
while ( current.next != null){
System.out.print(current.dataitems + " ");
current = current.next;
}
System.out.println(current.dataitems);
}
public static void main(String[] args) {
String[] names = {"Billy Joe", "Sally Hill", "Mike Tolly"}; // Trying to print theses names..Possibly in alphabetical order
Node x = new Node();
Scanner in = new Scanner(System.in);
System.out.println("What size list? Enter Number: ");
int number = in.nextInt();
x.printNodes(number);
}
}
several things must be changed in my opinion
public void printNodes(String[] nameList){
int j;
for (j = 0; j < nameList.length; j++){
addNode(front, nameList[j]);
} showList(front);
}
you have to pass the array containing the names
x.printNodes(names);
also change:
public void addNode(Node front ,String name){
Node tail;
if(isListEmpty(front)){
this.front = makeNode(name);
}
else {
tail = findTail(front);
tail.next = makeNode(name);
}
}
and :
public Node makeNode(String name){
Node newNode;
newNode = new Node();
newNode.dataitems = name;
newNode.next = null;
return newNode;
}
and don't forget to change the type of dateitem into string :
import java.util.*;
public class Node {
public String dataitems;

Circular Single Linked List

I have been trying to make a Circular Linked List in Java. I believe that I am inserting properly, but I cannot get my delete or display to work properly. This is my code.
public class Link
{
public int data;
public Link next;
public Link(int d)
{
data = d; //store data
next = null; //set next Link to newLink
}
}
public class IntListCircularCount
{
private Link first;//this always points to the first link.
private Link current=null;
private int count =0;
public IntListCircularCount()
{
first = null;
}
public boolean isEmpty()
{
return (first==null);
}
public Link getFirst()
{
return first;
}
public void insert(int n)
{
if(count == 0)
{
Link newLink = new Link(n);
first=newLink;
count++;
current = first;
}
else if(count>0)
{
Link newLink = new Link(n);
first.next = newLink;
newLink.next = first;
count++;
current = first.next;
}
}
public void display(int width)
{
if(isEmpty())
System.out.printf("%" + width + "s", "--");
else if(count ==1)
System.out.printf("%" + width + "d",first.data);
else if(!isEmpty() && first.next !=first)
{
while (first !=current)
{
System.out.printf("%" + width + "d", current.data);
current = current.next;
}
}
}
public void delete()
{
if(count==0)
{
first=null;
}
else if(count==1)
{
first = first.next;
}
else if(count>1)
{
current.next=first.next;
first = first.next;
count--;
}
}
}
public class IntListUser
{
public static void main (String[] args)
{
final int n =5;//there will be n Links
final int w=5; //field width for display
IntListCircularCount list = new IntListCircularCount();
for(int i=1; i<=n; i++)
{
list.display(w);
list.insert(10*i);
}
list.display(w);
System.out.println(" -------------end of inserting ----------------");
list.delete();
list.display(w);
list.delete();
list.display(w);
list.delete();
list.display(w);
list.delete();
list.display(w);
list.delete();
list.display(w);
}
}
I usually do some napking sketches before writing any code. They save me a lot of trouble.
Ok, but for your question:
Your insert is only inserting after the first element. If your current points to the end, then when you insert a new element it should be linked to current, not to first. And current should always point to first (to make the list circular), even with just one element.
public void insert(int n)
{
if(count == 0)
{
Link newLink = new Link(n);
first=newLink;
count++;
current = first;
current.next = first;
}
else
{
Link newLink = new Link(n);
current.next = newLink;
newLink.next = first;
count++;
current = current.next;
}
}
Also, your display needs to display from first to current, but you shouldn't lost first and current.
public void display(int width)
{
Link display_me = first;
if(isEmpty())
System.out.printf("%" + width + "s", "--");
else
{
Link display_me = first;
do {
System.out.printf("%" + width + "d", current.data);
display_me= display_me.next;
} while (first != display_me);
}
}
As for the delete, I don't know if you want to delete the first or the current.
Hope this helps.

Categories