I have created this Node class for a singly linked list:
class Node{
int item;
Node next;
Node(int v){
item = v;
next = null;
}
}

I want to make a search for the node with the highest key in a method called findmax.But i want to check if the list is empty, and if so , to return null, otherwise return the node with the highest key. This is what i have done:
Node findmax(Node h){
if(h==null)
return null;
else{
//search
}
All i want to know is if the check i make to see if the list is Empty is correct.
Yes, the check you've done is correct if:
Node n = null;// init empty list
and:
n = new Node(3);// first item
However, I suggest you to create a list struct which is independent from the item it concatenates. That's what I mean:
The Node class:
public class Node
{
int value;
public Node(int value) {
this.value = value;
}
public int getValue() {
return value;
}
}
The list struct:
public interface IList
{
public int getNodeNumbers();
}
public class EmptyList implements IList
{
#Override public int getNodeNumbers() {
return 0;
}
}
public class ConsList implements IList
{
private Node node;
private IList next;
public ConsList(Node node, IList next) {
this.node = node;
this.next = next;
}
#Override public int getNodeNumbers() {
return 1 + next.getNodeNumbers();
}
}
How to use it:
public class Main
{
public static void main(String[] args) {
IList list1 = new ConsList(new Node(1),
new ConsList(new Node(2),
new ConsList(new Node(3),
new ConsList(new Node(4),
new EmptyList()))));
IList list2 = new EmptyList();
System.out.println(list1.getNodeNumbers() + " - " + list2.getNodeNumbers());
}
}
And now, a list is empty (you can create your own method isEmpty() into the IList interface) when getNodeNumbers() returns 0.
Related
I doesnt quite get why the part with the object names down there works? I invoke the method append(int number) with a parameter in my main method and create a List of Node Objects that store integer values this way. However, why wont the object names "temp" and "current" be replaced when a call append a second, a third.... time. They are always the same object names and one object name cant refer to multiple objects, I thought. When I call the method elementAt(), I get everytime the response I wanna have, but I dont know exactly why it did work.
Heres my Code for the Class MyList
public class MyList
{
Node head;
int count;
Node temp;
Node current;
public MyList(){
head= new Node(0);
count = 0;
}
public void append(int number){
temp = new Node(number);
current = head;
while(current.getNext() != null){
current = current.getNext();
}
current.setNext(temp);
count++;
}
public int elementAt(int number){
if(head != null){
current = head.getNext();
for(int i = 0; i < number ; i++){
if(current.getNext() == null){
return 0;
}
current = current.getNext();
}
return current.item;
}
return 0;
}
}
Heres the Code for the Class Node
public class Node {
public int item;
public Node next;
public Node(int item){
this.item = item;
}
public Node getNext(){
return next;
}
public void setNext(Node next){
this.next = next;
}
}
Heres the code for my the Main Class
public class MainList {
public static void main(String[] args) {
MyList list = new MyList();
list.append(10);
list.append(20);
list.append(30);
list.append(40);
list.append(50);
list.append(60);
list.append(40);
System.out.println(list.elementAt(0));
}
}
Is there a way to use the compareTo function when comparing objects, I'm not sure if it's just for Strings. I am trying add an node into its correct position in ascending order.
heres where I declare my attributes/constructor
private Node<E> head; //refers to the head of the node
private int size; // keeps track of the size of the list
// default constructor which creates empty ordered list
public OrderedList(){head = null; size = 0;}
Heres my insert function
public void insert(Object o)
{
Node n = new Node(o, null); // creates new node
// Node for first element greater than or equal
Node current = head.getLink();
Node before = head; // Node for right before the next one is found
// checks to see if list is empty
if(size == 0)
{
head = n;
}
// checks if element is smaller than the head
else if (o.compareTo(head.o) < 0)
{
n.getLink() = head;
head = n;
}
}
here is my node class
package project.pkg3;
public class Node<T>
{
private Object data;
private Node link;
public Node(Object o, Node l){data = o; link = l;}
public void setData(Object o){data = o;}
public void setLink(Node l){link = l;}
public Object getData(){return data;}
public Node getLink(){return link;}
}
I'm getting an error message when trying to check whether the element belongs in the front on this line
else if (o.compareTo(head.o) < 0)
telling me that it cannot find the symbol, which I'm not sure what that means
Im also getting another error message on this line
n.getLink() = head;
this one is telling me that it's an unexpected type
If your linked list must be sorted using compareTo(), then you need to make sure that the underlying data is comparable.
public class Node<T extends Comparable>
{
private T data;
private Node<T> link;
public Node(T o, Node<T> l) { data = o; link = l; }
public void setData(T o) { data = o; }
public void setLink(Node<T> l) {link = l; }
public T getData() { return data; }
public Node<T> getLink() { return link; }
}
Then this block
else if (o.compareTo(head.o) < 0)
{
n.getLink() = head;
head = n;
}
should be changed into this:
else if (
(o.getData() != null) ?
(o.getData().compareTo(head.getData()) < 0) :
(head.getData().compareTo(o.getData()) > 0)
)
{
n.setLink(head);
head = n;
}
I didn't look at your linked list implementation though, so I have no idea the other stuff are correct.
Your node class should implement java.lang.Comparable interface and override its compareTo() method as per your logic.
public class Node<T extends Comparable<T>>{
}
Your argument object would implement Comparable interface. For eg:
public class Name implements Comparable<Name> {
private String str1;
public int compareTo(Name o) {
//your logic here to compare object with itself
return this.str1.compareTo(o.str1);
}
}
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.
I need to implement custom linked list using generics.
Here is what I've done
public class Node {
Node next;
Object data;
public Node(Object data) {
next = null;
this.data = data;
}
public Object getData() {
return data;
}
public void setData(Object dataValue) {
data = dataValue;
}
public Node getNext() {
return next;
}
public void setNext(Node nextValue) {
next = nextValue;
}
}
public class LinkedList {
private Node head;
private int size;
public LinkedList() {
head = new Node(null);
size = 0;
}
public void add(Object data) {
Node node = new Node(data);
Node current = head;
while (current.getNext() != null) {
current = current.getNext();
}
current.setNext(node);
size++;
}
public int getSize() {
return size;
}
public String toString() {
Node current = head.getNext();
String elements = "";
while (current != null) {
elements += "[" + current.getData().toString() + "]";
current = current.getNext();
}
return elements;
}
}
public class Main {
public static void main(String[] args) {
System.out.println("Hello there!");
LinkedList list = new LinkedList();
list.add("First node");
list.add("Second node");
list.add("Third node");
list.add("Fourth node");
list.add("Fifth node");
System.out.println("Linked list contains " + list.getSize() + " nodes");
System.out.println("Here they are: " + list);
}
}
I have no idea or just didn't quite understand where i should use generics and how? Any ideas?
You start with the Node class; specifically, you make it such that it can contain any type of data.
You do that in this manner:
Introduce a generic type parameter at the class level
public class Node<T> { }
Wherever you have Object, replace it with T.
T data;
Be sure to update references to other Node instances inside so that they're using the same generic argument.
Node<T> next;
Now, you can address the issues in your LinkedList class in a similar way.
Introduce a generic type parameter at the class level
public class LinkedList<T> { }
Change the argument of add from Object to T.
public void add(T data) { }
Add the generics to your Node instance(s) so that you're not using a raw type.
private Node<T> head;
You should consider going through the Generics tutorial. Specifically, read through the 'Generic Types' section.
Basically, your LinkedList and Node implementations need to be generic by simply declaring them as LinkedList<T> and Node<T>. Once you've changed the classes to be generic, you can then instantiate a parameterized LinkedList, such as:
LinkedList<String> stringList = new LinkedList<>();
The LinkedList is now type-safe and will only allow Strings to be stored.
I have been diligently watching YouTube videos in an effort to understand linked lists before my fall classes start and I am uncertain how to proceed with iterating over the following linked list. The 'node' class is from a series of videos (same author), but the 'main' method was written by me. Am I approaching the design of a linked list in an illogical fashion (assuming of course one does not wish to use the predefined LinkedList class since the professor will expect each of us to write our own implementation)?:
class Node
{
private String data;
private Node next;
public Node(String data, Node next)
{
this.data = data;
this.next = next;
}
public String getData()
{
return data;
}
public Node getNext()
{
return next;
}
public void setData(String d)
{
data = d;
}
public void setNext(Node n)
{
next = n;
}
public static String getThird(Node list)
{
return list.getNext().getNext().getData();
}
public static void insertSecond(Node list, String s)
{
Node temp = new Node(s, list.getNext());
list.setNext(temp);
}
public static int size(Node list)
{
int count = 0;
while (list != null)
{
count++;
list = list.getNext();
}
return count;
}
}
public class LL2
{
public static void main(String[] args)
{
Node n4 = new Node("Tom", null);
Node n3 = new Node("Caitlin", n4);
Node n2 = new Node("Bob", n3);
Node n1 = new Node("Janet", n2);
}
}
Thanks for the help,
Caitlin
There are some flaws in your linked list as stated by some of the other comments. But you got a good start there that grasps the idea of a linked list and looks functional. To answer your base question of how to loop over this particular implemention of the linked list you do this
Node currentNode = n1; // start at your first node
while(currentNode != null) {
// do logic, for now lets print the value of the node
System.out.println(currentNode.getData());
// proceed to get the next node in the chain and continue on our loop
currentNode = currentNode.getNext();
}
Maybe this will be useful:
static void iterate(Node head) {
Node current = head;
while (current != null) {
System.out.println(current.getData());
current = current.getNext();
}
}
// or through recursion
static void iterateRecursive(Node head) {
if (head != null) {
System.out.println(head.getData());
iterateRecursive(head.getNext());
}
}
class List {
Item head;
class Item {
String value; Item next;
Item ( String s ) { value = s; next = head; head = this; }
}
void print () {
for( Item cursor = head; cursor != null; cursor = cursor.next )
System.out.println ( cursor.value );
}
List () {
Item one = new Item ( "one" );
Item two = new Item ( "three" );
Item three = new Item ( "Two" );
Item four = new Item ( "four" );
}
}
public class HomeWork {
public static void main( String[] none ) { new List().print(); }
}
Good luck!!
You can have your linked list DS class implement 'Iterable' interface and override hasNext(), next() methods or create an inner class to do it for you. Take a look at below implementation:
public class SinglyLinkedList<T>{
private Node<T> head;
public SinglyLinkedList(){
head = null;
}
public void addFirst(T item){
head = new Node<T>(item, head);
}
public void addLast(T item){
if(head == null){
addFirst(item);
}
else{
Node<T> temp = head;
while(temp.next != null){
temp = temp.next;
}
temp.next = new Node<T>(item, null);
}
}
private static class Node<T>{
private T data;
private Node<T> next;
public Node(T data, Node<T> next){
this.data = data;
this.next = next;
}
}
private class LinkedListIterator implements Iterator<T>{
private Node<T> nextNode;
public LinkedListIterator(){
nextNode = head;
}
#Override
public boolean hasNext() {
return (nextNode.next != null);
}
#Override
public T next() {
if(!hasNext()) throw new NoSuchElementException();
T result = nextNode.data;
nextNode = nextNode.next;
return result;
}
}
}