Trouble printing reversed linked list (java) - java

Basically, I have created methods that print a linked list of integers, delete duplicates from the linked list, as well as invert the linked list. Everything works fine...almost.For some reason, I cannot get my printLinked() method to work after the list has been inverted. For the time being, I just created a while loop to output the reversed list so that I can at least be sure that the list is being reversed. I need to have the printLinked() method do this, though. If anyone can help me out or point me in the right direction in terms of figuring out what the problem is, then I would appreciate it much.
Thank you.
import java.util.Scanner;
public class ListTest
{
public static void main (String[] args)
{
ListNode head = new ListNode();
ListNode tail = head;
tail.link = null;
int input;
Scanner keyboard = new Scanner (System.in);
System.out.println("Enter integers into list; end by entering a zero");
input = keyboard.nextInt();
ListNode temp;
while (input != 0)
{
temp = new ListNode();
temp.data = input;
temp.link = null;
tail.link = temp;
tail = temp;
input = keyboard.nextInt();
}
System.out.println("You entered the following integers : ");
printLinked(head.link);
delrep(head);
System.out.println("After deleting repeating integers, you are left with : ");
printLinked(head.link);
System.out.println("Your inverted list of integers is now : ");
invert(head);
printLinked(head.link);
}
public static void printLinked(ListNode list)
{
ListNode cursor = list;
while (cursor != null)
{
System.out.print(cursor.data + " ");
cursor = cursor.link;
}
System.out.println("");
}
public static void delrep(ListNode head)
{
ListNode temp = new ListNode();
while(head != null)
{
temp = head;
while(temp.link != null)
{
if(head.data == temp.link.data)
{
ListNode temp2 = new ListNode();
temp2 = temp.link;
temp.link = temp2.link;
temp2 = null;
}
else
{
temp = temp.link;
}
}
head = head.link;
}
}
public static void invert(ListNode head)
{
ListNode temp1 = null;
ListNode temp2 = null;
while (head != null)
{
temp1 = head.link;
head.link = temp2;
temp2 = head;
head = temp1;
}
head = temp2;
//This portion of code needs to be removed. I added this part just so I can visually
//confirm that the list is reversing until I can get the print method to work for the
// reversed list.
while (head.link != null)
{
System.out.print(head.data + " ");
head = head.link;
}
System.out.println("");
}
}
also, this is what my ListNode class is:
public class ListNode
{
public int data;
public ListNode link;
}

You need to return the new head of the list at your invert method:
public static ListNode invert(ListNode head) {
ListNode temp1;
ListNode temp2 = null;
while (head != null) {
temp1 = head.link;
head.link = temp2;
temp2 = head;
head = temp1;
}
return temp2;
}
And use the returned value when printing:
System.out.println("Your inverted list of integers is now : ");
ListNode result = invert(head);
printLinked(result.link);
It wasn't printing because you were using the original head that was now the tail of the list.

Related

infinite loop, LeetCode 1721

here's my code :
class Solution {
public int size (ListNode head)
{
int size = 0;
ListNode curr = head;
while (curr != null)
{
size ++;
curr = curr.next;
}
return size;
}
public ListNode swapNodes(ListNode head, int k) {
ListNode curr = head;
ListNode curr2 = head;
ListNode pre = null;
ListNode pre2 = null;
ListNode result = head;
for (int i = 1; i < k && curr != null; i ++)
{
pre = curr;
curr = curr.next;
}
int size = size(head);
for (int i = 0; i < (size - k) && curr2 != null; i ++)
{
pre2 = curr2;
curr2 = curr2.next;
}
ListNode tmp = curr.next;
ListNode tmp2 = curr2.next;
pre.next = curr2;
curr2.next = tmp;
pre2.next = curr;
curr.next = tmp2;
return head;
}
}
there seems to be an infinite loop in one of the cases and i can't fix it, can someone help please ?
for me everything works fine. Maybe you are using other inputs or initialising the List in a wrong way.
I added a method to your ListNode class to create the list in a fluent way:
public ListNode addListNode(int v) {
ListNode listNode = new ListNode(v);
next = listNode;
return listNode;
}
and a print Method to your Solution class to print the list.
public static void printList(ListNode head)
{
StringBuilder out = new StringBuilder();
ListNode curr = head;
while (curr != null)
{
out.append(curr.val).append(",");
curr = curr.next;
}
System.out.println(out);
}
Running it with this main method:
public static void main(String[] args) {
ListNode listNode = new ListNode(1);
ListNode currNode = listNode.addListNode(2);
for( int i = 3; i <= 10; i++) {
currNode = currNode.addListNode(i);
}
// you also could write listNode.addListNode(2).addListNode(3).addListNode(4) ...
printList(listNode);
System.out.println("SwapNodes");
ListNode swappedListNode = swapNodes(listNode, 2);
printList(swappedListNode);
}
it outputs
1,2,3,4,5,6,7,8,9,10,
SwapNodes
1,9,3,4,5,6,7,8,2,10,
So it seems to work as expected, no infinite loop. As I mentioned at the beginning feel free to add your main method and the way you are calling the swapNodes Method.
You can edit your question and add these informations..

