Trouble sorting linked list - java

outputI'm doing a project for class where I have to sort a linked list using insertion sort. I am supposed to take user input, convert it into an int array and insert it into a linked list. My problem is for some reason when I go to print the linked list post sort, it only prints the first node. The code worked jsut fine when I was initially testing it(I was manually entering what integers to insert), but now that I'm using arrays it doesn't seem to work. Can anyone help?
(this is only one class from my project but let me know if more information is needed).
Edit: I added a picture of what my output lokos like
import java.util.Arrays;
public class SortLL {
static LL top;
static Node head;
static Node sorted;
//function to insert node at head
public void toHead(int newData){
Node newNode = new Node(newData);
newNode.link = head;
head = newNode;
}
public static void insertion(Node ref){ //problem right now is that i'm only passing in one node
sorted = null;
Node current = ref;
while(current != null){
Node next = current.link;
sortInsert(current);
current = next;
}
head = sorted;
}
static void sortInsert(Node newNode){ //item in this case is val
if(sorted == null || sorted.item >= newNode.item){
newNode.link = sorted;
sorted = newNode;
} else {
Node current = sorted;
while(current.link != null && current.link.item < current.item){
current = current.link;
}
newNode.link = current.link;
current.link = newNode;
}
}
void printList(Node head)
{
while (head != null)
{
System.out.print(head.item + " ");
head = head.link;
}
}
public static void sortList(int[] arrA, int[] arrB){
int[] arr = new int[arrA.length + arrB.length];
System.arraycopy(arrA, 0, arr, 0, arrA.length);
System.arraycopy(arrB, 0, arr, arrA.length, arrB.length);
System.out.println("checking array " + Arrays.toString(arr));
SortLL sort = new SortLL();
for(int i=0;i<arr.length;i++){
sort.toHead(arr[i]);
}
System.out.println("sortLL.java\n\n");
sort.printList(sort.head);
sort.sortInsert(sort.head);
System.out.println("\nLinkedList After sorting");
sort.printList(sort.head);
}
}

Inside your printList() method, you shift the head variable while iterating over the list. When you move the head variable to the end, you essentially destroy the linked list since you lose your reference to the beginning of it. Java will then automatically treat the unreferenced nodes as garbage.
From what I see, after you first call sort.printList(sort.head), you destroyed your original linked list, so it didn't work when sorting.
When calling printList(), it might help to use a temporary node (Node temp = head) so that you don't lose your original head variable.

Related

When I delete from a LinkedList object vs. Deleting a node from given a head node why do I get different results?

I think I know what the problem may be (a misunderstanding on Global vs. Local variables), but would like further verification on why it is not doing what I would like it to.
So, originally, I was just messing around and tried to implement the LinkedList delete method as follows :
(Also, I know most of this looks a mess right now, I think I am doing some bad practices, so you may be frank)
// Practicing with Lists...
public class ListPrac {
/*
Implement Delete for
singly-linked linked list
*/
public static void main(String[] args) {
ListNode head = new ListNode(1);
head.next = new ListNode(2);
head.next.next = new ListNode(3);
head.next.next.next = new ListNode(4);
delete(head, 1);
System.out.println("done");
}
public static int delete(ListNode head, int deleteMe) {
ListNode temp = head;
ListNode prev = null;
// need to check if it is first and
// need to check if it is at the end...
if (temp != null && temp.dat == deleteMe) {
temp = temp.next;
return deleteMe;
}
// ^ two edge cases...
while (temp != null) {
int curVal = temp.dat;
if (curVal == deleteMe && head.dat == curVal) {
head = temp.next;
return deleteMe; // done...
}
if (curVal == deleteMe) {
if (temp.next != null) {
prev.next = temp.next;
return deleteMe; // done...
}
}
prev = temp;
temp = temp.next;
}
return -1; // not found, so not deleted...
}
public static class ListNode {
int dat;
ListNode next;
public ListNode(int val) {
dat = val;
next = null;
}
}
}
When I debug this and check what the head looks like in the end, it still shows 1->2->3->4,
but as I went through the method, it seemed to be doing the right thing for when I removed a middle element (for ex, removing 3 yields giving me 1->2->4 at the end)
When looking at geeksforgeeks they implement it like this (and it works fine)
(this is just a snippet with delete rest can be found at https://www.geeksforgeeks.org/linked-list-set-3-deleting-node/):
class LinkedList1
{
Node head; // head of list
/* Linked list Node*/
class Node
{
int data;
Node next;
Node(int d)
{
data = d;
next = null;
}
}
/* Given a key, deletes the first occurrence of key in linked list */
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;
}
}
(There may be other things wrong with my code, but right now I am just focusing on removal of the first element not working)
I think the problem may be that I do not fully understand what is happening globally vs. locally if that makes sense?
For further clarification :
(Also further looking into it, I think there are a lot of differences in approach to mine vs. geeksforgeeks, but I think I narrowed down where my problem lies) Anyways, after moving some things around, I think my question is really about why their delete method works with a linked list object vs. just a linked list built using ListNodes in main, for example below :

