I have been working on a project where I must implement a java class that implements the use of doubly linked lists. I have the LinkedList class finished with all my methods. I'm just unsure how to actually add node objects into the list. Here is my code so far with test at the bottom. Any help would be appreciated. Thanks
public class LinkedList {
private Node first;
private Node current;
private Node last;
private int currentIndex;
private int numElements;
public LinkedList() {
this.first = null;
this.last = null;
this.numElements = 0;
this.current = null;
this.currentIndex = -1;
}
private class Node {
Node next;
Node previous;
Object data;
}
public boolean hasNext() {
return (current != null && current.next != null);
}
public Object next() {
if (!this.hasNext()) {
throw new IllegalStateException("No next");
}
current = current.next;
return current.data;
}
public boolean hasPrevious() {
return (current != null && current.previous != null);
}
public Object previous() {
if (!this.hasPrevious()) {
throw new IllegalStateException("No previous");
}
current = current.previous;
return current.data;
}
int nextIndex() {
int index = numElements;
if (hasNext()) {
index = this.currentIndex + 1;
}
System.out.println(index + "The current index is " + current);
return index;
}
int previousIndex() {
int index = -1;
if (hasPrevious()) {
index = this.currentIndex - 1;
}
System.out.println(index + "The current index is " + current);
return index;
}
public void set(Object o) {
if (this.current == null) {
throw new IllegalStateException("No node found, cannot set.");
}
current.data = o;
}
public int size() {
return numElements;
}
public void add(Object o) {
Node newNode = new Node();
newNode.data = o;
if (first == null) {
first = newNode;
last = newNode;
newNode.next = null;
} else if (first != null) {
if (current == null) {
newNode.previous = null;
newNode.next = first;
first.previous = newNode;
first = newNode;
} else if (current == last) {
newNode.previous = current;
newNode.next = null;
current.next = newNode;
last = newNode;
} else {
newNode.previous = current;
newNode.next = current.next;
current.next.previous = newNode;
current.next = newNode;
}
}
current = newNode;
numElements++;
currentIndex++;
}
public void remove() {
if (current != null) {
if (current == first && current == last) {
first = null;
last = null;
} else if (current == last) {
current.previous = null;
last = current.previous;
} else if (current == last) {
current.previous.next = null;
last = current.previous;
} else {
current.previous.next = current.next;
current.next.previous = current.previous;
}
current = current.next;
numElements--;
}
}
}
import java.util.Scanner;
public class LinkedListTest {
public static void main(String[] args) {
Scanner keyboard = new Scanner(System.in);
String name;
int index;
LinkedList<Object> listOne = new LinkedList<Object>();
listOne.add(object o);
}
}
The posted class LinkedList looks functional to me.
Make sure that your test code does not confuse this class and java.util.LinkedList, which Java provides for you (It's a part of the existing Collections framework).
For clarity, I would recommend renaming your class to something like MyLinkedList
The following code works and the output is "0","2":
public class MyLinkedListTest {
public static final void main(String[] args) {
MyLinkedList list = new MyLinkedList();
System.out.println("Number of items in the list: " + list.size());
String item1 = "foo";
String item2 = "bar";
list.add(item1);
list.add(item2);
System.out.println("Number of items in the list: " + list.size());
// and so on...
}
}
I'd be surprised if your code compiled, since your class isn't actually generic. Just initialize it as LinkedList listOne = new LinkedList(); (no angle brackets).
As to actually adding elements, you just need an instance of some Object to add; anything will do (assuming your internal code works properly). Try this down at the end there:
Object objectToAdd = "Strings are Objects";
listOne.add(objectToAdd);
objectToAdd = new File("C:\\foo.bar"); // Or use any other Objects!
listOne.add(objectToAdd);
Think of numbered list and look at the relations between the elements
Say I have the list:
A
B
C
What do I have to do to the relations get the list:
A
B
NewNode
C
The new next node of B is NewNode
The new previous node of C is NewNode. So an insert function would want to know the immediate previous node or the immediate next node and then adjust the relationships.
Your LinkedList doesn't have generic types so you can't declare it as
LinkedList<Object> listOne = new LinkedList<Object>();
but rather as
LinkedList listOne = new LinkedList();
And now to add elements just use your add method
listOne.add("something");
listOne.add(1);//int will be autoboxed to Integer objects
Also if you want to add data from keyboard you can use something like
String line="";
do{
System.out.println("type what you want to add to list:");
line = keyboard.nextLine();
listOne.add(line);
}while(!line.equals("exit"));
The line
LinkedList<Object> listOne = new LinkedList<Object>();
won't compile unless you change your class declaration to
class LinkedList<T>
or alternately you can just write
LinkedList listOne = new LinkedLis();
After that you should be able to add objects to your list. However, you'll need to create an Object to add to it, listOne.add(object o); won't do--at the very least you'll have to write listOne.add(new Object()). (Your code does not instantiate an Object, there is no Object that you already have called o, and besides, object o does not mean anything in Java and would not compile.
As people have mentioned your list is not generic. However as they advise you to get rid of the parameter, you can also just add <Object> or <E> to your linked list implementation and leave your initialization of the list as it is.
So in your linked list class you should do something like:
public class LinkedList<E>
This will make sure when you're using LinkedList<Object> listOne = new LinkedList<Object>();, E will be covnerted to Object
Let's improve your test a little bit so that it becomes apparent where your problems are (if any) I commented out the call to the current() method since you have not included one. (I would leave this alone as it may confuse you.) The general idea would be to add items to the linked list and walk forward and backward through it checking the items with each step.
public class LinkedListTest {
public static void main(String[] args) {
Scanner keyboard = new Scanner(System.in);
String name;
int index;
LinkedList listOne = new LinkedList();
//Initially we should be empty so we are positioned
// at both the beginning and end of the list
assert listOne.size() == 0 :"List should be empty";
assert listOne.hasPrevious()==false: "Should be at the beginning of the list";
assert listOne.hasNext()==false : "Should be at the end of the list";
Object firstNode = "I am the first node";
listOne.add(firstNode); //we've added something
//I left this commented out since you don't have a current() method.
// assert firstNode == listOne.current() : "Our current item should be what we just added";
assert listOne.hasPrevious()==false : "Should not have moved forward in our list yet";
assert listOne.hasNext()==true : "should have an item after our current";
assert listOne.size() == 1 : "Should only have one item in the list";
Object secondNode = "I am the second node";
listOne.add(secondNode);
assert listOne.size() == 2 : "Should only have two items in the list";
assert firstNode == listOne.next() : "1st call to next should return the 1st node";
assert listOne.hasPrevious()==true : "We should be positioned after the 1st node";
assert listOne.hasNext()==true : "We should be positioned before the 2nd node";
}
}
Related
So i got this one task to do, about LinkedList, you can take a look on my Main file, also got to mention that my "//The conditions" part is wrong and I just put something as an idea, but that's actually not really working
import java.util.*;
public class Main {
public static void main(String[] args){
ArrayList nokiaAL = new ArrayList();
LinkedList phoneAL = new LinkedList();
//input
Smartphone a = new Smartphone("Nokia","Nokia 7 Plus",1300,260101);
Smartphone b = new Smartphone("Samsung","Galaxy S8",900,220100);
Smartphone c = new Smartphone("Xiaomi","Mi 10",1500,150031);
Smartphone d = new Smartphone("Nokia","3310",250,101001);
Smartphone e = new Smartphone("Samsung","Galaxy Y",400,774101);
Smartphone f = new Smartphone("Apple","iPhone 7",1100,316300);
phoneAL.insertAtFront(f);
phoneAL.insertAtFront(e);
phoneAL.insertAtFront(d);
phoneAL.insertAtFront(c);
phoneAL.insertAtFront(b);
phoneAL.insertAtFront(a);
//process
Object r = (Object) phoneAL.getFirst();
while (r != null) {
System.out.print(" "+r);
r = (Object) phoneAL.getNext();
}
//The conditions
//If nokia + the price $1200+, it will save all the info about nokia
//If brand samsung + model Galaxy Y, It will count the total of the phone
Object obj;
int countSamsung = 0;
for(int i=0;i<phoneAL.size();i++){
obj = phoneAL.get(i);
Smartphone obj2 = (Smartphone) obj;
if(obj2.getBrand().equalsIgnoreCase("Nokia")){
nokiaAL.add(obj2);
}
if(obj2.getBrand().equalsIgnoreCase("Samsung")){
if(obj2.getModel().equalsIgnoreCase("Galaxy Y")){
countSamsung++;
}
}
}
//output
System.out.println("\n");
System.out.println("Details about Nokia phone more than RM1200:"+nokiaAL.toString());
System.out.println("Quantity of Samsung model Galaxy Y: " + countSamsung);
}
}
I know how to print all the details in the LinkedList, the main point here is, you can't add or change anything of other .java files, you can only edit the Main.java file, is it even possible? here's my Smartphone and LinkedList code.
public class Smartphone {
String brand;//e.g: Nokia, Samsung
String model;//e.g: Lumia, Galaxy Y, Note S
double price;
int warranty;//warranty (in year)
Smartphone() {
}
public Smartphone(String a, String b, double c, int d){
this.brand=a;
this.model=b;
this.price=c;
this.warranty=d;
}
public String getBrand(){
return brand;
}
public String getModel(){
return model;
}
public double getPrice(){
return price;
}
public int getWarranty(){
return warranty;
}
public String toString(){
return "\n\nBrand: "+brand +"\nModel: "+ model +"\nPrice: $"+ price +"\nWarranty: "+ warranty;
}
}
public class LinkedList
{
private Node first;
private Node last;
private Node current;
public LinkedList()
{
first = null;
last = null;
current = null;
}
public boolean isEmpty(){
return (first == null); }
public void insertAtFront(Object insertItem){
Node newNode = new Node(insertItem);
if (isEmpty()){
first = newNode;
last = newNode;
}else{
newNode.next = first;
first = newNode;
}
}
public void insertAtBack(Object insertItem){
Node newNode = new Node(insertItem);
if(isEmpty()){
first = newNode;
last = newNode;
}else{
last.next = newNode;
last = newNode;
}
}
public Object removeFromFront(){
Object removeItem = null;
if(isEmpty()){
return removeItem;
}
removeItem = first.data;
if(first == last){
first = null;
last = null;
}else
first = first.next;
return removeItem;
}
public Object removeFromBack(){
Object removeItem = null;
if(isEmpty())
{
return removeItem;
}
removeItem = last.data;
if (first == last)
{
first = null;
last = null;
}else{
current = first;
while(current.next != last)
current = current.next;
last = current;
last.next = null;
}
return removeItem;
}
public Object getFirst(){
if(isEmpty())
return null;
else
{
current = first;
return current.data;
}
}
public Object getNext(){
if(current == last)
return null;
else
{
current = current.next;
return current.data;
}
}
}
As I said before, I can print all the details of the phones, but how to really use it as conditions, like If-else statement? for example, if(obj.getBrand().equalsIgnoreCase("Nokia")){} , I can achieve this with ArrayList but since this is LinkedList task, So I'm still figuring this out without even know if its possible or not. I hope someone would understand this and able to help. TQ
here's my node code for the LinkedList
public class Node {
Object data;
Node next;
Node(Object obj){
data=obj;
}
}
You should iterate using while and validating if the list has ended.
Diferently from an ArrayList, that you can directly acess the vector positions, in a linked list you should walk from node to node. Also, in your example you only implement a getNext() method and not a get(i).
Example:
Object aux = linkedList.getFirst();
while(aux != null) {
// your business logic here
aux = linkedList.getNext();
}
As you dont make the use of generics in your implementation, to acess your object data, you will need to use cast or make use of generics in your implementation.
Cast way:
while(aux != null) {
phoneObject = (Smartphone) aux;
// your business logic here
if(phoneObject.getBrand().equalsIgnoreCase("Nokia")){
System.out.println("Phone brand == Nokia");
}
aux = linkedList.getNext();
}
In the generic approach, you will also need to change the LinkedList implementation and Node implementation.
LinkedList:
public class LinkedList<T>
{
private Node<T> first;
private Node<T> last;
private Node<T> current;
public T getFirst(){
if(isEmpty())
return null;
else
{
current = first;
return current.data;
}
}
public T getNext(){
if(current == last)
return null;
else
{
current = current.next;
return current.data;
}
}
// add other methods here
}
Node:
public class Node<T> {
T data;
Node<T> next;
// add other methods here
}
Main:
LinkedList<Smartphone> linkedList = new LinkedList<Smartphone>();
// add objects
Smartphone aux = linkedList.getFirst();
while(aux != null) {
// no need to cast, because of generics use
if(aux.getBrand().equalsIgnoreCase("Nokia")){
System.out.println("Phone brand == Nokia");
}
// your business logic here
aux = linkedList.getNext();
}
Your getNext() method, returns null if your list has ended, so our stop criteria is aux == null. Our loop will execute while aux is not null, execute all your business logic (if clauses or what ever validation you want to do) and in the end of the loop, you will set the next object to aux variable.
You should add a generic parameter to your LinkedList.
class LinkedList<T> {
private Node<T> first;
private Node<T> last;
private Node<T> current;
....
}
class Node<T> {
T data;
Node<T> next;
Node(T obj) {
data = obj;
}
}
Then you can only add objects of that type to your list.
LinkedList<Smartphone> phoneList = new LinkedList<>();
But of course, if you can you really should not implement LinkedList by yourself but use the existing one! That's far more easier and safer to use.
List<Smartphone> nokiaList = new ArrayList<>();
List<Smartphone> phoneList = new LinkedList<>();
//input
phoneList.add(new Smartphone("Nokia", "Nokia 7 Plus", 1300, 260101));
phoneList.add(new Smartphone("Samsung", "Galaxy S8", 900, 220100));
phoneList.add(new Smartphone("Xiaomi", "Mi 10", 1500, 150031));
phoneList.add(new Smartphone("Nokia", "3310", 250, 101001));
phoneList.add(new Smartphone("Samsung", "Galaxy Y", 400, 774101));
phoneList.add(new Smartphone("Apple", "iPhone 7", 1100, 316300));
//The conditions
//If nokia + the price $1200+, it will save all the info about nokia
//If brand samsung + model Galaxy Y, It will count the total of the phone
Object obj;
int countSamsung = 0;
for (int i = 0; i < phoneList.size(); i++) {
Smartphone phone = phoneList.get(i);
if (phone.getBrand().equalsIgnoreCase("Nokia")) {
nokiaList.add(phone);
}
if (phone.getBrand().equalsIgnoreCase("Samsung")) {
if (phone.getModel().equalsIgnoreCase("Galaxy Y")) {
countSamsung++;
}
}
}
I have an assignment that goes:
implement a linked list of String objects by use of the class Node (see Big >Java Early Objects 16.1.1). Write methods, that make it possible to insert >and delete objects, as well as print all objects in the list. It is a >requirement that all elements in the list are sorted, at all times, according >to the natural ordering of Strings(Comparable).
The method that I can't seem to get right, is the addElement method
The entire class is here: https://pastebin.com/Swwn8ykZ
And the mainApp: https://pastebin.com/A22MFDQk
I've looked through the book (Big Java Early Objects), as well as looked on geeksforgeeks
public void addElement(String e) {
Node newNode = new Node();
if (first.data == null) {
first.data = e;
System.out.println("Success! " + e + " has been
added!");
} else if (first.data.compareTo(e) == 0) {
System.out.println("The element already exists in the
list");
} else {
while (first.next != null) {
if (first.next.data.compareTo(e) != 0) {
first.next.data = e;
} else {
first.next = first.next.next;
}
}
}
}
public static void main(String[] args) {
SortedLinkedList list = new SortedLinkedList();
String e1 = new String("albert");
String e2 = new String("david");
String e3 = new String("george");
String e4 = new String("jannick");
String e5 = new String("michael");
// ----------------SINGLE LIST--------------------------
list.addElement(e1);
list.addElement(e2);
list.addElement(e3);
list.addElement(e4);
list.addElement(e5);
System.out.println("Should print elements after this:");
list.udskrivElements();
}
}
Expected result: The five names printed in a list
Actual result: The first name printed
Given this Node class:
private class Node {
public String data;
public Node next;
}
and a class-level field of private Node first; that is initially null to signal an empty list,
the addElement could be like this:
public void addElement(String text) {
if (text == null) return; // don't store null values
Node extra = new Node();
extra.data = text;
if (first == null) {
// no list yet, so create first element
first = extra;
} else {
Node prev = null; // the "previous" node
Node curr = first; // the "current" node
while (curr != null && curr.data.compareTo(text) < 0) {
prev = curr;
curr = curr.next;
}
if (curr == null) {
// went past end of list, so append
prev.next = extra;
} else if (curr.data.compareTo(text) == 0) {
System.out.println("Already have a " + text);
} else {
// between prev and curr, or before the start
extra.next = curr;
if (prev != null) {
prev.next = extra;
} else {
// append before start, so 'first' changes
first = extra;
}
}
}
}
By the way, also try and add the names in an unsorted order to check that the list sorts them (I found a bug in my code when I tried that).
I'm working on an assignment for my Data Structures class. We have to create an address book using our own sorted linked based list adt. Right now the add method works, but it seems to make all the nodes point to the first node. Whenever I try to output the the list using getEntry() in a for loop, it gives me the last added entry each time. I've tried using toArray but it does the same thing. Can you see any problems?
public class GTSortedLinkedBasedList implements GTListADTInterface {
private Node firstNode;
private int numberOfEntries;
public GTSortedLinkedBasedList(){
//firstNode = new Node(null);
numberOfEntries = 0;
}
public void setNumberOfEntries(int x){
numberOfEntries = x;
}
public void add(ExtPersonType newEntry){
//firstNode = null;
Node newNode = new Node(newEntry);
Node nodeBefore = getNodeBefore(newEntry);
if (isEmpty() || (nodeBefore == null))
{
// Add at beginning
newNode.setNextNode(firstNode);
firstNode = newNode;
}
else
{
// Add after nodeBefore
Node nodeAfter = nodeBefore.getNextNode();
newNode.setNextNode(nodeAfter);
nodeBefore.setNextNode(newNode);
} // end if
numberOfEntries++;
}
private Node getNodeBefore(ExtPersonType anEntry){
Node currentNode = getFirstNode();
Node nodeBefore = null;
while ((currentNode != null) &&
(anEntry.getFirstName().compareTo(currentNode.getData().getFirstName()) > 0))
{
nodeBefore = currentNode;
currentNode = currentNode.getNextNode();
} // end while
return nodeBefore;
}
private class Node {
private ExtPersonType data;
private Node next;
public Node(ExtPersonType dataValue) {
next = null;
data = dataValue;
}
public Node(ExtPersonType dataValue, Node nextValue) {
next = nextValue;
data = dataValue;
}
public ExtPersonType getData(){
return data;
}
public void setData(ExtPersonType newData){
data = newData;
}
public Node getNextNode(){
return next;
}
public void setNextNode(Node newNode){
next = newNode;
}
}
public ExtPersonType getEntry(int givenPosition) {
if ((givenPosition >= 1) && (givenPosition <= numberOfEntries)){
assert !isEmpty();
return getNodeAt(givenPosition).getData();
}
else{
throw new IndexOutOfBoundsException("Illegal position given to getEntry operation.");
}
}
public void loadData(GTSortedLinkedBasedList contacts) throws FileNotFoundException{
//int index = 0;
ExtPersonType person = new ExtPersonType();
DateType tempDate = new DateType();
AddressType tempAddress = new AddressType();
Scanner file = new Scanner(new FileInputStream("Programming Assignment 1 Data.txt"));
while(file.hasNext()){
person.setFirstName(file.next());
person.setLastName(file.next());
tempDate.setMonth(file.nextInt());
tempDate.setDay(file.nextInt());
tempDate.setYear(file.nextInt());
person.setDOB(tempDate);
tempAddress.setStreetAddress(file.nextLine());
if(tempAddress.getStreetAddress().isEmpty()){
tempAddress.setStreetAddress(file.nextLine());
}
tempAddress.setCity(file.nextLine());
tempAddress.setState(file.nextLine());
tempAddress.setZipCode(file.nextLine());
person.setAddress(tempAddress);
person.setPhoneNumber(file.nextLine());
person.setPersonStatus(file.nextLine());
if(person.getPersonStatus().isEmpty()){
person.setPersonStatus(file.nextLine());
}
contacts.add(person);
System.out.println(contacts.getEntry(contacts.getLength()).getFirstName());
//index++;
}
}
public static void main(String[] args) throws FileNotFoundException {
AddressBook ab = new AddressBook();
ab.loadData(ab);
ExtPersonType people = new ExtPersonType();
//people = ab.toArray(people);
System.out.println(ab.getLength());
for(int cnt = 1; cnt <= ab.getLength(); cnt++){
people = ab.getEntry(cnt);
System.out.println(people.getFirstName());
}
}
EDIT: The add method is overwriting each previous object with the newly added one. It also doesn't seem to matter if I do a sorted list or just a basic list.
I'm not going to lie here, I'm not totally sure I understand your code but I think I see what's wrong. In your getNodeBefore() method's code, you set currentNode() always to firstNode(). I believe that is causing the problem. I see that you are trying to recursively move through the list to find the proper node but I don't think each recursive call is causing movement through the list. I suggest you add properties to the object that represent the forward and backward nodes.
Something like this...
private T data;
private Node nodeBefore;
private Node nodeAfter;
As you create objects, you assign the properties before and after and then all the information you need is contained in the object itself.
To move recursively through the list you would then just add a statement like currentNode = currentNode.nodeAfter.
Your getNodeBefore() method would simply return currentNode.nodeBefore and getNodeAfter() would return currentNode.nodeAfter.
You don't have code that handles the situation where the node being added will be the first node in the list, but the list is also not empty. In this case, getNodeBefore returns null, and your code overwrites the root node.
Try
if (isEmpty() && (nodeBefore == null))
{
// Add at beginning
newNode.setNextNode(firstNode);
firstNode = newNode;
}
else if(nodeBefore == null)
{
Node temp = new Node();
temp.setNextNode(first.next);
temp.setData(first.data);
newNode.setNextNode(temp);
firstNode = newNode;
}
I am trying to make a method to merge two linked lists for a homework assignment in my programming class. I'm really confused here, the method has to have this method signature:
public UnorderedLinkedListInt merge2(UnorderedLinkedListInt list), so in my tester method it will look like this list3 = list1.merge2(list2). I'm confused on how to make this when the method only takes in one list and not both. Here is my code so far
public class UnorderedLinkedListInt extends LinkedListIntClass {
//Default constructor
public UnorderedLinkedListInt() {
super();
}
public boolean search(int searchItem) {
LinkedListNode current; //variable to traverse the list
current = first;
while (current != null)
if (current.info == searchItem)
return true;
else
current = current.link;
return false;
}
public void insertFirst(int newItem) {
LinkedListNode newNode; //variable to create the new node
//create and insert newNode before first
newNode = new LinkedListNode(newItem, first);
first = newNode;
if (last == null)
last = newNode;
count++;
}
public void insertLast(int newItem) {
LinkedListNode newNode; //variable to create the new node
//create newNode
newNode = new LinkedListNode(newItem, null);
if (first == null) {
first = newNode;
last = newNode;
}
else {
last.link = newNode;
last = newNode;
}
count++;
}
public void deleteNode(int deleteItem) {
LinkedListNode current; //variable to traverse the list
LinkedListNode trailCurrent; //variable just before current
boolean found;
//Case 1; the list is empty
if ( first == null)
System.err.println("Cannot delete from an empty list.");
else {
//Case 2: the node to be deleted is first
if (first.info == deleteItem) {
first = first.link;
if (first == null) //the list had only one node
last = null;
count--;
}
else { //search the list for the given info
found = false;
trailCurrent = first; //trailCurrent points to first node
current = first.link; //current points to second node
while (current != null && !found) {
if (current.info == deleteItem)
found = true;
else {
trailCurrent = current;
current = current.link;
}
}
//Case 3; if found, delete the node
if (found) {
count--;
trailCurrent.link = current.link;
if (last == current) //node to be deleted was the last node
last = trailCurrent;
}
else
System.out.println("Item to be deleted is not in the list.");
}
}
}
public void merge(UnorderedLinkedListInt list2){
UnorderedLinkedListInt list1 = this;
while (list2.first != null) {//while more data to print
list1.insertLast(list2.first.info);
list2.first = list2.first.link;
}
}
public UnorderedLinkedListInt merge2(UnorderedLinkedListInt list2){
UnorderedLinkedListInt list3 = new UnorderedLinkedListInt();
UnorderedLinkedListInt list1 = this;
while (list1.first != null) {//while more data to print
list3.insertLast(list1.first.info);
list1.first = list1.first.link;
}
while (list2.first != null) {//while more data to print
list3.insertLast(list2.first.info);
list2.first = list2.first.link;
}
return list3;
}
}
I'm still having some trouble understanding exactly how linked lists work, any suggestions as to how to design this method would be greatly appreciated.
In a method call like list1.merge2(list2), the method receives list1 as the implicit "current object" that you can access with the this reference.
If you want to you can use another name for it:
public UnorderedLinkedListInt merge2(UnorderedLinkedListInt list2){
UnorderedLinkedListInt list1 = this;
// now merge list1 and list2
}
Your first list would be actual Object pointed to by the this reference.
Try this:
import java.io.*;
class Node1
{
int data;
Node1 link;
public Node1()
{
data=0;
link=null;
}
Node1 ptr,start,temp,ptr1;
void create()throws IOException
{
int n;
BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
System.out.println("Enter first data");
this.data=Integer.parseInt(br.readLine());
ptr=this;
start=ptr;
char ins ='y';
do
{
System.out.println("Wanna Insert another node???");
ins=(char)br.read();
br.read();
if(ins=='y')
{
temp=new Node1();
System.out.println("Enter next data");
temp.data=Integer.parseInt(br.readLine());
temp.link=null;
ptr.link=temp;
temp=null;
ptr=ptr.link;
}
}while(ins=='y');
}
void merge()throws IOException
{
ptr1=this;
ptr=this;
Node1 t=new Node1();
t.create();
while(ptr1.link!=null)
{ ptr1=ptr1.link;}
ptr1.link=t.start;
ptr1=t=null;
System.out.println("---------------------------");
System.out.println("Merged LL :\n");
while(ptr!=null)
{
System.out.print("-->"+ptr.data);
ptr=ptr.link;
}
}
}
I was trying to reverse a linked list using recursion. I got the solution, but can't get it to work for below question found on internet.
Reverse a linked list using recursion but function should have void
return type.
I was able to implement the function with return type as Node. Below is my solution.
public static Node recursive(Node start) {
// exit condition
if(start == null || start.next == null)
return start;
Node remainingNode = recursive(start.next);
Node current = remainingNode;
while(current.next != null)
current = current.next;
current.next = start;
start.next = null;
return remainingNode;
}
I cannot imagine if there will be such a solution to this problem.
Any suggestions ?
Tested, it works (assuming you have your own implementation of a linked list with Nodes that know the next node).
public static void reverse(Node previous, Node current) {
//if there is next node...
if (current.next != null) {
//...go forth and pwn
reverse(current, current.next);
}
if (previous == null) {
// this was the start node
current.next= null;
} else {
//reverse
current.next= previous;
}
}
You call it with
reverse(null, startNode);
public void recursiveDisplay(Link current){
if(current== null)
return ;
recursiveDisplay(current.next);
current.display();
}
static StringBuilder reverseStr = new StringBuilder();
public static void main(String args[]) {
String str = "9876543210";
reverse(str, str.length() - 1);
}
public static void reverse(String str, int index) {
if (index < 0) {
System.out.println(reverseStr.toString());
} else {
reverseStr.append(str.charAt(index));
reverse(str, index - 1);
index--;
}
}
This should work
static void reverse(List list, int p) {
if (p == list.size() / 2) {
return;
}
Object o1 = list.get(p);
Object o2 = list.get(list.size() - p - 1);
list.set(p, o2);
list.set(list.size() - p - 1, o1);
reverse(list, p + 1);
}
though to be efficient with LinkedList it should be refactored to use ListIterator
I am not familiar with Java, but here is a C++ version. After reversing the list, the head of list is still preserved, which means that the list can still be accessible from the old list head List* h.
void reverse(List* h) {
if (!h || !h->next) {
return;
}
if (!h->next->next) {
swap(h->value, h->next->value);
return;
}
auto next_of_next = h->next->next;
auto new_head = h->next;
reverse(h->next);
swap(h->value, new_head->value);
next_of_next->next = new_head;
h->next = new_head->next;
new_head->next = nullptr;
}
Try this code instead - it actually works
public static ListElement reverseListConstantStorage(ListElement head) {
return reverse(null,head);
}
private static ListElement reverse(ListElement previous, ListElement current) {
ListElement newHead = null;
if (current.getNext() != null) {
newHead = reverse(current, current.getNext());
} else {//end of the list
newHead=current;
newHead.setNext(previous);
}
current.setNext(previous);
return newHead;
}
public static Node recurse2(Node node){
Node head =null;
if(node.next == null) return node;
Node previous=node, current = node.next;
head = recurse2(node.next);
current.next = previous;
previous.next = null;
return head;
}
While calling the function assign the return value as below:
list.head=recurse2(list.head);
The function below is based on the chosen answer from darijan, all I did is adding 2 lines of code so that it'd fit in the code you guys want to work:
public void reverse(Node previous, Node current) {
//if there is next node...
if (current.next != null) {
//...go forth and pwn
reverse(current, current.next);
}
else this.head = current;/*end of the list <-- This line alone would be the fix
since you will now have the former tail of the Linked List set as the new head*/
if (previous == null) {
// this was the start node
current.next= null;
this.tail = current; /*No need for that one if you're not using a Node in
your class to represent the last Node in the given list*/
} else {
//reverse
current.next= previous;
}
}
Also, I've changed it to a non static function so then the way to use it would be: myLinkedList.reverse(null, myLinkedList.head);
Here is my version - void ReverseWithRecursion(Node currentNode)
- It is method of LinkListDemo Class so head is accessible
Base Case - If Node is null, then do nothing and return.
If Node->Next is null, "Make it head" and return.
Other Case - Reverse the Next of currentNode.
public void ReverseWithRecursion(Node currentNode){
if(currentNode == null) return;
if(currentNode.next == null) {head = currentNode; return;}
Node first = currentNode;
Node rest = currentNode.next;
RevereseWithRecursion(rest);
first.next.next = first;
first.next = null;
}
You Call it like this -
LinkListDemo ll = new LinkListDemo(); // assueme class is available
ll.insert(1); // Assume method is available
ll.insert(2);
ll.insert(3);
ll.ReverseWithRecursion(ll.head);
Given that you have a Node class as below:
public class Node
{
public int data;
public Node next;
public Node(int d) //constructor.
{
data = d;
next = null;
}
}
And a linkedList class where you have declared a head node, so that it can be accessed by the methods that you create inside LinkedList class. The method 'ReverseLinkedList' takes a Node as an argument and reverses the ll.
You may do a dry run of the code by considering 1->2 as the linkedList. Where node = 1, node.next = 2.
public class LinkedList
{
public Node? head; //head of list
public LinkedList()
{
head = null;
}
public void ReverseLinkedList(Node node)
{
if(node==null)
{
return;
}
if(node.next==null)
{
head = node;
return;
}
ReverseLinkedList(node.next); // node.next = rest of the linkedList
node.next.next = node; // consider node as the first part of linkedList
node.next = null;
}
}
The simplest method that I can think of it's:
public static <T> void reverse( LinkedList<T> list )
{
if (list.size() <= 1) {
return;
}
T first = list.removeFirst();
reverse( list);
list.addLast( first );
}