How to implement a sorted list - java

So i have a class called List and a class called SortedList which inherits the class List. Also there is a class called node. I have created another class which contains the printing method.
But, everytime i insert three names for example, and i call the printing method it only prints the last name i have inserted. So my question is: does this code makes a sorted list? And if so, why does it print only the last name?
List class:
public class List {
protected Node head;
protected int length;
public void list()
{
head=null;
length=0;
}
public boolean isEmpty()
{
return head==null;
}
public Node insert(Item a)
{
length++;
head=new Node(a, head);
return head;
}
SortList class:
public class SortList extends List {
private Node head;
public SortList()
{
this.head=null;
}
public Node getFirst()
{
return head;
}
public Node Insert(Item newitem)
{
Node node = new Node(newitem);
Node previous = null;
Node current = head;
while(current!=null && current.getValue().less(newitem))
{
previous=current;
current=current.getNext();
}
if(previous==null)
{
head=node;
}
else
{
previous.setNext(node);
node.setNext(current);
}
return head;
}
public void printlist()
{
Node current = head; //ΑΡΧΗ ΤΗΣ ΛΙΣΤΑΣ.
while(current!=null)
{
current.print();
current = current.getNext();
}
}
Node class:
public class Node {
private Item info;
private Node next;
public Node(Item dat)
{
info=dat;
}
public Node (Item dat, Node b)
{
info=dat;
next=b;
}
public Item getValue()
{
return info;
}
public void setNext(Node a)
{
next=a;
}
public Node getNext()
{
return next;
}
public void print()
{
info.print();
}
}

In your Implementation of List, you have a major bug in the insert() method:
public Node insert(Item a)
{
length++;
head=new Node(a, head);
return head;
}
You do not attach the new element to the end of the list, but rather replace the list's head each time, thus discarding the previous element.
This would explain why you always only see the last element you have inserted.
Edit: Turns out, the insert() method actually does work, since you set the reference to the next node in the node's constructor.
In your sorted list however, you have one insert case for which the next node is not set:
if(previous==null)
{
head=node;
}
I your sorted list, you don't set the next element in the constructor of the node. In all other cases, you set the next element in the insert() method, but not in this case. If the element you want to insert is the smallest in the list, previous is null, which is correct -- your new element is the new head of the list. Since you don't set the new element's successor, however, all elements that have been in the list are now gone.
If the last element you insert into the list is the smallest, the last element will also be the only one remaining and you print out only the last element.
Try setting the successor:
if(previous==null)
{
head=node;
head.setNext(current);
}

Related

Need guidance on creating Node class (java)?

I need to implement a Node class, where the basic methods are: getItem(), getNext(), setItem() and setNext(). I want the nodes to be able to store at least the default integer range in Java as the “item”; the “next” should be a reference or pointer to the next Node in a linked list, or the special Node NIL if this is the last node in the list.I also want to implement a two-argument constructor which initializes instances with the given item (first argument) and next node (second argument) , I've kind of hit a brick wall and need some guidance about implementing this , any ideas ?
I have this so far:
class Node {
public Node(Object o, Node n) {
}
public static final Node NIL = new Node(Node.NIL, Node.NIL);
public Object getItem() {
return null;
}
public Node getNext() {
return null;
}
public void setItem(Object o) {
}
public void setNext(Node n) {
}
}
While implementing the custom LinkedList/Tree, we need Node. Here is demo of creating Node and LinkedList. I have not put in all the logic. Just basic skeleton is here and you can then add more on yourself.
I can give you a quick hint on how to do that:
Class Node{
//these are private class attributes, you need getter and setter to alter them.
private int item;
private Node nextNode;
//this is a constructor with a parameter
public Node(int item)
{
this.item = item;
this.nextNode = null;
}
// a setter for your item
public void setItem(int newItem)
{
this.item = newItem;
}
// this is a getter for your item
public int getItem()
{
return this.item;
}
}
You can create a Node object by calling:
Node newNode = Node(2);
This is not a complete solution for your problem, the two parameter constructor and the last node link are missing, but this should lead you in the correct direction.
Below is a simple example of the Node implementation, (i renamed Item to Value for readability purpose). It has to be implemented somehow like this, because methods signatures seems to be imposed to you. But keep in mind that this is definely not the best way to implement a LinkedList.
public class Node {
public static final Node NIL = null;
private Integer value;
private Integer next;
public Node(Integer value, Node next) {
this.value = value;
this.next = next;
}
public Integer getValue() {
return this.value;
}
public Node getNext() {
return this.next;
}
public void setValue(Integer value) {
this.value = value;
}
public void setNext(Node next) {
this.next = next;
}
public boolean isLastNode() {
return this.next == Node.NIL || Node;
}
}
public class App {
public static void main(String[] args) {
Node lastNode = new Node(92, Node.NIL);
Node secondNode = new Node(64, lastNode);
Node firstNode = new Node(42, secondNode);
Node iterator = firstNode;
do () {
System.out.println("node value : " + iterator.getValue());
iterator = iterator.getNext();
} while (iterator == null || !iterator.isLastNode());
}
}
The node class that will be implemented changes according to the linked list you want to implement. If the linked list you are going to implement is circular, then you could just do the following:
public class Node {
int data;
Node next = null;
public Node(int data){
this.data = data;
}
}
Then how are you going to implement the next node?
You are going to do it in the add method of the circularLinkedList class. You can do it as follows:
import java.util.*;
public class CircularLinkedList {
public CircularLinkedList() {}
public Node head = null;
public Node tail = null;
public void add(int data) {
Node newNode = new Node(data);
if(head == null) {
head = newNode;
}
else {
tail.next = newNode;
}
tail = newNode;
tail.next = head;
}
public void displayList() {
System.out.println("Nodes of the circular linked list: ");
Node current = head;
if(head == null) {
System.out.println("Empty list...");
}
else {
do {
System.out.print(" " + current.data);
current = current.next;
}while(current != head);
System.out.println();
}
}
}

Storing more than one information into one Node in a singly linked list

I'm trying to add several information into one Node in a singly linked list... How do I do that?
After asking the user for several vehicle information: plateNo(String), vehicleType(String), serviceType(String) I will have to store this information for each vehicle. I have to use a singly linked list to store all the vehicle entering and leaving the wash.
Then, my program should display all the vehicles entering and leaving the vehicle wash with their service order.
How do I do this?
This is my singly LinkedList:
public class LinkedList<T>
{
private Node<T> head; // first node in the linked list
private int count;
public int getCount() {
return count;
}
public Node getHead() {
return head;
}
public LinkedList() {
head = null; // creates an empty linked list
count = 0;
}
public void displayList(){
Node<T> current = head; // start at beginning
while(current != null) // until end of list,
{
System.out.print(current.getData() + " ");
current = current.getNext();
//move to next link
}
System.out.println("");
}
public Node deleteFront()
{
Node<T> temp = head;
if(head.getNext() == null) // if only one item
return null; // return null
head = head.getNext(); // first --> old next
count--;
return temp;
}
public void removeValue(T value)
{
Node<T> current = head, prev = null;
while (current != null)
{ //if current node contains value
if (value == current.getData())
{
//handle front removal (case 1)
if( prev == null)
head = current.getNext();
else //handle mid removal (case 2)
prev.setNext(current.getNext());
// prev node now points to maxNode's (a.k.a current) successor, removing max node.
break; // remove first occurence only
}
// update prev to next position (curr)
prev = current;
// move curr to the next node
current = current.getNext();
}
}
public void addFront(T n)
{
Node<T> newNode = new Node<T>(n);
newNode.setNext(head);
head = newNode;
count++;
}
}
My Node
public class Node<T> {
private T data;
private Node next;
public T getData() {
return data;
}
public void setData(T data) {
this.data = data;
}
public Node getNext() {
return next;
}
public void setNext(Node next) {
this.next = next;
}
public Node(T data) {
this.data = data;
this.next = null;
}
}
I'm trying to add several information into one Node in a singly linked list... How do I do that?
... by thinking object-oriented! Create a class that models a vehicle:
class Vehicle {
String plateNo;
String vehicleType;
String serviceType;
// constructors, getters, setters, other methods ...
}
You have already a generic Node<T>, so use it:
Vehicle vehicle = callAwesomeMethodThatCreatesVehicleInstance();
Node<Vehicle> node = new Node(vehicle);
Now you can use such a node in your linked list.
Your code seems fine. You just need to define a new class that contains all the information that you want to store. As you have already made the Node class for a generic data type T, you can then insert the new class that you will make here.
class Details{
String plateNo;
String vehicleType;
String serviceType;
public Details(){
this.plateNo = "";
this.vehicleType = "";
this.serviceType = "";
}
}
Then in your code for the linked list:
public class LinkedList<T>
{
private Node<Details> head = new Details();
//rest of the class
}

Java - Custom iterator not able to track head of custom linked list

The classes are not complete, but here's what I have so far and I expected the test below to pass.
public class LinkedList<T> extends AbstractSequentialList<T> {
private Node<T> head;
#Override
public boolean add(T element) {
if(head == null) {
head = new Node(element);
}
return true;
}
#Override
public ListIterator<T> listIterator(int index) {
return new LinkedListIterator<>();
}
#Override
public int size() {
return 0;
}
private class LinkedListIterator<T> implements ListIterator<T> {
private Node<T> current;
public LinkedListIterator() {
current = (Node<T>) head;
}
#Override
public boolean hasNext() {
return (current != null && current.getNext() != null)? true : false;
}
#Override
public T next() {
return null;
}
}
}
Here is the Node class.
public class Node<T> {
private T value;
private Node next;
public Node(T value) {
this.value = value;
}
public Node(T value, Node next) {
this.value = value;
this.next = next;
}
public T getValue() {
return value;
}
public Node getNext() {
return next;
}
public void setNext(Node next) {
this.next = next;
}
}
My iterator test is like this.
LinkedList<String> list;
ListIterator<String> iterator;
#Before
public void setUp() throws Exception {
list = new LinkedList<>();
iterator = list.listIterator();
}
#Test
public void testHasNext() throws Exception {
assertThat(iterator.hasNext(), is(false));
list.add("Hello World");
assertThat(iterator.hasNext(), is(true));
}
However, I'm failing on the second assertion. My issue is that the "current" pointer in the iterator is always null even though I'm setting it to the head of the enclosing LinkedList class. How can I fix this? Thanks.
It looks the value of current is set inside the constructor of LinkedListIterator.
It hasn't been updated after you have added an element to the list. This seems to your problem here.
What is wrong is your test, IMO.
You shouldn't expect the iterator to point to the first element if the first element has been added after the iterator has been constructed.
Now, why does your iterator work this way? Because Java is pass-by-value. When you construct an iterator, the iterator receives a copy of the reference to the first node of the list. And at this time, this reference is null, because you haven't added any node yet.
If you really want the iterator to "see" the first node of the list even after it has been constructed, then the iterator needs to get the first node of the list in hasNext(), not in the constructor.

Java Searching LinkedList for data return true/false?

I need write a method to loop through a linked list searching to see if Object data is in linked list. Any help?
public class LinkedList {
private LinkedListNode head;
public boolean find(Object data){
for(somethinggoeshere..){
if(head==data){
return true;
}else{
return false;
}
}
Any help?
Edit: My LinkedListNode class:
public class LinkedListNode {
private Object data;
private LinkedListNode next;
public LinkedListNode(Object data, LinkedListNode next) {
super();
this.data = data;
this.next = next;
}
public Object getData() {
return data;
}
public void setData(Object data) {
this.data = data;
}
public LinkedListNode getNext() {
return next;
}
public void setNext(LinkedListNode next) {
this.next = next;
}
}
Edit: Final solution for those who are interested:
public class LinkedList {
private LinkedListNode head;
public boolean find(Object data){
LinkedListNode temp = head;
while(temp!= null) // check if you have reached the tail
{
if(data.equals(temp.getData()))
{
return true;
}
temp = temp.getNext(); // move to the next node
} // end of while loop
return false;
} // end of find method
Assuming that you wrote the code for LinkedListNode, you should know wether or not is Iterable, and thus be able to loop through it with a for-each loop like that.
As it stands, you should traverse the nodes either recursively or in an iterative manner, by using some form of "next" pointers that is held within each node, and in essence do a linear search through the links until you find the data you are looking for, or return null.
Here's a link for some help on implementing a linked list:
http://www.danielacton.com/Data-Structures/Linked-List/Java/
You need to loop through your LinkedList and search for the data. If you reach tail of the list and still unable to find the data this implies that data is not in the LinkedList.
I am assuming that LinkedListNode has a member variable data to store the data in each node. Below is the corrected code :
public class LinkedList {
private LinkedListNode head;
public boolean find(Object data)
{
LinkedListNode temp = head;
while(temp!= null) // check if you have reached the tail
{
if(data.equals(temp.getData()))
{
return true;
}
temp = temp.getNext(); // move to the next node
} // end of while loop
return false;
} // end of find method
}

How to implement getPrevious() method for double linked list?

We were given the following code from the last assignment to use for singly linked list, but we're supposed to add in a getPrevious() and setPrevious() method. The following code works for the singly linked list as I completed the assignment and got 100%.
I searched online and read my book but couldn't find a solution.
For a singly linked list I would start from the head and iterate until the getNext() == current or something of the like. Obviously that beats the purpose of a doubly linked list, so any ideas?
public class Node
{
private Object item;
private Node next;
public Node()
{
this.next = null;
}
public Node(Object newItem)
{
this.item = newItem;
this.next = null;
}
public Node(Object newItem, Node newNext)
{
this.item = newItem;
this.next = newNext;
}
public Object getItem()
{
return this.item;
}
public void setItem(Object newItem)
{
this.item = newItem;
}
public Node getNext()
{
return this.next;
}
public void setNext(Node newNext)
{
this.next = newNext;
}
}
You just need to to add an extra member similar to next that would point to the previous node in the list. Having done that, adding a getter and a setter would be trivial.
(You will, of course, need to change your implementation of the linked list to correctly populate this new member.)
So... where's the problem?
Node previous;
public Node getPrevious() {
return previous;
}
public void setPrevious(Node node) {
this.previous = node;
}
If you are to make the list a doubly-linked-list you have to implement the "other", opposite-direction link. You do it by adding nother field for each node. And you also have to update the field each time you modify the list.

Categories