This is the code I was given for the Singly Linked List, however I am struggling on completing the Reverse function. This was the code and my attempt at the reverse function. I keep getting 2 errors that say "Undeclared variable: node" and "imcompatible types: Node cannot be converted to Linkedlist".
class LinkedList
{
Node head;
Node current;
Node previous;
public Object Get()
{
return current != null ? current.GetData() : null;
}
public void Next()
{
if (current != null)
{
previous = current;
current = current.next;
}
}
public void Head()
{
previous = null;
current = head;
}
public void Insert(Object data)
{
Node node = new Node(data);
node.next = current;
if (current == head)
head = node;
else
previous.next = node;
current = node;
}
public void Remove()
{
if (current == null)
throw new RuntimeException("Invalid position to remove");
if (current == head)
head = current.next;
else
previous.next = current.next;
current = current.next;
}
public void Print()
{
for (Head(); Get() != null; Next())
System.out.println(Get());
}
public LinkedList Reverse()
{
Node previous = null;
Node current = node;
Node forward;
while (current != null)
{
forward = current.next;
current.next = previous;
previous = current;
current = forward;
}
return previous;
}
}
There is also class Node:
class Node
{
// Public reference to next node
public Node next;
// Private data field
Object data;
Node(Object data)
{
this.data = data;
}
public Object GetData()
{
return data;
}
}
And this is the main function:
class Test
{
public static void main(String args[])
{
// creating a singly linked list
LinkedList linked_list = new LinkedList();
// adding node into singly linked list
linked_list.Insert(Integer.valueOf(10));
linked_list.Next();
linked_list.Insert(Integer.valueOf(11));
linked_list.Next();
linked_list.Insert(Integer.valueOf(12));
// printing a singly linked
linked_list.Print();
// reversing the singly linked list
linked_list.Reverse();
// printing the singly linked list again
linked_list.Print();
}
}
Here is a simple solution:
public class ListReverser {
public static Node<Integer> reverse(Node head) {
Node current = head;
while(current.getNext() != null) {
Node next = current.getNext();
current.setNext(next.getNext());
next.setNext(head);
head = next;
}
return head;
}
}
Related
I am trying to write a simple linked list class that uses generic data type. I am new to Java so I can't figure out how to debug the error message in the main method that arises when I try to insert data into an instance of my class. The class code and the main method are as follows:
import java.io.*;
// Java program to implement
// a Singly Linked List
public class MyLinkedList<T> {
Node head; // head of the list
class Node<T> {
T data;
Node next;
// Constructor
Node(T d)
{
data = d;
next = null;
}
}
// Method to insert a new node
MyLinkedList insert(MyLinkedList list, T data)
{
// Create a new node with given data
Node new_node = new Node(data);
new_node.next = null;
// If the Linked List is empty,
// then make the new node as head
if (list.head == null) {
list.head = new_node;
}
else {
// Else traverse till the last node
// and insert the new_node there
Node last = list.head;
while (last.next != null) {
last = last.next;
}
// Insert the new_node at last node
last.next = new_node;
}
// Return the list by head
return list;
}
// Driver code
public static void main(String[] args)
{
/* Start with the empty list. */
MyLinkedList list = new MyLinkedList();
// Insert the values
list = insert(list, 1);
}
}
You need to change int to T in class declaration and method signature.
class MyLinkedList<T> {
MyLinkedList() {
head=null;
}
Node head; // head of list
class Node<T> {
T data;
Node next;
// Constructor
Node(T d) {
data = d;
next = null;
}
}
// Method to insert a new node
public void insert(T data) {
// Create a new node with given data
Node new_node = new Node(data);
new_node.next = null;
// If the Linked List is empty,
// then make the new node as head
if (this.head == null) {
this.head = new_node;
} else {
Node last = this.head;
while (last.next != null) {
last = last.next;
}
// Insert the new_node at last node
last.next = new_node;
}
}
protected void display() {
Node myNode=head;
System.out.println();
while (myNode != null) {
System.out.println(myNode.data);
myNode=myNode.next;
}
}
Change the insert method signature to the below:
public static void main(String[] args) {
/* Start with the empty list. */
MyLinkedList<Integer> list = new MyLinkedList<Integer>();
// Insert the values
list.insert(1);
list.insert(3);
list.insert(12);
list.insert(11);
list.insert(21);
list.insert(22);
list.insert(45);
list.display();
}
For clear coding and understanding I have changed class name as MyLinkedList
When I try to implement a method to remove duplicates, it returns the linked list with the duplicates still in. I'm not sure if it is a problem of variable assignment or potentially the show() method that I have created.
https://www.dropbox.com/s/2cjj4nb4v8i5fg9/RemoveDuplicates.zip?dl=0
public class LinkedList {
LinkedListNode head;
//generating add method to
public void add(int data) {
LinkedListNode newNode = new LinkedListNode();
newNode.data = data;
newNode.next = null;
if (head == null) {
head = newNode;
}
else {
LinkedListNode current = head;
while(current.next != null) {
current = current.next;
}
current.next = newNode;
}
}
public void show() {
LinkedListNode newNode = head;
while(newNode.next != null) {
System.out.println(newNode.data);
newNode = newNode.next;
}
System.out.println(newNode.data);
}
}
public class Test {
public static void main(String[] args) {
LinkedListNode head = new LinkedListNode();
//12 and 5 are duplicates
LinkedList list = new LinkedList();
list.add(5);
list.add(45);
list.add(12);
list.add(12);
list.add(5);
list.add(33);
list.add(12);
list.add(45);
list.show();
removeDuplicates(head);
list.show();
}
public static void removeDuplicates(LinkedListNode head) {
LinkedListNode current = head;
LinkedListNode runner = null;
while (current != null) {
runner = current;
while (runner.next != null) {
if (runner.next.data == current.data) {
runner.next = runner.next.next;
}
else {
runner = runner.next;
}
}
current = current.next;
}
}
}
The head in your main method is not the same one as the head inside your linked list.
The head in your main method is always empty and you are not modifying list at all.
The method not working:
public void insert_before_node(Node givenNode, int data) {
Node newNode = new Node(data);
newNode.prev = givenNode.prev;
givenNode.prev = newNode;
newNode.next = givenNode;
if(newNode.prev != null)
newNode.prev.next = newNode;
}
Another add method which is working:
public void insert_front(int data) {
Node newNode = new Node(data);
newNode.next = head;
newNode.prev = null;
if(head != null)
head.prev = newNode;
head = newNode;
}
A print method to debug:
public void print() {
Node n = head;
while(n != null){
System.out.println(n.data);
n = n.next;
}
}
DoublyLinkedList class:
public class DoublyLinkedList {
static class Node {
int data;
Node next;
Node prev;
Node(int data) {
this.data = data;
this.next = null;
this.prev = null;
}
}
Node head;
DoublyLinkedList() {
this.head = null;
}
public static void main(String[] args) {
DoublyLinkedList ll = new DoublyLinkedList();
ll.insert_front(0);
ll.insert_before_node(ll.head, 100);
ll.print();
}
}
LinkedList and Node implementations are very straightforward. Find here: https://www.geeksforgeeks.org/doubly-linked-list/
I first create a linkedlist, insert_front() a value to make the head not null, then use the method above to insert something else. Insertion to front, end, after a node are working, however, this insert_before_node() is not working. What I have inserted with this method is not appears on my print.
I draw on a paper too, still couldn't find the problem.
The geeksforgeeks link also has no java implementation for this method.
Your code is working, apart from the assignment of head in insert_front(Node,int) method, I think you forgot this. before that.
Plus, maybe you would need to
remove the head argument in insert_front method (it's the head of the dll, it has a class member for that),
remove the underscores (not Java good practice, Sonar would complain)
return the nodes you create so you can later reference them (and possibly create a fluent API)
A basic rework would look like this MVP:
import java.util.Objects;
public class DoubleLinkLists {
public static void main(String[] args) {
DoubleLinkedList dll = new DoubleLinkedList();
DoubleLinkedList.Node node5 = dll.insertInFront(5);
DoubleLinkedList.Node node4 = dll.insertInFront(4);
DoubleLinkedList.Node node2 = dll.insertInFront(2);
DoubleLinkedList.Node node1 = dll.insertInFront(1);
DoubleLinkedList.Node node3 = dll.insertBefore(node4, 3);
System.out.println(dll);
}
public static class DoubleLinkedList {
Node head;
#Override
public String toString() {
Node current = head;
StringBuilder sb = new StringBuilder();
while (current != null) {
sb.append(current.data)
.append(" ");
current = current.next;
}
return sb.toString();
}
public Node insertBefore(Node givenNode, int data) {
Node newNode = new Node(data);
newNode.prev = givenNode.prev;
givenNode.prev = newNode;
newNode.next = givenNode;
if (newNode.prev != null) {
newNode.prev.next = newNode;
}
return newNode;
}
public Node insertInFront(int data) {
Node newNode = new Node(data);
newNode.next = head;
newNode.prev = null;
if (head != null) {
head.prev = newNode;
}
head = newNode;
return newNode;
}
public static class Node {
int data;
Node prev;
Node next;
Node(int d) {
data = d;
}
#Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Node node = (Node) o;
return data == node.data;
}
#Override
public int hashCode() {
return Objects.hash(data);
}
}
}
}
I edit the code for more readable.
public void insert_before_node(Node next, int data) {
Node newNode = new Node(data);
Node prev = next.prev;
//left to right
prev.next = newNode;
newNode.next = next;
//traverse right to left
next.prev = newNode;
newNode.prev = prev;
}
I assume the next and prev is also not null.
By the way, you should add more condition to detect null(next and prev) in insert_before_node.
Please update the result and hope it help.
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
}
I'm trying to define a recursive method that removes all instances in the singly-linked list that are equal to the target value. I defined a remove method and an accompanying removeAux method. How can I change this so that if the head needs to be removed, the head is reassigned as well? Here is what I have so far:
public class LinkedList<T extends Comparable<T>> {
private class Node {
private T data;
private Node next;
private Node(T data) {
this.data = data;
next = null;
}
}
private Node head;
public LinkedList() {
head = null;
}
public void remove(T target) {
if (head == null) {
return;
}
while (target.compareTo(head.data) == 0) {
head = head.next;
}
removeAux(target, head, null);
}
public void removeAux(T target, Node current, Node previous) {
if (target.compareTo(current.data) == 0) {
if (previous == null) {
head = current.next;
} else {
previous.next = current.next;
}
current = current.next;
removeAux(target, current, previous); // previous doesn't change
} else {
removeAux(target, current.next, current);
}
}
I prefer to pass a reference to the previous when you remove to switch previous to the next something like this
public void remove(T target){
removeAux(target,head, null);
}
public void removeAux(T target, Node current, Node previous) {
//case base
if(current == null)
return;
if (target.compareTo(current.data) == 0) {
if (previous == null) {
// is the head
head = current.next;
} else {
//is not the head
previous.next = current.next;
}
current = current.next;
removeAux(target, current, previous); // previous doesn't change
} else {
removeAux(target, current.next, current);
}
}
Check this answer graphically linked list may help you to think how to implement it.
If this for training is good but you can do in iterative way.
You could try to fashion your function so that it works like this.
head = removeAux(target, head); // returns new head
A neat trick I learn't from Coursera's Algorithms classes.
The rest of the code is as follows.
public void removeAux(T target, Node current) {
//case base
if(current == null)
return null;
current.next = removeAux(target, current.next);
return target.compareTo(current.data) == 0? current.next: current; // the actual deleting happens here
}