Hi all im wondering how to display all nodes in a linked list. Heres the code I have so far. The Manager class is supposed to operate the list. The movieNode class creates new list nodes for the movie. I know I have to use other things as well but im just trying to get the first element of the list to display for starters.
public class Manager {
MovieNode head;
public Manager (){
head=null;
}
public void Add (MovieNode data) {
if (head==null){
head=data;
}
}
public void Display () {
int i=1;
MovieNode temp=head;
System.out.println("Displaying Movies");
while (head!=null) {
System.out.println(temp.getData().getName());
head=null;
}
}
}
also, the code for the MovieNode class
public class MovieNode {
private Movie data;
private MovieNode next;
public MovieNode (){
data=null;
next=null;
}
public MovieNode (Movie data){
setData(data);
}
public void setData (Movie data){
this.data=data;
}
public Movie getData (){
return data;
}
}
Hopefully this will help you get started. Here are some pointers:
Manager Class
You don’t need an explicit constructor for Manager, as you can initialize the head variable in line and you’re not passing any other information to the constructor
Method names in Java are conventionally camel case and start with lower-case letter
When you add a new item to the linked list, you can pass in just the data and create the node in the add method
Assuming you don’t need to maintain any special order, you can insert the new item to the head of the list. This saves the time to go through the whole list to find the tail or keeping a reference to the tail.
To display all the movies, you just need to start with the head and check if there is a node next in list. If you don’t need to implement this custom method, I would recommend implementing the class as Iterable. A SO discussion on this topic can be found here
MovieNode Class
You only need one constructor that takes the data and sets the private variable
You also need the getter and setter for the next variable in order to hold the list structure and iterate through the list
The toString() implementation will allow to print an instance of this class directly, as in displayAllMovies() method
Movie Class
This class just holds the title of the movie for now, but you can extend it according to your spec.
Here is the code:
public class Manager {
MovieNode head = null;
public void addMovie(Movie data) {
MovieNode newNode = new MovieNode(data);
if (head == null) {
head = newNode;
} else {
newNode.setNext(head);
head = newNode;
}
}
public void addMovieInOrder(Movie data) {
MovieNode newNode = new MovieNode(data);
if (head == null) {
head = newNode;
} else {
MovieNode higher = head;
MovieNode lower = null;
// find the right position for newNode
while(higher != null){
if(newNode.compareTo(higher) > 0){
lower = higher;
higher = higher.getNext();
}
else break;
}
newNode.setNext(higher);
if(higher == head) head = newNode; //inserting as head
else lower.setNext(newNode);
}
}
public void displayAllMovies() {
MovieNode node = head;
if (node == null) {
System.out.println("The list is empty!");
}
do {
System.out.println(node.getData());
node = node.getNext();
} while (node != null);
}
public static void main(String[] args) {
Manager manager = new Manager();
manager.addMovieInOrder(new Movie("ddd"));
manager.addMovieInOrder(new Movie("ccc"));
manager.addMovieInOrder(new Movie("aaa"));
manager.addMovieInOrder(new Movie("bbb"));
manager.displayAllMovies();
}
}
Movie Node class:
public class MovieNode implements Comparable<MovieNode> {
private Movie data;
private MovieNode next = null;
public MovieNode(Movie data) {
this.data = data;
}
public void setData(Movie data) {
this.data = data;
}
public Movie getData() {
return data;
}
public void setNext(MovieNode node) {
this.next = node;
}
public MovieNode getNext() {
return next;
}
#Override
public String toString() {
return data.toString();
}
#Override
public int compareTo(MovieNode otherMovieNode) {
return data.compareTo(otherMovieNode.getData());
}
}
Movie class:
public class Movie implements Comparable<Movie> {
private String title;
public Movie(String title) {
this.title = title;
}
#Override
public String toString() {
return title;
}
#Override
public int compareTo(Movie otherMovie) {
return title.compareTo(otherMovie.title);
}
}
Related
I am working on a class assignment and I don't quite understand how to use comparator in the way the assignment is asking.
The assignment reads:
"Complete the Priority Queue class
Your Priority Queue must use an anonymous function to decide priority
It must take the Function interface as a parameter to the constructor
You should still have the default constructor – and if no function is provide use the compareTo function of the class"
This is the class that I am working on...
public class PriorityQueue <Item extends Comparable<Item>> {
public PriorityQueue()
{
}
public PriorityQueue(Comparator<Item> compare )
{
}
private int size = 0;
private Node<Item> head = null;
private Comparator<Item> compare ;
private static class Node<Item>
{
private Item data;
private Node<Item> next;
public Node(Item data, Node<Item> next)
{
this.data = data;
this.next = next;
}
public Node(Item data)
{
this.data = data;
this.next = null;
}
public Node()
{
this.data = null;
this.next = null;
}
}
#Override
public int size() {
return size;
}
#Override
public Item dequeue() {
// TODO Auto-generated method stub
return null;
}
#Override
public void enqueue(Item item) {
Node<Item> curr = head;
Node<Item> prev = curr;
if (isEmpty())
{
head = new Node<Item>(item,null);
}
else
{
while (curr != null)
{
prev = curr;
curr = curr.next;
}
prev.next = new Node<Item>(item, curr);
}
size++;
}
#Override
public boolean isEmpty() {
return size == 0;
}
#Override
public void printQueue() {
Node<Item> curr = head;
while (curr != null)
{
System.out.println(curr.data);
curr = curr.next;
}
}
}
This is the process class that the queue will contain...
public class Process implements Comparable<Process> {
private ProcessPriorty priority;
private String name;
public Process(ProcessPriorty priority, String name) {
super();
this.priority = priority;
this.name = name;
}
public void setPriority(ProcessPriorty priority) {
this.priority = priority;
}
#Override
public String toString() {
return name + "... Priority = " + priority + ".";
}
public String getName() {
return name;
}
public ProcessPriorty getPriority() {
return priority;
}
#Override
public int compareTo(Process other) {
if(other == null)
{
return 1;
}
return this.priority.compareTo(other.priority) ;
}
}
I understand the concept of a queue and have even coded the enqueue method to work as a simple queue that inserts the items as they come in. The problem I am coming across is comparing the nodes within that method to sort the list by priority at insertion. Which I believe relates back to those three directions of the assignment. So, what am I suppose to do with the constructors, the Comparator variable, and how do I make it default to compareTo?
Well since you have a reference to the head of the queue, its pretty simple from there. You have 2 cases -
compare != null
compare == null
In the first case, you are interested in Comparator::compareTo. From the definition of a priority queue, all you have to do is traverse the queue beginning from head, and as soon as the item in enqueue(Item item) is greater than the current element in the traversal, you insert item before element. You'll use compare.compareTo(item, element) to determine their order.
In the second case you'll simply use item.compareTo(element) to make the above stated comparison, the traversal and insertion will be the same.
I already wrote a small program of single linked list with add and traverse method in that. Now I want to convert it into a doubly linked list. I know all the concept of doubly linked list but I am facing little difficulty to implement it in my program.
public class SingleLinkList<T> {
private Node<T> head;
private Node<T> tail;
public void add(T element)
{
Node<T> nd = new Node<T>();
nd.setValue(element);
if (head==null)
{
head = nd;
tail = nd;
}
else
{
tail.setNextRef(nd);
tail = nd;
}
}
public void traverse(){
Node<T> tmp = head;
while(true){
if(tmp == null){
break;
}
System.out.println(tmp.getValue());
tmp = tmp.getNextRef();
}
}
public static void main (String args[])
{
SingleLinkList<Integer> s1 = new SingleLinkList<Integer>();
s1.add(2);
s1.add(3);
s1.add(3);
s1.traverse();
}
}
class Node<T> {
private T value;
private Node<T> nextRef;
public T getValue() {
return value;
}
public void setValue(T value) {
this.value = value;
}
public Node<T> getNextRef() {
return nextRef;
}
public void setNextRef(Node<T> nextRef) {
this.nextRef = nextRef;
}
public int compareTo(T arg)
{
if (arg==this.value)
{
return 0;}
else
{return 1;}
}
}
Add a Node<T> prevRef field to your list class with appropriate getters and setters and then add this method:
public void linkReverse(Node<T> head) {
if (head == null) {
return;
}
head.setPrevRef(null);
if (head.getNextRef() == null) {
return;
}
Node<T> prev = head;
Node<T> curr = head.getNextRef();
while (curr != null) {
curr.setPrevRef(prev);
prev = curr;
curr = curr.getNextRef();
}
}
This method will walk down a currently singly linked list and will link each node in reverse, leaving the list doubly linked.
Of course, you would need to modify the other methods as well, but this is at least a good starting point.
just add private Node<T> prevRef; instance variable to Node class, and set it during add() method. I suggest that traverse() will receive a boolean (or even better, enum) direction argument
Hey ya'll I am having a little trouble with my singly linked list. I decided to create a simple one because we do not get enough practice during my data structures class and cannot seem to find why I am not getting the right output.
The code is:
package linked_list;
public class LinkedList {
private Node head;
private Node tail; // After figuring out head, come back to this FIXME
private int listSize;
public LinkedList() {
head = new Node(null);
tail = new Node(null);
}
public void addLast(String s) {
Node newNode = new Node(s);
if (head == null) {
addFirst(s);
} else {
while (head.next != null) {
head = head.next;
}
head.next = newNode;
tail = newNode;
}
listSize++;
}
public void addFirst(String s) {
Node newNode = new Node(s);
if (head == null) {
head = newNode;
tail = newNode;
}
else {
newNode.next = head;
head = newNode;
}
listSize++;
}
public Object getFirst() {
return head.data;
}
public Object getLast() {
return tail.data;
}
public void clear() {
head = null;
tail = null;
listSize = 0;
}
public Object peek() {
try {
if (head == null) {
throw new Exception ("The value is null");
}
else {
return head;
}
} catch (Exception e) {
System.out.println(e.getMessage());
return null;
}
}
public int size() {
return listSize;
}
// This class has the ability to create the nodes that are used
// in the Linked List.
private class Node {
Node next;
Object data;
public Node(String value) {
next = null;
data = value;
}
public Node(Object value, Node nextValue) {
next = nextValue;
data = value;
}
public Object getData() {
return data;
}
public void setData(Object dataValue) {
data = dataValue;
}
public Node getNext() {
return next;
}
public void setNext(Node nextValue) {
next = nextValue;
}
}
}
Now here is my driver that I created to run a simple little operation:
package linked_list;
public class LinkedListDriver {
public static void main(String[] args) {
LinkedList list1 = new LinkedList();
list1.clear();
list1.addLast("This goes last");
list1.addFirst("This goes first");
list1.addLast("Now this one goes last");
System.out.println(list1.getFirst());
System.out.println(list1.getLast());
}
}
My output is this:
This goes last
Now this one goes last
I guess my question is why am I not getting the answer This goes first from my getFirst() method. It seems to be something wrong with the order or structure of that method but I cannot pinpoint it.
When you are in the else in the addLast, you are changing the reference to head. You should use another reference pointer to traverse the list when adding in the else.
Also, your list size should only be incremented in the else in addLast because you are incrementing twice otherwise (once in addFirst and again after the if-else in addLast).
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;
}
}
}
Hey, so I wanted to insert one data after the input data (not index).
I've tried but it always at the end, the data that i want to insert end up at the dront of the link list..
**public static void insertAfter(Object o,Object c){
Node newN = new Node();
Node help = new Node();
Node help2 = new Node();
newN.data = o;
help = head.next;
if(isEmpty()){
head = newN;
newN.next=head;
newN.prev=head;
}
else{
do{
help=help.next;
System.out.println(help);
}while(help.next!=head || !help.data.equals(c));
help2 = help.next;
newN.next = help2;
help2.prev = newN;
help.next=newN;
newN.prev=help;
}**
anyone could help?
thx a bunch!
What are the objects that you are comparing? if they are something other than string than you will have to override equals() method in order to get the correct comparison.
I think you should try another ending condition:
while(help.next!=head && !help.data.equals(c));
By the way, I can only advise you to avoid do...while without serious reasons, and to use getters and setters.
Your code should also be structured diffently. Why are you not writing a private method which just make the insert, i.e. your 5 last lines? Everything would be more readable and reusable.
Also, your variables need clear and meaningful names.
Do it yourself
I begun fixing your solution but ended writing a whole new implementation when wanting to test it... so here goes:
public class DoubleLinkedList<T> {
private class Node {
private Node prev;
private Node next;
private T data;
Node(T data) {
this.data = data;
}
}
Node head;
public boolean isEmpty() {
return head == null;
}
public void insertAfter(T afterThis, T objectToAdd) {
// cannot insert after in a empty list?!
if(isEmpty())
throw new NoSuchElementException("list is empty?");
// find the node where we want to insert the element
Node after = findNodeByObject(afterThis);
// create the node and update the links
addAfter(after, new Node(objectToAdd));
}
private void add(T objectToAdd) {
if (isEmpty()) {
head = new Node(objectToAdd);
head.next = head;
head.prev = head;
}
else {
addAfter(head.prev, new Node(objectToAdd));
}
}
private void addAfter(Node after, Node toAdd) {
Node afterAfter = after.next;
after.next = toAdd;
afterAfter.prev = toAdd;
toAdd.prev = after;
toAdd.next = afterAfter;
}
private Node findNodeByObject(T object) {
Node current = head;
while (true) {
if (current.data.equals(object))
return current;
if (current.next == head)
break;
current = current.next;
}
throw new NoSuchElementException("" + object);
}
#Override
public String toString() {
List<T> printList = new LinkedList<T>();
Node current = head;
while (true) {
printList.add(current.data);
if (current.next == head)
break;
current = current.next;
}
return printList.toString();
}
public static void main(String[] args) throws Exception {
DoubleLinkedList<String> list = new DoubleLinkedList<String>();
list.add("first");
list.add("third");
list.insertAfter("first", "second");
System.out.println(list);
}
}
Extend LinkedList
... and add the insertAfter method like this:
import java.util.LinkedList;
import java.util.ListIterator;
public class MyList<T> extends LinkedList<T> {
private void insertAfter(T first, T second) {
ListIterator<T> iterator = listIterator();
while (iterator.hasNext()) {
if (iterator.next().equals(first)) {
iterator.add(second);
return;
}
}
throw new IndexOutOfBoundsException("Could not find " + first);
}
public static void main(String[] args) throws Exception {
MyList<String> list = new MyList<String>();
list.add("first");
list.add("third");
list.insertAfter("first", "second");
System.out.println(list); // prints "[first, second, third]"
}
}