Determine the Object (book) that appears first alphabetically

I was tasked with creating my own linked list class, using a book class i made. One of the questions was to Determine the book that appears first alphabetically.
i was able to sort the Linked list alphabetically using bubble sort(i know its not efficient but im still new) here is the code.
public void alphaBubbleSort() {
int size = size();
if (size > 1) {
boolean wasChanged;
do {
Node current = head;
Node previous = null;
Node next = head.next;
wasChanged = false;
while (next != null) {
if (current.book.getName().compareToIgnoreCase(next.book.getName()) > 0) {
wasChanged = true;
if (previous != null) {
Node sig = next.next;
previous.next = next;
next.next = current;
current.next = sig;
} else {
Node temp = next.next;
head = next;
next.next = current;
current.next = temp;
}
previous = next;
next = current.next;
} else {
previous = current;
current = next;
next = next.next;
}
}
} while (wasChanged);
}
}
my problem is i only want the front node and i do not want to alter the linked list order. i tried to do this in my main.
Linky tempLinky = new Linky(); // create temp linked list
tempLinky = linky; // copy temp main linked list to temp
tempLinky.alphaBubbleSort(); // sort temp list
System.out.println(tempLinky.peek());// return object in first node
This did not seem to work. Ive tried some other code that does not work, so ive come here as a last resort.
If you need to find the first book alphabetically, there's no need to sort the entire list (and, as you commented, you don't want to alter the list's order anyway).
Instead, you could iterate over the list and keep the "first" object as you go:
public Book getFirstAlphabetically() {
Node current = head;
Book retVal = head.book;
while (current != null) {
if (current.book.getName().compareToIgnoreCase(retVal.getName()) < 0) {
retVal = current.book;
}
current = current.next;
}
return retVal;
}
Here's an example:
import java.util.Random;
class Book {
String title;
Book(String title){this.title = title;}
}
class Node {
Book b; Node next;
Node(Book b){this.b = b;}
}
public class Main {
static Book least(Node head){
if (head == null) return null;
Book least = head.b;
for(Node n=head.next; n.next!=null; n=n.next)
least = least.title.compareTo(n.b.title) > 0 ? n.b : least;
return least;
}
static void print(Node head){
for(Node n=head; n.next!=null; n=n.next)
System.out.println(n.b.title);
}
static String randString(){
Random r = new Random();
int len = r.nextInt(20)+1;
char[] chars = new char[len];
for(int i=0; i<chars.length; i++)
chars[i]= (char) (r.nextInt(26)+97);
return new String(chars);
}
public static void main(String[] args) {
Node head = new Node(new Book(randString()));
Node next = head;
for(int i = 0; i<20; i++)
next = next.next = new Node(new Book(randString()));
print(head);
System.out.println("==========");
System.out.println(least(head).title);
}
}

How can I Search for a node's contents in a Generic Linked List with a String Input?