// Practicing with Lists...
public class ListPrac1 {
public static ListNode head;
public static ListNode headExample; // the different example
public static void main(String[] args) {
ListPrac1 ll1= new ListPrac1();
ll1.push(4);
ll1.push(3);
ll1.push(2);
ll1.push(1);
ll1.delete(1);
System.out.println("done");
System.out.println("\nLinked List after Deletion of 1:");
ll1.printList();
// This is what they did basically while creating a LinkedList
// Object I guess and it works...
// but... with the same structure of delete method and just
// using ListNodes to build a list starting with
// variable headExample instead and then calling deleteMine.
// (which has the same structure as delete except a reference to
// the new head...)
ListNode headExample = new ListNode(1);
headExample.next = new ListNode(2);
headExample.next.next = new ListNode(3);
headExample.next.next.next = new ListNode(4);
deleteMine(1);
System.out.println();
System.out.println("\nLinked List starting with headExample after Deletion of 1:");
while (headExample != null) {
System.out.print(headExample.dat + " ");
headExample = headExample.next;
}
}
public static void printList() {
ListNode tnode = head;
while (tnode != null)
{
System.out.print(tnode.dat+" ");
tnode = tnode.next;
}
}
public static int delete(int deleteMe) {
// Store head node
ListNode temp = head, prev = null;
// If head node itself holds the key to be deleted
if (temp != null && temp.dat == deleteMe)
{
head = temp.next; // Changed head
return deleteMe;
}
// Search for the key to be deleted, keep track of the
// previous node as we need to change temp.next
while (temp != null && temp.dat != deleteMe)
{
prev = temp;
temp = temp.next;
}
// If key was not present in linked list
if (temp == null) return -1;
// Unlink the node from linked list
prev.next = temp.next;
return deleteMe;
}
public static int deleteMine(int deleteMe) {
// Store head node
ListNode temp = headExample, prev = null;
// If head node itself holds the key to be deleted
if (temp != null && temp.dat == deleteMe)
{
headExample = temp.next; // Changed head
return deleteMe;
}
// Search for the key to be deleted, keep track of the
// previous node as we need to change temp.next
while (temp != null && temp.dat != deleteMe)
{
prev = temp;
temp = temp.next;
}
// If key was not present in linked list
if (temp == null) return -1;
// Unlink the node from linked list
prev.next = temp.next;
return deleteMe;
}
public static void push(int new_data) {
ListNode new_node = new ListNode(new_data);
new_node.next = head;
head = new_node;
}
public static class ListNode {
int dat;
ListNode next;
public ListNode(int val) {
dat = val;
next = null;
}
}
}
Output yields :
done


Linked List after Deletion of 1:

2 3 4


Linked List starting with headExample after Deletion of 1:

