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.
Related
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");
So my problem is that I wanna delete a node based on a value inputted by the user, in my program I can already, add, search, and delete the node in the last position, but so far I haven't been able to delete a specific value inputted by the user, if for example I have 1,2,3,4 elements in my list I wanna be able to point at, say 2, and delete it. here are my functions, the last one is the uncompleted one:
//searches node
public void searchNode(int input){
Node temp = first;
boolean found = false;
if(!isEmpty()){
for(int i = 0 ; i<size ; i ++){
if(temp.value == input){
System.out.println(input + " found in the position: " + (i+1));
found = true;
break;
}
temp = temp.rightNode;
}
if(!found)
System.out.println("value not found.");
}
}
//deletes last node
public void deleteLastNode(){
if(isEmpty()){
System.out.println("There are no nodes to delete.");
}
if(last == first){
first = null;
last = null;
} else {
Node current = first;
while(current.rightNode != last){
current = current.rightNode;
}
current.rightNode = null;
last = current;
}
size --;
}
//delete element, input by user.
public void deleteInputByUser(int input) {
Node temp = first;
boolean found = false;
if(isEmpty()){
System.out.println("There are no nodes to delete.");
} else {
}
size--;
}
//Node class
public class Node{
int value;
Node rigthNode;
public Node(int value){
this.value = value;
}
}
Deletion of a node in a Linked List by value is not so bad. This pseudocode should help you get started:
deleteNodeByValue(int val) {
if (head.val = val) {
head = head.next
return
}
current = head
while (current.next != null) {
if (current.next.val = val) {
current.next = current.next.next
return
}
current = current.next
}
}
Find the nodeToDelete and his previousNode, then
previousNode.rightNode = nodeToDelete.rightNode;
you can do it this way. The following code will remove the element once the index is given.
public boolean deleteAt(int index){
Node current=first;
if(index==0){
first=current.rightNode;
return true;
}
currentIndex=0;
previousNode=first;
current=first.rightNode;
while(current!=null){
if(currentIndex==index){
previousNode.rightNode=current.rightNode;
return true;
}
currentIndex++;
previousNode=current;
current=current.rightNode;
}
return false;
}
You could try something like that.
public void deleteNodeByValue(int input) {
Node currNode = first;
boolean found = false;
Node prevNode = first;
if (!isEmpty()) {
for (int i = 0; i < size; i++) {
if (currNode.value == input) {
///////DELETE START
if (currNode == first) {
first = currNode.rightNode;
} else {
prevNode.rightNode = currNode.rightNode;
if (currNode == last)
last = prevNode;
}
////DELETE END
found = true;
size--;
break;
}
prevNode = currNode;
currNode = currNode.rightNode;
}
if (!found)
System.out.println("value not found.");
}
}
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.
I am doing some exercises on practice-it website. And there is a problem that I don't understand why I didn't pass
Write a method deleteBack that deletes the last value (the value at the back of the list) and returns the deleted value. If the list is empty, your method should throw a NoSuchElementException.
Assume that you are adding this method to the LinkedIntList class as defined below:
// A LinkedIntList object can be used to store a list of integers.
public class LinkedIntList {
private ListNode front; // node holding first value in list (null if empty)
private String name = "front"; // string to print for front of list
// Constructs an empty list.
public LinkedIntList() {
front = null;
}
// Constructs a list containing the given elements.
// For quick initialization via Practice-It test cases.
public LinkedIntList(int... elements) {
this("front", elements);
}
public LinkedIntList(String name, int... elements) {
this.name = name;
if (elements.length > 0) {
front = new ListNode(elements[0]);
ListNode current = front;
for (int i = 1; i < elements.length; i++) {
current.next = new ListNode(elements[i]);
current = current.next;
}
}
}
// Constructs a list containing the given front node.
// For quick initialization via Practice-It ListNode test cases.
private LinkedIntList(String name, ListNode front) {
this.name = name;
this.front = front;
}
// Appends the given value to the end of the list.
public void add(int value) {
if (front == null) {
front = new ListNode(value, front);
} else {
ListNode current = front;
while (current.next != null) {
current = current.next;
}
current.next = new ListNode(value);
}
}
// Inserts the given value at the given index in the list.
// Precondition: 0 <= index <= size
public void add(int index, int value) {
if (index == 0) {
front = new ListNode(value, front);
} else {
ListNode current = front;
for (int i = 0; i < index - 1; i++) {
current = current.next;
}
current.next = new ListNode(value, current.next);
}
}
public boolean equals(Object o) {
if (o instanceof LinkedIntList) {
LinkedIntList other = (LinkedIntList) o;
return toString().equals(other.toString()); // hackish
} else {
return false;
}
}
// Returns the integer at the given index in the list.
// Precondition: 0 <= index < size
public int get(int index) {
ListNode current = front;
for (int i = 0; i < index; i++) {
current = current.next;
}
return current.data;
}
// Removes the value at the given index from the list.
// Precondition: 0 <= index < size
public void remove(int index) {
if (index == 0) {
front = front.next;
} else {
ListNode current = front;
for (int i = 0; i < index - 1; i++) {
current = current.next;
}
current.next = current.next.next;
}
}
// Returns the number of elements in the list.
public int size() {
int count = 0;
ListNode current = front;
while (current != null) {
count++;
current = current.next;
}
return count;
}
// Returns a text representation of the list, giving
// indications as to the nodes and link structure of the list.
// Detects student bugs where the student has inserted a cycle
// into the list.
public String toFormattedString() {
ListNode.clearCycleData();
String result = this.name;
ListNode current = front;
boolean cycle = false;
while (current != null) {
result += " -> [" + current.data + "]";
if (current.cycle) {
result += " (cycle!)";
cycle = true;
break;
}
current = current.__gotoNext();
}
if (!cycle) {
result += " /";
}
return result;
}
// Returns a text representation of the list.
public String toString() {
return toFormattedString();
}
// ListNode is a class for storing a single node of a linked list. This
// node class is for a list of integer values.
// Most of the icky code is related to the task of figuring out
// if the student has accidentally created a cycle by pointing a later part of the list back to an earlier part.
public static class ListNode {
private static final List<ListNode> ALL_NODES = new ArrayList<ListNode>();
public static void clearCycleData() {
for (ListNode node : ALL_NODES) {
node.visited = false;
node.cycle = false;
}
}
public int data; // data stored in this node
public ListNode next; // link to next node in the list
public boolean visited; // has this node been seen yet?
public boolean cycle; // is there a cycle at this node?
// post: constructs a node with data 0 and null link
public ListNode() {
this(0, null);
}
// post: constructs a node with given data and null link
public ListNode(int data) {
this(data, null);
}
// post: constructs a node with given data and given link
public ListNode(int data, ListNode next) {
ALL_NODES.add(this);
this.data = data;
this.next = next;
this.visited = false;
this.cycle = false;
}
public ListNode __gotoNext() {
return __gotoNext(true);
}
public ListNode __gotoNext(boolean checkForCycle) {
if (checkForCycle) {
visited = true;
if (next != null) {
if (next.visited) {
// throw new IllegalStateException("cycle detected in list");
next.cycle = true;
}
next.visited = true;
}
}
return next;
}
}
// YOUR CODE GOES HERE
}
My work so far is this:
public int deleteBack(){
if(front==null){
throw new NoSuchElementException();
}else{
ListNode current = front;
while(current!=null){
current = current.next;
}
int i = current.data;
current = null;
return i;
}
}
Don't you want to iterate until the current.next is != null?
What you have now passes the entire list, and your last statements do nothing, since current is null already.
Think about the logic you have here
while(current!=null){
current = current.next;
}
When that loop exits, current == null, and then you try to access current's data. Does this point you in the right direction?
// This is the quick and dirty
//By Shewan
public int deleteBack(){
if(size()== 0){ throw new NoSuchElementException(); }
if(front==null){ throw new NoSuchElementException();
}else{
if(front.next == null){
int i = front.data;
front = null;
return i;
}
ListNode current = front.next;
ListNode prev= front;
while(current.next!=null){
prev = current;
current = current.next;
}
int i = current.data;
prev.next = null;
return i;
}
}
I created a linked list using nodes that prints out a list(string) of names. I'm trying to write a sort method that prints out the names in alphabetical order. If this was integers it would be easy but I have no idea how to go about doing this. Any help or tips are appreciated.
-I cannot use the builtin collections.sort(). I need to make my own method.
SortMethod: (this is what I used when I was printing a list of numbers out but now its strings so I know I can't use the > operator. I just don't know how to replace it.
public void Sort( BigNode front)
{
BigNode first,second,temp;
first= front;
while(first!=null) {
second = first.next;
while(second!=null) {
if(first.dataitems < second.dataitems)
{
temp = new BigNode();
temp.dataitems =first.dataitems;
first.dataitems = second.dataitems;
second.dataitems = temp.dataitems;
}
second=second.next;
}
Heres the rest of program(I dont think its needed but just in case)
import java.util.*;
public class BigNode {
public String dataitems;
public BigNode next;
BigNode front ;
BigNode current;
String a = "1", b = "2", c = "3", d = "4";
String[] listlength;
public void initList(){
front = null;
}
public BigNode makeNode(String number){
BigNode newNode;
newNode = new BigNode();
newNode.dataitems = number;
newNode.next = null;
return newNode;
}
public boolean isListEmpty(BigNode front){
boolean balance;
if (front == null){
balance = true;
}
else {
balance = false;
}
return balance;
}
public BigNode findTail(BigNode front) {
BigNode 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(BigNode front ,String name){
BigNode tail;
if(isListEmpty(front)){
this.front = makeNode(name);
}
else {
tail = findTail(front);
tail.next = makeNode(name);
}
}
public void addAfter(BigNode n, String dataItem2) { // n might need to be front
BigNode temp, newNode;
temp = n.next;
newNode = makeNode(dataItem2);
n.next = newNode;
newNode.next = temp;
}
public void findNode(BigNode front, String value) {
boolean found , searching;
BigNode curr;
curr = front;
found = false;
searching = true;
while ((!found) && (searching)) {
if (curr == null) {
searching = false;
}
else if (curr.dataitems == value) { // Not sure if dataitems should be there (.data in notes)
found = true;
}
else {
curr = curr.next;
}
}
System.out.println(curr.dataitems);
}
public void deleteNode(BigNode front, String value) {
BigNode curr, previous = null; boolean found;
if (!isListEmpty(front)){
curr = front;
found = false;
while ((curr.next != null) && (!found)) {
if(curr.dataitems.equals(value)) {
found = true;
}
else {
previous = curr;
curr = curr.next;
}
}
if (!found) {
if(curr.dataitems.equals(value)) {
found = true;
}
}
if (found) {
if (curr.dataitems.equals(front.dataitems)){ // front.dataitems may be wrong .dataitems
front = curr.next;
} else {
previous.next = curr.next;
}
} else {
System.out.println("Node not found!");
//curr.next = null; // Not sure If this is needed
}
}
showList(front);
}
public void printNodes(String[] len){
listlength = len;
int j;
for (j = 0; j < len.length; j++){
addNode(front, len[j]);
} showList(front);
}
public void showList(BigNode front){
current = front;
while ( current.next != null){
System.out.print(current.dataitems + ", ");
current = current.next;
}
System.out.println(current.dataitems);
MenuOptions();
}
public void MenuOptions() {
Scanner in = new Scanner(System.in);
System.out.println("Choose an Option Below:");
System.out.println(a + "(Display Length of List)" + ", " + b + "(Delete a person)" + ", " + c + ("(Exit)"));
String pick = in.nextLine();
if (pick.equals(b)) {
System.out.println("Who would you like to delete?");
String delete = in.nextLine();
deleteNode(front, delete);
}
if (pick.equals(a)) {
System.out.println("Length of List = " + listlength.length);
MenuOptions();
}
if (pick.equals(c)) {
}
}
public static void main(String[] args) {
String[] names = {"Billy Joe", "Sally Mae", "Joe Blow", "Tasha Blue", "Malcom Floyd"}; // Trying to print theses names..Possibly in alphabetical order
BigNode x = new BigNode();
x.printNodes(names);
}
}
first.dataitems.compareTo(second.dataitems)<0
or if you have a comparator
comp.compare(first.dataitems, second.dataitems)<0