I am trying to return all node contents that match a given String input. What I am trying to do is essentially a very simple search engine, where the user is able to type in a String and the program returns all characteristically similar contents it can find in the linked list. The linked list itself is built from a file, formatted as
<<Game’s Name 0>>\t<<Game’s Console 0>>\n
<<Game’s Name 1>>\t<<Game’s Console 1>>\n
where the lines are delimited with a \n and the game and its corresponding console are delimited with a \t.
My current methodology follows searching the linked list with a while loop, assigning a temporary value to the head and reassigning it to it's link as it goes down the list. Once the loop finds contents within a node that matches the current input, it stops the loop and returns the data found in the node. I have yet to try if this could be done with a for loop, as the while loop more than likely would not know when to continue once it has found a match. I am also unsure if the while loop argument is the most efficient one to use, as my understanding of it is very minimal. I believe !temp.equals(query) is stating "temp does not equal query," but I have a feeling that this could be done in a more efficient manner.
This is what I have so far, I will provide the entire Generic linked list class for the sake of context, but the method I am questioning is the very last one, found at line 126.
My explicitly stated question is how can I search through a linked list's contents and return those contents through the console.
import java.io.FileNotFoundException;
import java.util.Scanner;
public class GenLL<T>
{
private class ListNode
{
T data;
ListNode link;
public ListNode(T aData, ListNode aLink)
{
data = aData;
link = aLink;
}
}
private ListNode head;
private ListNode current;
private ListNode previous;
private int size;
public GenLL()
{
head = current = previous = null;
this.size = 0;
}
public void add(T aData)
{
ListNode newNode = new ListNode(aData, null);
if (head == null)
{
head = current = newNode;
this.size = 1;
return;
}
ListNode temp = head;
while (temp.link != null)
{
temp = temp.link;
}
temp.link = newNode;
this.size++;
}
public void print()
{
ListNode temp = head;
while (temp != null)
{
System.out.println(temp.data);
temp = temp.link;
}
}
public void addAfterCurrent(T aData)
{
if (current == null)
return;
ListNode newNode = new ListNode(aData, current.link);
current.link = newNode;
this.size++;
}
public T getCurrent()
{
if(current == null)
return null;
return current.data;
}
public void setCurrent(T aData)
{
if(aData == null || current == null)
return;
current.data = aData;
}
public void gotoNext()
{
if(current == null)
return;
previous = current;
current = current.link;
}
public void reset()
{
current = head;
previous = null;
}
public boolean hasMore()
{
return current != null;
}
public void removeCurrent()
{
if (current == head)
{
head = head.link;
current = head;
}
else
{
previous.link = current.link;
current = current.link;
}
if (this.size > 0)
size--;
}
public int getSize()
{
return this.size;
}
public T getAt(int index)
{
if(index < 0 || index >= size)
return null;
ListNode temp = head;
for(int i=0;i<index;i++)
temp = temp.link;
return temp.data;
}
public void setAt(int index, T aData)
{
if(index < 0 || index >= size || aData == null)
return;
ListNode temp = head;
for (int i = 0; i < index; i++)
temp = temp.link;
temp.data = aData;
}
public T search() throws FileNotFoundException {
Scanner keyboard = new Scanner(System.in);
System.out.println("Search: ");
String query = keyboard.nextLine();
ListNode temp = head;
while(!temp.equals(query))
temp = temp.link;
return temp.data;
//plus some sort of print function to display the result in the console
}
}
You can apply regex for every node's content, if the data type is string apply it if it is of some other datatype convert it into string if possible, else throw some exceptions.

How to reverse a singly-linked list in blocks of some given size in O(n) time in place?