1 2 3 4
So it works for their way when creating a LinkedList, but not the other way where I make one with Nodes.
The delete and deleteMine methods are the same except deleteMine references headExample (which is what builds my second list in the second part)
So, my question really is:
Shouldn’t the delete work in both cases? Since both the LinkedList and headExample reference their respective head variables, why is headExample not being modified after delete, but the LinkedList ll1 is?
I think the problem of your implementation is that you do not have a 'List'-object.
You have some instances of the ListNode class.
For a LinkedList you need to have an additional class that represents the List.
That List-class should have a ListNode variable that represents the head of the list. Look at the
class LinkedList1
{
Node head; // head of list
part. It has a member named 'head'.
When the delete method is called it changes the head member variable of the list object.
If the class ListPrac represents your list a starting point could look like this:
public class ListPrac {
// each instance of ListPrac has a ListNode that represents the head of the list.
ListNode head;
public static void main(String[] args) {
ListPrac theList = new ListPrac();
ListNode head = new ListNode(1);
head.next = new ListNode(2);
head.next.next = new ListNode(3);
head.next.next.next = new ListNode(4);
// here we assign a ListNode as the head of the list.
theList.head = head;
// the delete method is invoked on the list.
theList.delete(1);
//print the list to the console.
System.out.println(theList);
}
// not static because we operate on a ListPrac instance.
public int delete(int deleteMe) {
//...
public static class ListNode {
//...
#Override
public String toString(){
String nextNodeAsString = next == null ? "null" : next.toString();
return "{data="+dat+",next="+nextNodeAsString+"}";
}
}
//...
#Override
public String toString(){
return "a list: {head="+head.toString()+"}";
}
}
In the next step you should compare your and the other solution and try to spot the error.
Happy coding :)

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();
}
}
}

Insertion sort using Linked Integer Nodes

Hey there I have been trying to get an insertion sort method to work for a class I'm taking and we have been told to use insertion sort to sort a linked list of integers without using the linked list class already in the Java libraries.
Here is my inner Node class I have made it only singly linked as i don't fully grasp the circular doubly linked list concept yet
public class IntNode
{
public int value;
public IntNode next;
}
And here is my insertion sort method in the IntList class
public IntList Insertion()
{
IntNode current = head;
while(current != null)
{
for(IntNode next = current; next.next != null; next = next.next)
{
if(next.value <= next.next.value)
{
int temp = next.value;
next.value = next.next.value;
next.next.value = temp;
}
}
current = current.next;
}
return this;
}
The problem I am having is it doesn't sort at all it runs through the loops fine but doesn't manipulate the values in the list at all can someone please explain to me what I have done wrong I am a beginner.
you need to start each time from the first Node in your list, and the loop should end with the tail of your list -1
like this
public static IntList Insertion()
{
IntNode current = head;
IntNode tail = null;
while(current != null&& tail != head )
{
IntNode next = current;
for( ; next.next != tail; next = next.next)
{
if(next.value <= next.next.value)
{
int temp = next.value;
next.value = next.next.value;
next.next.value = temp;
}
}
tail = next;
current = head;
}
return this;
}
The insertion operation only works if the list being inserted into is already sorted - otherwise you're just randomly swapping elements. To start out, remove an element from the original list and construct a new list out of it - this list only has one element, hence it is sorted. Now proceed to remove the remaining elements from the original list, inserting them into the new list as you go. At the end the original list will be empty and the new list will be sorted.
I agree with the Zim-Zam opinion also.
The loop invariant of insertion sort also specifies this: "the subarray which is in sorted order".
Below is the code, I implemented for insertion sorting in which I created another linked list that contains the element in sorted order:
Node newList=new Node();
Node p = newList;
Node temp=newList;
newList.data=head.data;
head=head.node;
while(head!=null)
{
if(head.data<newList.data)
{
Node newTemp = new Node();
newTemp.data=head.data;
newTemp.node=newList;
newList=newTemp;
p=newList;
}
else
{
while(newList!=null && head.data>newList.data)
{
temp=newList;
newList=newList.node;
}
Node newTemp = new Node();
newTemp.data=head.data;
temp.node=newTemp;
newTemp.node=newList;
newList=p;
}
head=head.node;
}

How to add a display method to a Java Linked List implementation that displays only the first and the last 10 items on the list?

