Linked Lists Java SearchAll and Boolean Remove - java

package phonelist;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.PrintWriter;
import java.util.Scanner;
public class LinkedList {
private Node head;
private int size = 0;
public LinkedList() {
load(); // Load a contacts from a file
}
public void add(Contact contact) {
Node newNode = new Node(contact, null);
size++;
if (head == null) {
newNode.setNextNode(head);
head = newNode;
} else {
Node c = head;
while ((c.getNextNode() != null)) {
c = c.getNextNode();
}
newNode.setNextNode(c.getNextNode());
c.setNextNode(newNode);
}
}
public boolean remove(String name) {
return true;
}
public Contact search(String name) {
return null;
}
public String getAll() {
return null;
}
/** Save contacts to a text file **/
public void save() {
if (size == 0) {
return;
}
Scanner in = new Scanner(System. in );
try {
PrintWriter outFile = new PrintWriter("contacts.txt");
if (head != null) {
Node currentNode = head;
do {
Contact contact = currentNode.getContact();
outFile.println(contact.getName() + "," + contact.getNumber());
currentNode = currentNode.getNextNode();
} while (currentNode != null);
}
outFile.close();
} catch (FileNotFoundException e) {
System.out.println("Cannot find that file");
}
}
/** Load contacts from a text file **/
public void load() {
try {
FileReader file = new FileReader("contacts.txt");
Scanner inFile = new Scanner(file);
while (inFile.hasNext()) {
String contact = inFile.nextLine();
int index = contact.indexOf(',');
String name = contact.substring(0, index);
String number = contact.substring(index + 1, contact.length());
add(new Contact(name, number));
}
inFile.close();
} catch (FileNotFoundException e) {
System.out.println("Cannot find that file");
}
}
}
I cannot figure out how to remove a specific node, nor how to search properly. It keeps giving me a node location not what i have added. I have spent the last 5 hours working on this and I am unable to finish the rest without at least being able to search. If someone could give me a few pointers on here to begin or give me examples, it would be much appreciated.
Here is a way I have tried the remove method.
public boolean remove(String name) {
if (name.equals(name)) {
remove(name);
return true;
} else {
return false;}}
Node Class
package phonelist;
public class Node {
private Contact contact;
private Node next;
public Node(Contact contact, Node next) {
// Do something here
this.contact = contact;
this.next = next;
}
public void setNextNode(Node next) {
// Do something here
this.next = next;
}
public Node getNextNode() {
// Replace return null with something useful
return next;
}
public Contact getContact() {
// Replace return null with something useful
return contact;
}
}
Contact Class
package phonelist;
public class Contact {
private String name;
private String number;
public Contact(String name, String number) {
this.name = name;
this.number = number;
}
public String getName() {
return name;
}
public String getNumber() {
return number;
}
}
In the LinkeList class Ive created a toString() method but i am currently only printing out a node location in memory not the actual data. Ideas?
#Override
public String toString() {
return "LinkedList{" + "head=" + head + ", size=" + size + '}';
}
public String getAll() {
System.out.println(toString());
return null;

The algorithms "in words"
Search
As for searching, you can just write a while loop in your search(String name) method that starts at the head and iterates through the list the same way you've done in your add function (where you've done:
Node c = head;
while ((c.getNextNode() != null)) {
c = c.getNextNode();
}
). But instead of stopping once the current contact being pointed to has null as it's next contact, stop when the current contact has the name you're searching for. Be careful to also stop once you have reached the end of the list in the case where you don't find the contact (so basically just add something to the existing loop condition).
Remove
As for removing an element, it's the same as searching, but with an additional step. It will be like the loop to search, but this time you'll want to stop when the next contact is the one you're looking for. Then set the 'next' reference of the current node to the node after the contact you want to remove.
I could code this up with an example, but I'll leave that to you so you will be sure to understand it :-) Good luck!