I recently encounter an algorithm problem:
Reverse a singly-linked list in blocks of k in place. An iterative approach is preferred.
The first block of the resulting list should be maximal with regards to k. If the list contains n elements, the last block will either be full or contain n mod k elements.
For example:
k = 2, list = [1,2,3,4,5,6,7,8,9], the reversed list is [8,9,6,7,4,5,2,3,1]
k = 3, list = [1,2,3,4,5,6,7,8,9], the reversed list is [7,8,9,4,5,6,1,2,3]
My code is shown as below.
Is there an O(n) algorithm that doesn't use a stack or extra space?
public static ListNode reverse(ListNode list, int k) {
Stack<ListNode> stack = new Stack<ListNode>();
int listLen = getLen(list);
int firstBlockSize = listLen % k;
ListNode start = list;
if (firstBlockSize != 0) {
start = getBlock(stack, start, firstBlockSize);
}
int numBlock = (listLen) / k;
for (int i = 0; i < numBlock; i++) {
start = getBlock(stack, start, k);
}
ListNode dummy = new ListNode(0);
ListNode cur = dummy;
while (!stack.empty()) {
cur.next = stack.peek();
cur = stack.pop();
while (cur.next != null) {
cur = cur.next;
}
}
return dummy.next;
}
public static ListNode getBlock(Stack<ListNode> stack, ListNode start, int blockSize) {
ListNode end = start;
while (blockSize > 1) {
end = end.next;
blockSize--;
}
ListNode temp = end.next;
end.next = null;
stack.push(start);
return temp;
}
public static int getLen(ListNode list) {
ListNode iter = list;
int len = 0;
while (iter != null) {
len++;
iter = iter.next;
}
return len;
}
This can be done in O(n) time using O(1) space as follows:
Reverse the entire list.
Reverse the individual blocks.
Both can be done using something very similar to the standard way to reverse a singly linked-list and the overall process resembles reversing the ordering of words in a string.
Reversing only a given block is fairly easily done by using a length variable.
The complication comes in when we need to move from one block to the next. The way I achieved this was by having the reverse function return both the first and last nodes and having the last node point to the next node in our original linked-list. This is necessary because the last node's next pointer needs to be updated to point to the first node our next reverse call returns (we don't know what it will need to point to before that call completes).
For simplicity's sake, I used a null start node in the code below (otherwise I would've needed to cater for the start node specifically, which would've complicated the code).
class Test
{
static class Node<T>
{
Node next;
T data;
Node(T data) { this.data = data; }
#Override
public String toString() { return data.toString(); }
}
// reverses a linked-list starting at 'start', ending at min(end, len-th element)
// returns {first element, last element} with (last element).next = (len+1)-th element
static <T> Node<T>[] reverse(Node<T> start, int len)
{
Node<T> current = start;
Node<T> prev = null;
while (current != null && len > 0)
{
Node<T> temp = current.next;
current.next = prev;
prev = current;
current = temp;
len--;
}
start.next = current;
return new Node[]{prev, start};
}
static <T> void reverseByBlock(Node<T> start, int k)
{
// reverse the complete list
start.next = reverse(start.next, Integer.MAX_VALUE)[0];
// reverse the individual blocks
Node<T>[] output;
Node<T> current = start;
while (current.next != null)
{
output = reverse(current.next, k);
current.next = output[0];
current = output[1];
}
}
public static void main(String[] args)
{
//Scanner scanner = new Scanner(System.in);
Scanner scanner = new Scanner("3 9 1 2 3 4 5 6 7 8 9\n" +
"2 9 1 2 3 4 5 6 7 8 9");
while (scanner.hasNextInt())
{
int k = scanner.nextInt();
// read the linked-list from console
Node<Integer> start = new Node<>(null);
Node<Integer> current = start;
int n = scanner.nextInt();
System.out.print("Input: ");
for (int i = 1; i <= n; i++)
{
current.next = new Node<>(scanner.nextInt());
current = current.next;
System.out.print(current.data + " ");
}
System.out.println("| k = " + k);
// reverse the list
reverseByBlock(start, k);
// display the list
System.out.print("Result: ");
for (Node<Integer> node = start.next; node != null; node = node.next)
System.out.print(node + " ");
System.out.println();
System.out.println();
}
}
}
This outputs:
Input: 1 2 3 4 5 6 7 8 9 | k = 3
Result: 7 8 9 4 5 6 1 2 3
Input: 1 2 3 4 5 6 7 8 9 | k = 2
Result: 8 9 6 7 4 5 2 3 1
Live demo.
Here is an iterative way of doing it... you read my full explanation here
Node reverseListBlocks1(Node head, int k) {
if (head == null || k <= 1) {
return head;
}
Node newHead = head;
boolean foundNewHead = false;
// moves k nodes through list each loop iteration
Node mover = head;
// used for reversion list block
Node prev = null;
Node curr = head;
Node next = null;
Finish: while (curr != null) {
// move the mover just after the block we are reversing
for (int i = 0; i < k; i++) {
// if there are no more reversals, finish
if (mover == null) {
break Finish;
}
mover = mover.next;
}
// reverse the block and connect its tail to the rest of
// the list (at mover's position)
prev = mover;
while (curr != mover) {
next = curr.next;
curr.next = prev;
prev = curr;
curr = next;
}
// establish the new head, if we didn't yet
if (!foundNewHead) {
newHead = prev;
foundNewHead = true;
}
// connects previous block's head to the rest of the list
// move the head to the tail of the reversed block
else {
head.next = prev;
for (int i = 0; i < k; i++) {
head = head.next;
}
}
}
return newHead;
}
The easiest way to reverse the single linked list is as follows.
private void reverse(Node node)
{
Node current = Node;
Node prev = null;
Node next = null;
if(node == null || node.next == null)
{
return node;
}
while(current != null)
{
next = current.next;
//swap
current.next = prev;
prev = current;
current = next;
}
node.next = current;
}
This section contains multiple Single Linked List Operation
import java.util.Scanner;
import java.util.Stack;
public class AddDigitPlusLL {
Node head = null;
int len =0;
static class Node {
int data;
Node next;
Node(int data) {
this.data = data;
this.next = null;
}
}
public void insertFirst(int data) {
Node newNode = new Node(data);
if (head != null)
newNode.next = head;
head = newNode;
}
public void insertLast(int data) {
Node temp = head;
Node newNode = new Node(data);
if (temp == null)
head = newNode;
else {
Node previousNode = null;
while (temp != null) {
previousNode = temp;
temp = temp.next;
}
previousNode.next = newNode;
}
}
public Long getAllElementValue() {
Long val = 0l;
Node temp=head;
while(temp !=null) {
if(val == 0)
val=(long) temp.data;
else
val=val*10+temp.data;
temp = temp.next;
}
System.out.println("value is :" + val);
return val;
}
public void print(String printType) {
System.out.println("----------- :"+ printType +"----------- ");
Node temp = head;
while (temp != null) {
System.out.println(temp.data + " --> ");
temp = temp.next;
}
}
public void generateList(Long val) {
head = null;
while(val > 0) {
int remaining = (int) (val % 10);
val = val/10;
insertFirst(remaining);
}
}
public void reverseList(Long val) {
head =null;
while(val >0) {
int remaining = (int) (val % 10);
val = val/10;
insertLast(remaining);
}
}
public void lengthRecursive(Node temp) {
if(temp != null) {
len++;
lengthRecursive(temp.next);
}
}
public void reverseUsingStack(Node temp) {
Stack<Integer> stack = new Stack<Integer>();
while(temp != null) {
stack.push(temp.data);
temp = temp.next;
}
head = null;
while(!stack.isEmpty()) {
int val = stack.peek();
insertLast(val);
stack.pop();
}
print(" Reverse Using Stack");
}
public static void main(String[] args) {
// TODO Auto-generated method stub
Scanner s = new Scanner(System.in);
AddDigitPlusLL sll = new AddDigitPlusLL();
sll.insertFirst(5);
sll.insertFirst(9);
sll.insertLast(8);
sll.print("List Iterate");
Long val = sll.getAllElementValue();
System.out.println("Enter the digit to add");
Long finalVal = val +s.nextInt();
s.close();
sll.generateList(finalVal);
sll.print("Add int with List Value");
sll.reverseList(finalVal);
sll.print("Reverse the List");
sll.lengthRecursive(sll.head);
System.out.println("Length with Recursive :"+ sll.len);
sll.print("Before call stack reverse method");
sll.reverseUsingStack(sll.head);
}
}