UPDATE: Thanks to all who answered I did what I was assigned to do. This is really a great forum and I was surprised to find so many helpful and friendly-minded people here :)
What I did was to modify the print method in the following way:
public static void print(ListNode start){
System.out.println("Printing the first 10 elements on the list:");
System.out.print("{");
ListNode previous = start;
ListNode current = start;
for (int i = 0; i<10; i++){
current=current.next;
}
for(ListNode node = start; node != current; node = node.next){
System.out.print(node);
}
System.out.println("}");
System.out.println("Printing the last 10 elements on the list:");
System.out.print("{");
while(current != null){
previous = previous.next;
current = current.next;
}
for(ListNode node = previous; node != current; node = node.next){
System.out.print(node);
}
System.out.println("}");
System.out.println("End of list");
}
END OF UPDATE
I'm learning Algorithms and Data structures in Java and I need to add a specific display method to an existing exercise Linked List implementation but I don't know how to do it.
So there is a linked list that contains many items (say thousands) and I need a display method that shows only the first and the last 10 items on the list.
Can you suggest to me a way to do it?
The Linked list implementation that I need to work on is the following:
import java.util.*;
public class Main {
public static class ListNode {
//A linked list node. The data field is represented by the field int data
//The next item is referenced by the reverence value next
int data;
ListNode next;
public ListNode(){
this.data = 0; this.next = null;
}
public ListNode(int data){
this();this.data = data;
}
public ListNode(int data, ListNode next){
this.data = data;this.next = next;
}
public String toString() {
return "[" + this.data + "]";
}
//The linked list is referenced by the first node.
//An empty list is referenced by a null reference.
//That's why all methods for the list are public static -
//(null doesn't have methods)
//Returns the beginning of a list with length "length"and
//elements with random values
public static ListNode generate(int length) {
ListNode start = null;
Random rn = new Random();
for(int i = 0; i < length; i++){
start = new ListNode(rn.nextInt(10000), start);
}
return start;
}
//Displays the list to the console from the specified starting point
public static void print(ListNode start){
System.out.print("{");
for(ListNode node = start; node != null; node = node.next){
System.out.print(node);
}
System.out.println("}");
}
//Counts how many elements there are in the list
public static int length(ListNode L){
int k=0;
for(;L!=null;k++,L=L.next);
return k;
}
//Returns a node with key searchd if found in the list
public static ListNode search(ListNode start, int searchd){
for(ListNode node = start; node != null; node = node.next){
if(node.data == searchd){ return node; }
}
return null;
}
//If a node with the specified key is found in the list L
//a new node with the value keyAfter is inserted after it.
public static void insertAfter(ListNode L, int key, int keyAfter){
while(L!=null && L.data!=key)L=L.next;
if(L!=null){
L.next= new ListNode(keyAfter,L.next);
}
}
//Inserts a node with key "keyBefore" before the node
//with the specified key
public static ListNode insertBefore(ListNode L, int key, int keyBefore){
ListNode p = null, r=L;
while(L!=null && L.data!=key){
p=L;L=L.next;
}
if(p!=null){
p.next= new ListNode(keyBefore,p.next);return r;
}
else{
p=new ListNode(keyBefore,L);return p;
}
}
//Inserts a new element with the specified key in a sorted list
//with ascending values so that the list remains sorted
public static ListNode insertOrd(ListNode L, int key){
ListNode p = null, r=L;
while(L!=null && L.data<key){
p=L;L=L.next;
}
if(p!=null){
p.next= new ListNode(key,p.next);return r;
}
else{
p=new ListNode(key,L);return p;
}
}
//Generates a sorted list with a specified lenght
public static ListNode generateOrd(int length) {
ListNode start = null;
Random rn = new Random();
for(int i = 0; i < length; i++){
start = insertOrd(start,rn.nextInt(10000));
}
return start;
}
//Takes two ordered lists and returns a merged and sorted list
//that combines the elements in the original lists
public static ListNode merge(ListNode a, ListNode b){
if(a==null)return b;
if(b==null)return a;
ListNode r = null;
if(a.data<=b.data){
r=a;a=a.next;
}else{
r=b;b=b.next;
}
ListNode last=r;
while(a!=null && b!=null){
if(a.data<=b.data){
last.next=a;a=a.next;
}else{
last.next=b;b=b.next;
}
last=last.next;
}
if(a!=null)last.next=a;else last.next=b;
return r;
}
//Splits a list evenly and returns the beginning of the 2-nd part
public static ListNode split(ListNode L){
int n=length(L)/2;
ListNode t=L;
for(int i=0;i<n-1;i++,t=t.next);
ListNode secPart = t.next;
t.next=null;
return secPart;
}
//Sorts a list in an ascending order
public static ListNode mrgSort(ListNode L){
if(L==null || L.next==null)return L;
ListNode b = split(L);
L=mrgSort(L); b= mrgSort(b);
return merge(L,b);
}
};//End of class ListNode
public static void main(String[] args){
ListNode a = ListNode.generateOrd(10);
ListNode.print(a);
ListNode b = ListNode.generateOrd(10);
ListNode.print(b);
a=ListNode.merge(a,b);
ListNode.print(a);
b=ListNode.split(a);
ListNode.print(a);
ListNode.print(b);
ListNode c = ListNode.generate(20);
ListNode.print(c);
c = ListNode.mrgSort(c);
ListNode.print(c);
}
}
Alright, I am not going to write the code for you but ill tell you how to go about doing it.
Initially say you have two pointers (head1 and head2) which point to the first node of the list. Move head2 ten steps forward keeping head1 at the same place.
Now, after ten steps you have head1 at 0 and head2 at 9th position. Now move both together till head2 hits NULL. Once head2 hits NULL, start moving head1 alone and print each node till head1 reaches head2.
Hope this helps
This is a fairly odd implementation of a Linked list.
What sticks out is
The amount of static members
No class representing the actual list.
The static members in node should be placed in a LinkedList class. Check out the members of the JavaAPIs LinkedList class.
The other members are similar to what is found in the Collections class.
As it stands the easiest solution is as peraueb suggests in the comments follow the print method; i.e. Do as print does, and store the link to the 10:th to last node. noMAD's idea will work fine there.
The usual way to do it would be to have a LinkedList class handle references / links to the first and the last Node. The Node itself should contain links/references to the previous as well as the next node. This is the suggestion of Nactives answer. Now you are manually dealing with those in main(...).
For that you need a reference to your first and your last item.
Best way is also to make it a duuble linked list: http://en.wikipedia.org/wiki/Doubly_linked_list
Basicly, at the front of your list it is still the same.
But now you can also access your list at the end and move to the beginning of your list.