Please see explanation in Javadoc . Let me know if you have any question.
Search Method
/**
*
* #param name this the name of the contact to search for. If list has two
* contacts with same name the first one found will be used
* #return Contact
*/
public Contact search(String name) {
Node currentNode = head;
Contact contact = null;
for (int i = 0; i < size; i++) {
if (currentNode.getContact().getName().equalsIgnoreCase(name)) {
contact = currentNode.getContact();
break;
}
currentNode = currentNode.getNextNode();
}
return contact;
}
Remove Method and helper method searchNodeOneBeforeTheTargetNode
/**
*
* #param name of the contact to remove
* #return True for successful removal
*/
public boolean remove(String name) {
Node node = searchNodeOneBeforeTheTargetNode(name);
boolean removalSuccessfull = false;
if (node != null) {
node.setNextNode(node.getNextNode().getNextNode());
removalSuccessfull = true;
}
return removalSuccessfull;
}
/**
* Pay attention to this method. Since your linked list a Singly linked
* list, meaning every node only knows about the next node not the previous.
* This method return the previous node to of the target node. All that is
* needed to be done here is that we get the next node of target and
* attached that to the previous node of the target e.d if we want to remove B from below
*
* A->B->C A know B but B does not know about A it know about C . To delete B we connect A->C and B is deleted
*
*
*
* #param name
* #return
*/
private Node searchNodeOneBeforeTheTargetNode(String name) {
Node currentNode = head;
Node nodeOneBeforeTheTargetNode = null;
for (int i = 0; i < size; i++) {
if (currentNode.getContact().getName().equalsIgnoreCase(name)) {
nodeOneBeforeTheTargetNode = currentNode;
break;
}
currentNode = currentNode.getNextNode();
}
return nodeOneBeforeTheTargetNode;
}
Get All Method Note your method returns String. If you are getting all elements of linked list which are in this case contacts then it should return some collection. I am using Array as that is most basic.
/**
*
* #return Array of all contacts in linked list
*/
public Contact[] getAll() {
Contact[] contacts = new Contact[size];
Node currentNode = head;
for (int i = 0; i < size; i++) {
if (currentNode != null) {
contacts[i] = currentNode.getContact();
currentNode = currentNode.getNextNode();
}
}
return contacts;
}

Related

How to create some methods(ex: insertAtIndex()) for custom linked list?