Append two linked list

I wrote a simple method to append a linked list at the end of another linked list.So what the program should ideally do is when I give it two lists
list1 ===>1->2->3
list2 ===>4->5->6
updatedList ==>1->2->3->4->5->6
But when I run the method appendList it goes into an infinite loop printing 1 to 6 indefinitely.What am I doing wrong out here?
public static Node appendList(Node head1, Node head2) {
Node prev = null;
Node current = head1;
while (current != null) {
prev = current;
current = current.next;
}
prev.next = head2;
return head1;
}
Oh and I forgot to add the Node class and how I call the method from my main .I know its bit cumbersome but here it is
public class ReverseLinkedList {
class Node {
int data;
Node next;
Node(int data) {
this.data = data;
}
public void displayData() {
System.out.println(data);
}
}
public static void main(String args[]) {
ReverseLinkedList reversedList = new ReverseLinkedList();
Scanner scanner = new Scanner(System.in);
System.out.println("Enter the length of the linked list!!");
int listSize = scanner.nextInt();
System.out.println("Enter the Numbers you want to insert!!");
int count = 0;
while (scanner.hasNextLine()) {
if (count == listSize)
break;
reversedList.insert(scanner.nextInt());
count++;
}
System.out.println("Inserted List !!");
reversedList.displayList();
/*
* Node reverseNodeStart =
* reversedList.reverseList1(reversedList.first);
* System.out.println("Reversed List !!"); while (reverseNodeStart !=
* null) { reverseNodeStart.displayData(); reverseNodeStart =
* reverseNodeStart.next; }
*/
Node reverseNodeStart = reversedList.appendList(reversedList.first,
reversedList.first);
while (reverseNodeStart != null) {
reverseNodeStart.displayData();
reverseNodeStart = reverseNodeStart.next;
}
}
}
The problem was I was using the same List which was causing the circular reference.It works fine now.You knew the problem even before I posted the code now that's impressive. Thanks!!I solved it by creating a new List2 and passing in List1 and List2.
appendList(Node lis1head, Node list2head)

Categories

Resources