Reversing linked list using stack? - java

This is a code that reverses linked list using stack. I got everything right from creating a linked list and getting input from the user, but I got some logic wrong. Iam trying to reverse linked list using stack, but it is only reversing two number if say suppose I give in three numbers. How do I get it right?
import java.util.*;
class LinkedList{
Node head;
static class Node{`
int data;
Node next;
Node(int d){
this.data = d;
next = null;
}
}
public static LinkedList insert(LinkedList list, int data){
Node new_node = new Node(data);
if(list.head == null){
list.head = new_node;
}
else{
Node last = list.head;
while(last.next != null){
last = last.next;
}
last.next = new_node;
}
return list;
}
public static LinkedList reverse(LinkedList list){
Stack<Integer> stack = new Stack<Integer>();
Node current = list.head;
while(current.next != null){
stack.push(current.data);
current = current.next;
}
while(!stack.isEmpty()){
System.out.println("The reversed list is: " + stack.pop());
}
return list;
}
}
public class Main
{
public static void main(String[] args) {
LinkedList l = new LinkedList();
Scanner sc = new Scanner(System.in);
int length = sc.nextInt();
for(int i=1; i<=length; i++){
int number = sc.nextInt();
l.insert(l,number);
}
l.reverse(l);
}
}

The problem lies with your reverse function. While reading the linked list your while loop logic is skipping the last item.
Correct function is:
public static LinkedList reverse(LinkedList list){
Stack<Integer> stack = new Stack<Integer>();
Node current = list.head;
while(current != null){ // instead of while(current.next != null)
System.out.println("Pushed Data:"+current.data);
stack.push(current.data);
current = current.next;
}
System.out.println("The reversed list is: ");
while(!stack.isEmpty()){
System.out.println(stack.pop());
}
return list;
}

Everything looks good except the line while(current.next != null){ as here you check for the next node instead of the current node. So you need to change this line to while(current != null){

Related

Is there any code which needs to be included for deleting the nodes in Java Linked List

Write a Java program to move the last element of the linked list in the front and rest of the element by one position, and then print the modified linked list.
NOTE: Remember you cannot use the LinkedList java class and its methods, you have to make your own LinkedList class and methods.
I have written the code to move the last node to the first but ii'm not able to delete the node whichever I wanted.
import java.util.*;
public class LinkedList {
Node head;
class Node
{
int data ;
Node next;
Node(int a )
{
data = a ;
next = null;
}
}
void movefront()
{
if(head == null || head.next == null)
return;
Node secLast = null;
Node last = head;
while(last.next!= null)
{
secLast = last;
last = last.next;
}
secLast.next=null;
last.next = head;
head = last;
}
void deleteNode(int key)
{
// Store head node
Node temp = head, prev = null;
// If head node itself holds the key to be deleted
if (temp != null && temp.data == key)
{
head = temp.next; // Changed head
return;
}
// Search for the key to be deleted, keep track of the
// previous node as we need to change temp.next
while (temp != null && temp.data != key)
{
prev = temp;
temp = temp.next;
}
// If key was not present in linked list
if (temp == null) return;
// Unlink the node from linked list
prev.next = temp.next;
}
public void push (int new_data)
{
Node new_node = new Node(new_data);
new_node.next= head;
head = new_node;
}
void printList()
{
Node temp = head;
while(temp!=null)
{
System.out.println(temp.data + " ");
temp = temp.next;
} System.out.println();
}
public static void main(String[] args) {
// TODO Auto-generated method stub
System.out.println("Number of integers to be enetered in the list:");
Scanner sc = new Scanner(System.in);
LinkedList llist = new LinkedList();
Integer n= sc.nextInt();
Integer arr[]=new Integer[n];
System.out.println("Insert the elements of your array");
for(int i=0; i<=arr.length; i++)
{
n= sc.nextInt();
llist.push(n);
}
System.out.println(" Linked list before moving last to front : " );
llist.printList();
llist.movefront();
llist.deleteNode(2);
System.out.println(" Linked list after moving from front to last : ");
llist.printList();
}
}
Try:
public class LinkedList {
static Scanner sc = new Scanner(System.in);
Node head;
class Node
{
int data ;
Node next;
Node(int a )
{
data = a ;
next = null;
}
}
void movefront()
{
if(head == null || head.next == null)
return;
Node secLast = null;
Node last = head;
while(last.next!= null)
{
secLast = last;
last = last.next;
}
secLast.next=null;
last.next = head;
head = last;
}
public void push(int new_data)
{
Node new_node = new Node(new_data);
new_node.next= null;
if(head == null) {
head = new_node;
return;
}
Node last_Node = head;
while(last_Node.next != null) {
last_Node = last_Node.next;
}
last_Node.next = new_node;
}
void printList()
{
Node temp = head;
while(temp != null)
{
System.out.println(temp.data + " ");
temp = temp.next;
} System.out.println();
}
private void delete() {
Node current_Node = head;
if(current_Node == null) {
System.out.println("no element in list to be deleted");
return;
}
head = current_Node.next;
}
public static void main(String[] args) {
System.out.println("Number of integers to be entered in the list:");
LinkedList llist = new LinkedList();
Integer n= sc.nextInt();
Integer arr[]=new Integer[n];
System.out.println("Insert the elements of your array: ");
for(int i=0; i<arr.length; i++)
{
n= sc.nextInt();
llist.push(n);
}
System.out.println("Linked list before moving last to front: " );
llist.printList();
llist.movefront();
System.out.println("Linked list after moving from front to last: ");
llist.printList();
System.out.println("Deleting first element from the list: ");
llist.delete();
llist.printList();
}
}
Output:
Explanation:
Updated for(int i=0; i<=arr.length; i++) to for(int i=0; i<arr.length; i++) in main method as index start from 0 so it should go till arr.length-1 hence i<arr.length.
Updated push method. New node is inserted at the end of the linkedlist but in your code it was acting as stack.
Added delete method to remove first node. If head is null in that case list is empty hence no element can be removed from the list. If it contains element then head will point to current_Node.next;

Best way to print a linked list(Singly and Doubly) in reverse?

Can someone provide the possible ways to print a Linkedlist in reverse in Java.
A way I understand would be to Recursively reach the end of list, And then start printing from the back and come to front recursively.
Please share the possible ways.
I am using a Node having next and previous.
A Solution I figured is below. But here I need to create a variable each time entering in the recursive loop. That's bad :(
public void reversePrinting(int count){
if(count==0){ //to assign the root node to current only once
current=root;
count++;
}
else{ //moving current node to subsequent nodes
current=current.nextNode;
}
int x= current.data;
if(current.nextNode==null){
System.out.println(x);
return;
}
reversePrinting(count);
System.out.println(x);
}
try this, it is able reverse a linkedlist
public class DoReverse{
private Node head;
private static class Node {
private int value;
private Node next;
Node(int value) {
this.value = value;
}
}
public void addToTheLast(Node node) {
if (head == null) {
head = node;
}
else {
Node temp = head;
while (temp.next != null)
temp = temp.next;
temp.next = node;
}
}
public void printList(Node head) {
Node temp = head;
while (temp != null) {
System.out.format("%d ", temp.value);
temp = temp.next;
}
System.out.println();
}
public static Node reverseList(Node head){
Node prev = null;
Node current = head;
Node next = null;
while(current != null){
next = current.next;
current.next = prev;
prev = current;
current = next;
}
head = prev;
return head;
}
public static void main(String[] args) {
DoReverse list = new DoReverse();
// Creating a linked list
Node head = new Node(5);
list.addToTheLast(head);
list.addToTheLast(new Node(6));
list.addToTheLast(new Node(7));
list.addToTheLast(new Node(1));
list.addToTheLast(new Node(2));
list.addToTheLast(new Node(10));
System.out.println("Before Reversing :");
list.printList(head);
Node reverseHead= list.reverseList(head);
System.out.println("After Reversing :");
list.printList(reverseHead);
}
}
Why not copy the list so that it is reversed:
Reversing a linked list in Java, recursively
And then loop the copy of the list like your normally would?

Putting text from txt file into linked list

I'm trying to tokenize lines of numeric expressions into a linked list for a CS Project. I have to use my own Linked List that I created in a previous lab.
I tokenize each number and operator of a line, and insert each token into a node in my linked list as they are tokenized. When I code the program to print out each token as it's tokenized, each token is printed. But when I tell it to print out the linked list that contains each token as a node, some operators are missing. I don't know what is the cause for this behavior.
Below is the method that creates the Linked List containing each token:
public static LinkedListTest ReadInFile(String path){
File file = new File(path);
LinkedListTest list = new LinkedListTest();
try {
Scanner scanner = new Scanner(file);
int count = 0;
while (scanner.hasNextLine()) {
String line = scanner.nextLine();
StringTokenizer st = new StringTokenizer(line);
while (st.hasMoreTokens()){
list.insert(st.nextToken());
}
}
scanner.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
}
return list;
}
Below are the methods for inserting into a linked list and printing one:
public class LinkedListTest implements LinkedList {
private Node head;
public LinkedListTest(){
head = new Node();
}
public void insert(Object x){
if (lookup(x) == false){
if (head.data == null)
head.data = x;
else{
/*
Node NewNode = new Node();
NewNode.data = x;
NewNode.next = head;
head = NewNode;
*/
//InsertLast
Node temp = head;
while (temp.next != null){
temp = temp.next;
}
Node NewNode = new Node();
NewNode.data = x;
NewNode.next = null;
temp.next = NewNode;
}
}
}
public void printList(){
Node temp = head;
while (temp.next != null){
System.out.print(temp.data + " ");
temp = temp.next;
}
System.out.print(temp.data + " ");
}
}
I solved it. The lookup clause on my insert function was screwing it up.

Order a linked list alphabetically by name

I am having an issue organizing a linked list alphabetically. I am reading the names in from a text file and storing them into a linked list. The problem I am having is how to sort them alphabetically. If anybody could point me in the right direction that would be amazing. The idea is to get the value of the first 3 letters in each name and compare them to the first 3 in the next name. But where would I compare the letters together?
Here is the LinkedListNode class:
public class LinkedListNode
{
private String data;
private LinkedListNode next;
public LinkedListNode(String data)
{
this.data = data;
this.next = null;
}
public String getData()
{
return data;
}
public LinkedListNode getNext()
{
return next;
}
public void setNext(LinkedListNode n)
{
next = n;
}
}
Here is the LinkedList file with the main method:
import java.io.*;
import java.util.Scanner;
public class LinkedList {
public LinkedListNode head;
String fname;
public static void main(String[] args) throws FileNotFoundException{
Scanner scan = new Scanner(new File("Names.txt"));
LinkedList l = new LinkedList();
int i = 1;
while(scan.hasNext()) {
String s = scan.nextLine();
l.insertBack(s);
i++;
}
System.out.print(l.showList());
}
public LinkedList() {
this.head = null;
}
public void insertBack(String data){
if(head == null){
head = new LinkedListNode(data);
}else{
LinkedListNode newNode = new LinkedListNode(data);
LinkedListNode current = head;
while(current.getNext() != null){
current = current.getNext();
}
current.setNext(newNode);
}
}
public String showList(){
int i = 0, j;
String retStr = "List nodes:\n";
LinkedListNode current = head;
while(current != null){
i++;
retStr += "Node " + i + ": " + current.getData() + "\n";
current = current.getNext();
}
return retStr;
}
}
Some pseudo code for you:
OUTER:
for word in file
node = head
while node.next
if word > node.word
node.next
else
Node temp = new Node(word)
temp.next = word.next
node.next = temp
continue OUTER
node.next = new Node(word)
This is an as-you-go insertion sort. After every insert the file will be sorted. Or you could use other sorting algorithms after you read all of the data
if it's if word > node.word this part you're having trouble with, the String#compareTo method will be useful
Try using Collections.sort(list)
Also, for comparing, you can use compareTo function under Comparable Interface
To do easy comparisons, your nodes should implement Comparable. The base Java libraries tend to rely upon this for easy sorting.
The Comaprable interface will require you to implement compareTo (see below).
public int <LinkedListNode> compareTo(LinkedListNode n){
//Case insensitively compare the first 3 characters of the two nodes
String myHead = data.substring(0,3).toLowerCase();
String comparableHead = n.data.substring(0,3).toLowerCase();
return (myHead.compareTo(comparableHead));
}
If you use a standard List structure like, ArrayList, the Collections.sort(list) will be able to use this method to order your list.
And here's an insertion sort based "insert" function for your runTime, using this comparable.
public void insert(String data){
LinkedListNode newNode = new LinkedListNode(data);
if(head == null){
head = newNode;
}else{
LinkedListNode current = head;
LinkedListNode prev;
//This is missing some key edge cases, but it inserts properly in the general case. You'll have to add to it to handle things like running off the list, or this needing to be inserted before the head.
while(current.getNext() != null){
if(current.compareTo(newNode)<0){
newNode.setNext(current);
prev.setNext(newNode);
break;
}
prev = current;
current = current.getNext();
}
}
}

java combine two linkedlist

I have a question for combining two linkedlist. Basically, I want to append one linkedlist to the other linkedlist.
Here is my solution. Is there a more efficient way to do it without looping the first linkedlist? Any suggestion would be appreciated.
static Node connect(LinkedList list1, LinkedList list2) {
Node original = list1.first;
Node previous = null;
Node current = list1.first;
while (current != null) {
previous = current;
current = current.next;
}
previous.next = list2.first;
return original;
}
Use list1.addAll(list2) to append list2 at the end of list1.
For linked lists, linkedList.addAll(otherlist) seems to be a very poor choice.
the java api version of linkedList.addAll begins:
public boolean addAll(int index, Collection<? extends E> c) {
checkPositionIndex(index);
Object[] a = c.toArray();
so even when you have 2 linked lists, the second one gets converted to an array, then re-constituted into individual elements. This is worse than just merging 2 arrays.
I guess this is your own linked list implementation? With only a pointer to next element, the only way to append at the end is to walk all the elements of the first list.
However, you could store a pointer to the last element to make this operation run in constant time (just remember to update the last element of the new list to be the last element of the added list).
The best way is to append the second list to the first list.
1. Create a Node Class.
2. Create New LinkedList Class.
public class LinkedList<T> {
public Node<T> head = null;
public LinkedList() {}
public void addNode(T data){
if(head == null) {
head = new Node<T>(data);
} else {
Node<T> curr = head;
while(curr.getNext() != null) {
curr = curr.getNext();
}
curr.setNext(new Node<T>(data));
}
}
public void appendList(LinkedList<T> linkedList) {
if(linkedList.head == null) {
return;
} else {
Node<T> curr = linkedList.head;
while(curr != null) {
addNode((T) curr.getData());
curr = curr.getNext();
}
}
}
}
3. In the Main function or whereever you want this append to happen, do it like this.
LinkedList<Integer> n = new LinkedListNode().new LinkedList<Integer>();
n.addNode(23);
n.addNode(41);
LinkedList<Integer> n1 = new LinkedListNode().new LinkedList<Integer>();
n1.addNode(50);
n1.addNode(34);
n.appendList(n1);
I like doing this way so that there isn't any need for you to pass both these and loop again in the first LinkedList.
Hope that helps
My Total Code:
NOTE: WITHOUT USING JAVA API
class Node {
Node next;
int data;
Node(int d){
data = d;
next = null;
}
}
public class OddEvenList {
Node head;
public void push(int new_data){
Node new_node = new Node(new_data);
new_node.next = head;
head = new_node;
}
Node reverse(Node head){
Node prev = null;
Node next = null;
Node curr = head;
while(curr != null){
next = curr.next;
curr.next = prev;
prev = curr;
curr = next;
}
head = prev;
return head;
}
Node merge(Node head1, Node head2){
Node curr_odd = head1;
Node curr_even = head2;
Node prev = null;
while(curr_odd != null){
prev = curr_odd;
curr_odd = curr_odd.next;
}
prev.next = curr_even;
return head1;
}
public void print(Node head){
Node tnode = head;
while(tnode != null){
System.out.print(tnode.data + " -> ");
tnode = tnode.next;
}
System.out.println("Null");
}
public static void main(String[] args) {
// TODO Auto-generated method stub
OddEvenList odd = new OddEvenList();
OddEvenList even = new OddEvenList();
OddEvenList merge = new OddEvenList();
odd.push(1);
odd.push(3);
odd.push(5);
odd.push(7);
odd.push(9);
System.out.println("Odd List: ");
odd.print(odd.head);
System.out.println("Even List: ");
even.push(0);
even.push(2);
even.push(4);
even.push(6);
even.push(8);
even.print(even.head);
System.out.println("After Revrse: --------------------");
Node node_odd =odd.reverse(odd.head);
Node node_even = even.reverse(even.head);
System.out.println("Odd List: ");
odd.print(node_odd);
System.out.println("Even List: ");
even.print(node_even);
System.out.println("Meged: --------------");
Node merged = merge.merge(node_odd, node_even);
merge.print(merged);
}
}

Categories