I am new to the concept of Linked list, and I am having a lot of trouble building this custom linked list for the first time.
I have two classes: CellPhone and CellList.
In CellPhone, I have 4 attributes: serialNum(long), brand(String), year(int), and price(double).
In CellList, I have:
an inner class called CellNode, which has two attributes: phone(CellPhone), and next(CellNode)
and two attributes head(CellNode) and size(int)
This is from my CellList class:
private CellNode head; // point first node in this list object
private int size; // current size of the list(how many nodes in the list)
public CellList() {
head = null;
size = 0;
}
public CellList(CellList c) { // is this a correct deep copying?
head = new CellNode(c.head);
size = c.getSize();
}
public int getSize() {
return size;
}
public void addToStart(CellPhone c) {
head = new CellNode(c, null); //head.getPhone() = c, head.getNextNode() = null.
size++;
}
I am not even sure if that addToStart method is correctly done, and now I need to add methods like insertAt(/deleteFrom)Index(CellPhone c, int index). I've done till here:
public void insertAtIndex(CellPhone c, int index) { //index is invalid when it's not 0<index<size-1
if(index<0 || index>size-1) {
throw new NoSuchElementException("index is invalid! System terminated.");
}
but I can't fully understand how this Node thing works, so I am stuck.
Here is the full code:
import java.util.NoSuchElementException;
public class CellList {
class CellNode {
private CellPhone phone;
private CellNode next;
public CellNode() {
phone = null;
next = null;
}
public CellNode(CellPhone c, CellNode n) {
phone = c;
next = n;
}
public CellNode(CellNode c) {
this(c.getPhone(), c.getNextNode());
}
public CellNode clone() {
CellNode c = new CellNode(phone, next);
return c;
}
public CellPhone getPhone() {
return phone;
}
public CellNode getNextNode() {
return next;
}
public void setPhone(CellPhone c) {
phone = c;
}
public void setNextNode(CellNode n) {
next = n;
}
}
private CellNode head; // point first node in this list object
private int size; // current size of the list(how many nodes in list)
public CellList() {
head = null;
size = 0;
}
public CellList(CellList c) {
head = new CellNode(c.head);
size = c.getSize();
}
public int getSize() {
return size;
}
public void addToStart(CellPhone c) {
head = new CellNode(c, null); //head.getPhone() = c, head.getNextNode() = null.
size++;
}
public void insertAtIndex(CellPhone c, int index) { //index is invalid when it's not 0<index<size-1
if(index<0 || index>size-1) {
throw new NoSuchElementException("index is invalid! System terminated.");
}
}
public void showContents() {
while(head.getNextNode() != null) {
System.out.println(head.getPhone()+"---->");
head = head.getNextNode();
}
}
}
If you want to insert a node at an index x you have to,
go to the node at index x-1, store the next value of node x-1 in a temp variable, put the node you want to insert in next property of x-1 node, and put the value in the temp variable in the next property of the node you want to insert.

I need help to write a program that takes input from user and reverses using a stack?

I’m trying to build a program (Java) that would take string input from user puts it into a stack and then reverses the stack using push and pop. When the user inputs “end-line” the program will stop pushing to the stack and print the strings entered by user in reverse order ?
public class stackReversal{
private class Node{
private String item;
private Node next;
}
private Node first = null;
public boolean isEmpty(){
return(first == null);
}
public void push(String s){
Node node = new Node();
node.item = s;
node.next = first;
first = node;
}
public String pop(){
if(first == null)
throw new RuntimeException("Stack Empty!");
String result = first.item;
first = first.next;
return result;
}
public String popString(){
String result="";
Node current = first;
while(current != null){
result += current.item;
current = current.next;
}
return result;
}
public static void main(String [] args)
{
stackReversal s = new stackReversal();
s.push("Hello");
s.push("world");
s.push("!");
System.out.println("Strings:" + s);
}
}
Please find the below code. All I did is I override the toString method to print the nodes item.
Now I am inputting 1,2,3 it will print Strings:3 -> 2 -> 1 as output.. Hope this helps
public class stackReversal {
private class Node {
private String item;
private Node next;
}
private Node first = null;
public boolean isEmpty() {
return (first == null);
}
public void push(String s) {
Node node = new Node();
node.item = s;
node.next = first;
first = node;
}
public String pop() {
if (first == null)
throw new RuntimeException("Stack Empty!");
String result = first.item;
first = first.next;
return result;
}
public String popString() {
String result = "";
Node current = first;
while (current != null) {
result += current.item;
current = current.next;
}
return result;
}
/*
* (non-Javadoc)
*
* #see java.lang.Object#toString()
*
* This method prints the nodes in reerse order
*/
#Override
public String toString() {
StringBuilder nodes = new StringBuilder();
Node node = first;
while (node != null) {
nodes.append(node.item).append(" -> ");
node = node.next;
}
if(isEmpty()) {
return "";
} else {
return nodes.toString().substring(0, nodes.toString().length() - 4);
}
}
public static void main(String[] args) {
stackReversal s = new stackReversal();
s.push("1");
s.push("2");
s.push("3");
System.out.println("Strings:" + s);
}
}

LinkedList class. (ReflectiveOperationException)

I am learning Java SE and am currently at simple linked lists (page 687/1047 of Savitch's Absolute Java).
I am stuck at instantiating the LinkList in the main method of my demo class:
LinkedList1 list = new LinkedList1();
I tried using breakpoint and it indicates a ReflectiveOperationException.
This is the code:
public class Node1
{
private String item;
private int count;
private Node1 link;
public Node1()
{
link = null;
item = null;
count = 0;
}
public Node1(String newItem, int newCount, Node1 linkValue)
{
setData(newItem, newCount);
link = linkValue;
}
public void setData(String newItem, int newCount)
{
item = newItem;
count = newCount;
}
public void setLink(Node1 newLink)
{
link = newLink;
}
public String getItem()
{
return item;
}
public int getCount()
{
return count;
}
public Node1 getLink()
{
return link;
}
}
This is the LinkedList1 class:
public class LinkedList1
{
private Node1 head;
public LinkedList1()
{
head = null;
}
/**
* Adds a node at the start of the list with the specified data.
* The added node will be the first node in the list.
*/
public void add(String itemName, int itemCount)
{
head = new Node1(itemName, itemCount, head);
}
/**
* Removes the head node and returns true if the list contains at least
* one node. Returns false if the list is empty.
*/
public boolean deleteHeadNode()
{
if (head != null)
{
head = head.getLink();
return true;
}
else
return false;
}
/**
* Returns the number of nodes in the list.
*/
public int size()
{
int count = 0;
Node1 position = head;
while (position != null)
{
count++;
head = position.getLink();
}
return count;
}
public boolean contains(String item)
{
return (find(item) != null);
}
/**
* Finds the first node containing the target item, and returns a
* reference to that node. If the target is not in the list, null is returned.
*/
public Node1 find(String target)
{
Node1 position = head;
String itemAtPosition;
while(position != null)
{
itemAtPosition = position.getItem();
if(itemAtPosition.equals(target))
{
return position;
}
position = position.getLink();
}
return null; //target was not found
}
public void outputList()
{
Node1 position = head;
while (position != null)
{
System.out.println(position.getItem() + " " + position.getCount());
position = position.getLink();
}
}
}
I think that the problem has something to do with the constructor of Node1 having the member link of type Node1. I'm trying to understand how these data structures work and not just resort to using the built-in ArrayList(& APIs) for my projects. Can you guys have a look and point me in the right direction. Any help would be very much appreciated.
This is my main method.
public class LinkedListDemo
{
public static void main(String[] args)
{
try
{
LinkedList1 list = new LinkedList1();
list.add("apples", 1);
list.add("bananas", 2);
list.add("cantaloupe", 3);
System.out.println("List has "+ list.size() + " nodes.");
list.outputList();
}
catch(Exception e)
{
System.out.println(e.getMessage());
}
}
}
Your size method contains an infinite loop which explain why the outputs are never reached.
while (position != null)
{
count++;
head = position.getLink();
}
You are looping until position is null, but never assign anything to position and instead assign to head. Instead, you want to do
while (position != null)
{
count++;
position = position.getLink();
}
Now you would get the output
List has 3 nodes.
cantaloupe 3
bananas 2
apples 1

Null Pointer Exception with Singly Linked List to hashtable Java

This is the initial class provided which we cannot modify
public class SLL {
public class Node {
private int data;
private Node next;
public Node() {
data = 0;
next = null;
}
public Node(int newData, Node linkValue) {
data = newData;
next = linkValue;
}
public int getData() {
return data;
}
public Node getLink() {
return next;
}
}// End of Node inner class
private Node head;
public SLL() {
head = null;
}
public void addToStart(int itemData) {
head = new Node(itemData, head);
}
public boolean contains(int item) {
return (find(item) != null);
}
/**
* Finds the first node containing the target item, and returns a reference
* to that node. If target is not in the list, null is returned.
*/
public Node find(int target) {
Node position = head;
int itemAtPosition;
while (position != null) {
itemAtPosition = position.data;
if (itemAtPosition == target) {
return position;
}
position = position.next;
}
return null; // target was not found
}
public void outputList() {
Node position = head;
while (position != null) {
System.out.print(position.data + " ");
position = position.next;
}
System.out.println();
}
}
And this is the Set class that we are supposed to finish to get the Tester to work and I keep getting a Null Pointer Exception with my add method, however, it is almost exactly as I have seen in other codes including our text book. Any insight would be very much appreciated as my instructor has pre-made powerpoints and doesn't explain anything or offer any advice to students seeking help.
public class Set {
private SLL[] hashArray; // DO NOT MODIFY THIS LINE
private int size = 10; // DO NOT MODIFY THIS LINE
// DO NOT MODIFY THIS METHOD
public Set() {
hashArray = new SLL[size];
}
// DO NOT MODIFY THIS METHOD
private int computeHash(int s) {
return s % size;
}
// COMPLETE BELOW
public void add(int x)
{
int hash = computeHash(x); // Get hash value
SLL list = hashArray[hash];
if (!list.contains(x))
{
// Only add the target if it's not already
// on the list.
list.addToStart(x);/*replaced hashArray[hash] with list*/
}
}
public void output( )
{
System.out.println("I will work on this later");
}
}
Finally, the Tester...
public class Tester{
// Have this method to display your name, instead.
static void displayName(){
System.out.println("Program written by Tony.\n");
}
// DO NOT MODIFY THE MAIN METHOD
public static void main(String[] args){
displayName();
Set set1 = new Set();
Set set2 = new Set();
set1.add(3);
set1.add(3);
set1.add(13);
set1.add(23);
set1.add(4);
set1.add(5);
set2.add(15);
set2.add(6);
set2.add(6);
System.out.println("Contents of set 'set1': ");
set1.output();
System.out.println("Contents of set 'set2': ");
set2.output();
System.out.println();
}
}
I don't want to give the answer directly as this is likely a homework assignment (correct me if I am wrong). Consider the very first time the add method is called on a newly constructed set. What values are in all indices of "hashArray" at this time and what does that mean for the local variable "list" in your add method?
This line isn't doing what you think it's doing.
hashArray = new SLL[size];
You need to actually create each SLL that will populate the array once the array itself is created.

What is a better method to sort strings alphabetically in a linked list that is reading in lines from a text file?

public class ContactList {
private ContactNode head;
private ContactNode last;
public ContactNode current;
public ContactList value;
public ContactList() {}
public void addNode(ContactNode input) {
if (this.head == null) {
this.head = input;
this.last = input;
} else last.setNext(input);
input.setPrev(last);
this.last = input;
}
public void traverse() {
System.out.println();
current = this.head;
while (current != null) {
System.out.print(current.getName() + " ");
System.out.println("");
current = current.getNext();
}
System.out.println();
}
public void insertNewFirstNode(String value) {
ContactNode newNode = new ContactNode(value);
head = newNode;
if (last == null) {
last = head;
}
}
public void sort() {
ContactList sorted = new ContactList();
current = head;
while (current != null) {
int index = 0;
if ((current.getName() != null)) {
index = this.current.getName().compareTo(current.getName());
if (index == 1) {
sorted.insertNewFirstNode(current.getName());
}
current = current.getNext();
} else if ((current != null)) {
System.out.print(sorted + "\n");
}
}
} // end contactList
Main Method:
import java.util.Scanner;
import java.io.FileReader;
import java.io.FileNotFoundException;
public class ContactMain {
public static void main(String[] args) {
try {
FileReader filepath = new FileReader("data1.txt");
Scanner k = new Scanner(filepath);
ContactList myList = new ContactList();
while (k.hasNextLine()) {
String i = k.nextLine();
myList.addNode(new ContactNode(i));
}
myList.traverse();
myList.sort();
myList.traverse();
} catch (FileNotFoundException e) {
System.out.println("File Not Found. ");
}
}
}
Node Class:
public class ContactNode {
private String name;
public int index;
private ContactNode prev;
public ContactNode next;
ContactNode(String a) {
name = a;
index = 0;
next = null;
prev = null;
}
public ContactNode getNext() {
return next;
}
public ContactNode getPrev() {
return prev;
}
public String getName() {
return name;
}
public int getIndex() {
return index;
}
public void setNext(ContactNode newnext) {
next = newnext;
}
public void setPrev(ContactNode newprevious) {
prev = newprevious;
}
public void setName(String a) {
name = a;
}
public void setIndex(int b) {
index = b;
}
}
I am making a program for fun that reads in contact information from a text file and puts them into a Linked List. I want to create a sort() method to sort each node or name alphabetically. I've done a good amount of research and my method only prints code like: ContactList#282c0dbe, by as many lines as my text file.
what is ContactList#282c0dbe?
It is class name follow by at sign and hash code at the end, hash code of the object.All classes in Java inherit from the Object class, directly or indirectly . The Object class has some basic methods like clone(), toString(), equals(),.. etc. The default toString() method in Object prints “class name # hash code”.
What is the solution?
You need to override toString method in ContactList class because it is going to give you clear information about the object in readable format that you can understand.
The merit about overriding toString:
Help the programmer for logging and debugging of Java program
Since toString is defined in java.lang.Object and does not give valuable information, so it is
good practice to override it for subclasses.
#override
public String toString(){
// I assume name is the only field in class test
return name + " " + index;
}
For sorting, you should implement Comparator interface since your object does not have natural ordering. In better sense, if you want to define an external controllable ordering behavior, this can override the default ordering behavior
read more about Comparator interface
You need custom Comparator for sorting, and to pretty print your List you need to implement toString() in ContactList class

Categories

Resources