Invert linear linked list

a linear linked list is a set of nodes. This is how a node is defined (to keep it easy we do not distinguish between node an list):
class Node{
Object data;
Node link;
public Node(Object pData, Node pLink){
this.data = pData;
this.link = pLink;
}
public String toString(){
if(this.link != null){
return this.data.toString() + this.link.toString();
}else{
return this.data.toString() ;
}
}
public void inc(){
this.data = new Integer((Integer)this.data + 1);
}
public void lappend(Node list){
Node child = this.link;
while(child != null){
child = child.link;
}
child.link = list;
}
public Node copy(){
if(this.link != null){
return new Node(new Integer((Integer)this.data), this.link.copy());
}else{
return new Node(new Integer((Integer)this.data), null);
}
}
public Node invert(){
Node child = this.link;
while(child != null){
child = child.link;
}
child.link = this;....
}
}
I am able to make a deep copy of the list. Now I want to invert the list so that the first node is the last and the last the first. The inverted list has to be a deep copy.
I started developing the invert function but I am not sure. Any Ideas?
Update: Maybe there is a recursive way since the linear linked list is a recursive data structure.
I would take the first element, iterate through the list until I get to a node that has no child and append the first element, I would repeat this for the second, third....
I sometimes ask this question in interviews...
I would not recommend using a recursive solution, or using a stack to solve this. There's no point in allocating O(n) memory for such a task.
Here's a simple O(1) solution (I didn't run it right now, so I apologize if it needs some correction).
Node reverse (Node current) {
Node prev = null;
while (current != null) {
Node nextNode = current.next;
current.next = prev;
prev = current;
current = nextNode;
}
return prev;
}
BTW: Does the lappend method works? It seems like it would always throw a NullReferenceException.
There's a great recursive solution to this problem based on the following observations:
The reverse of the empty list is the empty list.
The reverse of a singleton list is itself.
The reverse of a list of a node N followed by a list L is the reverse of the list L followed by the node N.
You can therefore implement the reverse function using pseudocode along these lines:
void reverseList(Node node) {
if (node == null) return; // Reverse of empty list is itself.
if (node.next == null) return; // Reverse of singleton list is itself.
reverseList(node.next); // Reverse the rest of the list
appendNodeToList(node, node.next); // Append the new value.
}
A naive implementation of this algorithm runs in O(n2), since each reversal requires an append, which requires an O(n) scan over the rest of the list. However, you can actually get this working in O(n) using a clever observation. Suppose that you have a linked list that looks like this:
n1 --> n2 --> [rest of the list]
If you reverse the list beginning at n2, then you end up with this setup:
n1 [reverse of rest of the list] --> n2
| ^
+------------------------------------------+
So you can append n1 to the reverse of the rest of the list by setting n1.next.next = n1, which changes n2, the new end of the reverse list, to point at n1:
[reverse of the rest of the list] --> n2 --> n1
And you're golden! Again more pseudocode:
void reverseList(Node node) {
if (node == null) return; // Reverse of empty list is itself.
if (node.next == null) return; // Reverse of singleton list is itself.
reverseList(node.next); // Reverse the rest of the list
node.next.next = node; // Append the new value.
}
EDIT: As Ran pointed out, this uses the call stack for its storage space and thus risks a stack overflow. If you want to use an explicit stack instead, you can do so like this:
void reverseList(Node node) {
/* Make a stack of the reverse of the nodes. */
Stack<Node> s = new Stack<Node>();
for (Node curr = node; node != null; node = node.next)
s.push(curr);
/* Start unwinding it. */
Node curr = null;
while (!s.empty()) {
Node top = s.pop();
/* If there is no node in the list yet, set it to the current node. */
if (curr == null)
curr = top;
/* Otherwise, have the current node point to this next node. */
else
curr.next = top;
/* Update the current pointer to be this new node. */
curr = top;
}
}
I believe that this similarly inverts the linked list elements.
I would treat the current list as a stack (here's my pseudo code):
Node x = copyOf(list.head);
x.link = null;
foreach(node in list){
Node temp = copyOf(list.head);
temp.link = x;
x = temp;
}
At the end x will be the head of the reversed list.
I more fammiliar whit C, but still let me try. ( I just do not sure if this runs in Java, but it should)
node n = (well first one)
node prev = NULL;
node t;
while(n != NULL)
{
t = n.next;
n.next = prev;
prev = n;
n = t;
}
Reversing a single-linked list is sort of a classic question. It's answered here as well (and well answered), it does not requires recursion nor extra memory, besides a register (or 2) for reference keeping.
However to the OP, I guess it's a school project/homework and some piece of advice, if you ever get to use single linked list for some real data storage, consider using a tail node as well. (as of now single linked lists are almost extinct, HashMap buckets comes to mind, though).
Unless you have to check all the nodes for some condition during 'add', tail is quite an improvement. Below there is some code that features the reverse method and a tail node.
package t1;
public class SList {
Node head = new Node();
Node tail = head;
private static class Node{
Node link;
int data;
}
void add(int i){
Node n = new Node();
n.data = i;
tail = tail.link =n;
}
void reverse(){
tail = head;
head = reverse(head);
tail.link = null;//former head still links back, so clear it
}
private static Node reverse(Node head){
for (Node n=head.link, link; n!=null; n=link){//essentially replace head w/ the next and relink
link = n.link;
n.link = head;
head = n;
}
return head;
}
void print(){
for (Node n=head; n!=null;n=n.link){
System.out.println(n.data);
}
}
public static void main(String[] args) {
SList l = new SList();
l.add(1);l.add(2);l.add(3);l.add(4);
l.print();
System.out.println("==");
l.reverse();
l.print();
}
}
I was wondering something like that(I didnt test it, so):
invert(){
m(firstNode, null);
}
m(Node v, Node bef){
if(v.link != null)
m(v.link,v);
else
v.link=bef;
}
Without much testing,
Node head = this;
Node middle = null;
Node trail = null;
while (head != null) {
trail = middle;
middle = head;
head = head.link;
middle.link = trail;
}
head = middle;
return head;
public ListNode Reverse(ListNode list)
{
if (list == null) return null;
if (list.next == null) return list;
ListNode secondElem = list.next;
ListNode reverseRest = Reverse(secondElem);
secondElem.Next = list;
return reverseRest;
}
Hope this helps.

Categories