I wrote a recursive backtracking algorithm for the so-called "Coin Change Problem". I store the coin values (int) in a self-written LinkedList ("ll") and each of those LinkedLists is stored inside one master LinkedList ("ll_total"). Now, when I try to print out the LinkedLists inside the master LinkedList, all I get is "LinkedList#1e88b3c". Can somebody tell me how to modify the code, in order to print out the coin values properly?
I would also like the algorithm to chose the LinkedList with the least values stored inside, as it would represent the optimal coin combination for the "coin change problem".
import java.util.Scanner;
public class CoinChange_Backtracking {
static int[] coins = {3, 2, 1};
static int index_coins = 0;
static int counter = 0;
static LinkedList ll = new LinkedList();
static LinkedList ll_total = new LinkedList();
public static void main(String[] args) {
Scanner myInput = new Scanner(System.in);
int amount;
System.out.println("Put in the amount of money: ");
amount = myInput.nextInt();
if (amount < 101) {
//Start recursion and display result.
recursiveFunction(coins, amount, index_coins, ll);
ll_total.show_ll();
} else {
System.out.println("The value must be less than 100!");
}
}
public static LinkedList recursiveFunction(int[] coins, int amount, int index_coins, LinkedList ll) {
//The current coin is being omitted. (If index_coins + 1 is still within range.)
if ((index_coins + 1) < coins.length) {
ll = recursiveFunction(coins, amount, index_coins + 1, ll);
ll_total.insert_ll(ll);
for (int i = 0; i < counter; i++) {
ll.deleteAt(0);
}
counter = 0;
}
//The current coin is not being omitted. (If there is still some change left and value of change isn't lower than value of current coin.)
if (amount != 0) {
if (amount >= coins[index_coins]) {
ll.insert(coins[index_coins]);
counter++;
ll = recursiveFunction(coins, amount - coins[index_coins], index_coins, ll);
}
}
return ll;
}
}
public class LinkedList {
Node head;
public void insert(int data) {
Node node = new Node();
node.data = data;
node.next = null;
if (head == null) {
head = node;
} else {
Node n = head;
while(n.next != null) {
n = n.next;
}
n.next = node;
}
}
public void insert_ll(LinkedList ll) {
Node node = new Node();
node.ll = ll;
node.next = null;
if (head == null) {
head = node;
} else {
Node n = head;
while(n.next != null) {
n = n.next;
}
n.next = node;
}
}
public void deleteAt(int index) {
if(index == 0) {
head = head.next;
} else {
Node n = head;
Node n1 = null;
for (int i = 0; i < index - 1; i++) {
n = n.next;
}
n1 = n.next;
n.next = n1.next;
n1 = null;
}
}
public void show() {
Node node = head;
while(node.next != null) {
System.out.println(node.data);
node = node.next;
}
System.out.println(node.data);
}
public void show_ll() {
Node node = head;
while(node.next != null) {
System.out.println(node.ll);
node = node.next;
}
System.out.println(node.ll);
}
//A toString method I tried to implement. Causes an array error.
/*
public String toString() {
Node n = head.next;
String temp = "";
while (n != null) {
temp = temp + n.data + " ";
n = n.next;
}
return temp;
}
*/
}
public class Node {
int data;
LinkedList ll;
Node next;
}
To answer your question. You are printing the linked list object, see here System.out.println(node.ll);
There are several ways to do it right. One approach is to question why you use Node and LinkedList the way you do ? A node can have a linked list and a linked list can have a node, I believe this is not really what you wanted. Maybe you can make it work, but from a design point of view in my experience it is not good. I find it confusing and it's a great source of bugs.
I try to list some points that caught my eye (or that my IDE had caught for my eyes).
You are not closing the Scanner object. Just close it at the end of the program or use the try-with-resources.
As mentioned before you have linked list that has a node and a node that has a linked list. You are not using that correctly in your program. I recommend to review that approach. It is error prone.
Also simply use the LinkedList of the Java library unless you have a good reason not to. It works fine and offers all you need.
You use many static, global (within the scope of the package) variables. In this case I think you can avoid that. coins does not need to be given as a parameter every time. It should be an immutable object. It is not supposed to change.
...
And I am not sure if it is a backtracking algorithm. It is certainly tree recursive. This just as a side note.
I'd like to propose a solution that looks similar to yours. I'd probably do it differently my way, but then it probably takes time to understand it. I try to adopt your style, which I hope helps. I simplified the program.
In order to print the result, simply write a helper function.
The linked list is an object. You have to make a copy of the list every time you call the recursion in order to work on a dedicated object. Otherwise you modify the same object while recursing different paths.
You can simply use a list of lists. A global list of lists (within package scope), and a list of which you make a copy every time you recurse. When you reach a good base case you add it to the global list. Otherwise just ignore.
import java.util.LinkedList;
import java.util.Scanner;
public class CoinChangeBacktracking {
static final int[] COINS = {3, 2, 1};
static final LinkedList<LinkedList<Integer>> changes = new LinkedList<>();
public static void main(String[] args) {
Scanner myInput = new Scanner(System.in);
int amount;
System.out.println("Put in the amount of money: ");
amount = myInput.nextInt();
if (amount < 101) {
// Start recursion and display result.
recursiveFunction(amount, 0, new LinkedList<>());
print(changes);
} else {
System.out.println("The value must be less than 100!");
}
myInput.close();
}
static void recursiveFunction(int amount, int index,
LinkedList<Integer> list) {
// exact change, so add it to the solution
if (amount == 0) {
changes.add(list);
return;
}
// no exact change possible
if (amount < 0 || index >= COINS.length) {
return;
}
// explore change of amount without current coin
recursiveFunction(amount, index + 1, new LinkedList<>(list));
// consider current coin for change and keep exploring
list.add(COINS[index]);
recursiveFunction(amount - COINS[index], index, new LinkedList<>(list));
}
static void print(LinkedList<LinkedList<Integer>> ll) {
for (LinkedList<Integer> list : ll) {
for (Integer n : list) {
System.out.print(n + ", ");
}
System.out.println();
}
}
}
Related
Small problem i am having with a program here. I am trying to create a program that adds Words to Linked Lists within a Array depending on their hashCode, determined by my hashFunction. If they have the same value for their hashCode they get added into a Linked List. I have a small count method that counts how many times a word is in the List. It works by computing the value for their hashFunction. It then goes to that value in the array, and iterates through the LinkedList until it reaches a Null value. It has a count variable which is incremented each time it finds the word in the list. This is my code:
public class test{
public static class Node<T>{
public T data;
public Node<T> next;
public Node(){
}
public Node(T data, Node<T> next)
{
this.data = data;
this.next = next;
}
}
static Node[] array = new Node[512];
public static void add(String word){
int position = hashFunction(word);
if(array[position] == null){
array[position] = new Node(word, null);
}else{
Node newHead = new Node(word, array[position]);
array[position] = newHead;
}
}
public static void remove(String word){
int remove = hashFunction(word);
Node head = array[remove];
if(head.data == word){
head = head.next;
System.out.println("Found");
}else if(head.data != word){
for(; array[remove] != null; array[remove] = array[remove].next){
if(array[remove].data == word){
array[remove] = array[remove].next;
}
}
System.out.println("Yusuf");
}
}
public static int count(String word){
int number = 0;
int position = hashFunction(word);
for(; array[position] != null; array[position] = array[position].next){
if(array[position].data == word){
number++;
}
}
System.out.println(number);
return number;
}
public static int hashFunction(String a){
int sum = 1;
for(int i = 0; i<a.length(); i++){
char b = a.charAt(i);
int value = (int) b;
sum *= value;
}
return sum % array.length;
}
public static void addthings(String word, int n){
for(int i = 0; i<n; i++){
add(word);
}
}
public static void main(String[] args) {
addthings("abc", 500000);
count("abc");
count("abc");
count("abc");
count("abc");
}
}
My issue is the first time I add values in it and check how many times it occurs it works fine, but any more calls to the Count method after that returns 0 for some reason.
I have another issue too which is my remove method isn't removing the items from the Linked List I want it too. The code iterates through the List, and when it finds the item which is meant to be removed, it removes the pointer from there and points it to the next value. This isn't working however.
Can someone show me how to fix these two issues please?
Thanks.
In your function if you write something Node head it means you are creating some local instance for a Node. If you set head = head.next this will simply change the state of your local instance variable not the state of your array.
You are checking if the first node contains the data which you are looking and trying to remove it then you have to remove it from your source Array(Array in which your references reside).So you can write something like this:
if(head.data == word)
array[remove] = head.next;
This was an example. The point is that you are not chaning things in your array but in your local variable.
public static void remove(String word){
int remove = hashFunction(word);
Node head = array[remove];
if(head.data == word){
head = head.next;
System.out.println("Found");
}else if(head.data != word){
for(; array[remove] != null; array[remove] = array[remove].next){
if(array[remove].data == word){
array[remove] = array[remove].next;
}
}
System.out.println("Yusuf");
}
}
A second mistake is in second clause where you just set array[remove] = array[remove].next;
It will break your linkedlist into two different linkedlist. Suppose you have 4 elements in linkedlist A,B,C,D and you remove B and there were pointers like this A->B->C->D then you are adding no pointers from A -> C. Here you break your linkedlist.
You can use while loop that will work easily.
Given singly Linked List: 1 -> 2 -> 3 -> 4 -> 5 -> null
Modify middle element as doubly Linked List Node
here middle element is 3
3 -> next should point to 4
3 -> prev should point to 1
Can any one suggest how can it be done ? interviewer gave me hint use interface. but I couldn't figure it out how.
I have to iterate over this linked list and print all the node and when it reaches to the middle, print where next and prev is pointing to, then print till the end of the list.
Expected output : 1, 2, Middle: 3, Prev: 1, Next: 4, 5
I'm facing problem in adding the middle node.
So, this "works", but if this is expected to be answered on an interview, it is way too much work.
LinkedList
public class LinkedList {
public interface Linkable<V, L extends Linkable> {
V getValue();
L getNext();
void setNext(L link);
}
public static class Node implements Linkable<Integer, Linkable> {
int value;
Linkable next;
Node(int value) {
this.value = value;
}
#Override
public Integer getValue() {
return value;
}
#Override
public Linkable getNext() {
return next;
}
#Override
public void setNext(Linkable link) {
this.next = link;
}
}
private Linkable head;
public boolean isEmpty() {
return this.head == null;
}
public Linkable getHead() {
return head;
}
public void add(int v) {
Node next = new Node(v);
if (isEmpty()) {
this.head = next;
} else {
Linkable tmp = this.head;
while (tmp.getNext() != null) {
tmp = tmp.getNext();
}
tmp.setNext(next);
}
}
}
Interface
interface DoublyLinkable<V, L extends LinkedList.Linkable> extends LinkedList.Linkable<V,L> {
LinkedList.Linkable getPrev();
void setPrev(LinkedList.Linkable prev);
}
DoubleNode
public class DoubleNode extends LinkedList.Node implements DoublyLinkable<Integer, LinkedList.Linkable> {
LinkedList.Linkable prev;
public DoubleNode(int value) {
super(value);
}
#Override
public LinkedList.Linkable getPrev() {
return prev;
}
#Override
public void setPrev(LinkedList.Linkable prev) {
this.prev = prev;
}
}
Driver
Outputs
1, 2, Middle: 3, Prev: 1, Next: 4, 5
public class Driver {
public static LinkedList getList() {
LinkedList list = new LinkedList();
for (int i = 1; i <= 5; i++) {
list.add(i);
}
return list;
}
public static void main(String[] args) {
LinkedList list = getList();
LinkedList.Linkable head = list.getHead();
LinkedList.Linkable beforeMiddle = null;
LinkedList.Linkable middle = list.getHead();
LinkedList.Linkable end = list.getHead();
if (head != null) {
// find the middle of the list
while (true) {
if (end.getNext() == null || end.getNext().getNext() == null) break;
beforeMiddle = middle;
middle = middle.getNext();
end = end.getNext().getNext();
}
// Replace middle by reassigning the pointer to it
if (beforeMiddle != null) {
DoubleNode n = new DoubleNode((int) middle.getValue()); // same value
n.setPrev(list.getHead()); // point back to the front
n.setNext(middle.getNext()); // point forward to original value
beforeMiddle.setNext((DoublyLinkable) n);
middle = beforeMiddle.getNext();
}
// Build the "expected" output
StringBuilder sb = new StringBuilder();
final String DELIMITER = ", ";
head = list.getHead();
boolean atMiddle = false;
if (head != null) {
do {
if (head instanceof DoublyLinkable) {
atMiddle = true;
String out = String.format("Middle: %d, Prev: %d, ", (int) head.getValue(), (int) ((DoublyLinkable) head).getPrev().getValue());
sb.append(out);
} else {
if (atMiddle) {
sb.append("Next: ");
atMiddle = false;
}
sb.append(head.getValue()).append(DELIMITER);
}
head = head.getNext();
} while (head != null);
}
sb.setLength(sb.length() - DELIMITER.length());
System.out.println(sb.toString());
}
}
}
By definition, a single-linked list consists of single-linked nodes only, and a double-linked consists of double-linked nodes only. Otherwise. it is neither.
By definition the field prev of a double-linked list must point to the previous element.
Whatever you are supposed to build. It's something not well specified. So if you really were asked this in an interview (and did not misunderstand the question - maybe he wanted you to point out that ghis violates the interface?) this is a case for the code horror stories of http://thedailywtf.com/ - section "incompetent interviewers".
If you haven't, you'd better define a lenght() function so given one linked list you can know how many nodes does it have.
Thanks to the response of Cereal_Killer to the previous version of this answer, I noticed that the list is firstly a singly linked list, and you just have to make the middle node be linked both to the next node and to some previous node.
Now I guess that you have defined two structures (Struct, Class or whatever depending on the language you're using). So lets say you have Node_s defined as a node with only a next pointer, and Node_d with both a next and a prev pointer. (Node_d may inherite from Node_s so you just have to add the prev attribute in the child class). Knowing this, the code above should be doing what you need:
function do_it(my_LinkedList linkedList){
int i_middle;
int length = linkedList.length();
if ( (length รท 2 ) != 0 ) i_middle = length / 2;
else return -1;
Node_s aux = linkedList.first();
int index = 0;
Node_d middle= null;
while (aux != null) {
if (index == i_middle - 1){ //now aux is the middle's previous node
middle.data = aux.next.data; //aux.next is the middle singly node, we assignate the data to the new double linked node
middle.prev = aux; //as we said, aux is the prev to the middle
midle.next = aux.next.next; //so aux.next.next is the next to the middle
print(what you need to print);
}else {
print("Node " + index " next: "+ aux.next);
}//end if
index++;
aux = aux.next;
} //end while
}//end function
This previous code should be doing what you need. I wrote the answer in some kind of pseudo-java code so if you're not familiar with Java or don't understand what my pseudo-code does, please let me know. Anyway, the idea of my code may present some troubles depending on the language you're working with, so you'll have to adapt it.
Note that at the end of the execution of this program, your data structure won't be a singly linked list, and neither a double one, since you'll have linkedList.length() - 1 nodes linked in a signly way but the middle one will have two links.
Hope this helps.
As part of an assignment, I have to write a method that will print out repeating values in a linked list, as well as how many times they occur. Below is the method printRepeats() which uses the helper method countRepeats(ListNode node).
The issue is that the output of my method prints repeating values over and over again. For example, in a list with values 1 1 1 2 3 4 5 6 7 6, the output is 1 (Occurences = 3) 1 (Occurences = 3) 1 (Occurences = 3) 6 (Occurences = 2) 6 (Occurences = 2). Any value that repeats should only print once. Any suggestions? Thanks in advance!
public class LinkedList
{
private ListNode first;
public void printRepeats()
{
String ans = "";
ListNode temp = first;
while(temp != null)
{
if(countRepeats(temp) > 1 && ans.indexOf((int)temp.getValue()) == -1)
{
ans += temp.getValue();
System.out.print(temp.getValue() + " (Occurences = " + countRepeats(temp) + ") ");
}
temp = temp.getNext();
}
if(ans.length() == 0)
System.out.print("None of the elements repeat.");
}
private int countRepeats(ListNode node)
{
ListNode temp = first;
int count = 0;
while(temp != null)
{
if((int)temp.getValue() == (int)node.getValue())
count++;
temp = temp.getNext();
}
return count;
}
}
Considering that you must not use any other data structures than a LinkedList, you could:
Create another ListNode element as the first element of a list called "repeatedElements", that must contain pairs element/repetitions of such element.
When counting the repetitions of a single element, insert the element and the number of repetitions it has in "repeatedElements" list.
Before counting the number of repetitions of an element, sweep the repeatedElements list for the element. If the element is present, DO NOT print the output. If it is not, repeat your code as usual.
The system I described will contain more information than the specifically required (the number of repetitions of each element is stored), but it is likely that it will be needed again.
For counting occurrences you need to maintain track record of visited node also like if you have already count any node then need not to pick again those come on link list. Below program clearly explains this-
import java.util.ArrayList;
public class CustomLinkList {
public static void main(String[] args) {
ListNode linkedList = new ListNode(15);
linkedList.next =new ListNode(67);
linkedList.next.next =new ListNode(15);
linkedList.next.next.next =new ListNode(65);
linkedList.next.next.next.next =new ListNode(13);
linkedList.next.next.next.next.next =new ListNode(98);
linkedList.next.next.next.next.next.next =new ListNode(33);
linkedList.next.next.next.next.next.next.next =new ListNode(29);
linkedList.next.next.next.next.next.next.next.next =new ListNode(15);
ListNode printList = linkedList;
System.out.println("Custom Link List is ::: ");
while (printList.next != null){
System.out.printf("%d ",printList.info);
printList = printList.next;
}
System.out.println();
CustomLinkList.occurancesOfElement(linkedList);
}
public static void occurancesOfElement(ListNode listNode){
ArrayList<Integer> visitedNode = new ArrayList();
while(listNode !=null){
ListNode node = listNode;
int count = 0;
while (node !=null)
{
if(listNode.info == node.info && !visitedNode.contains(node.info)) {
count++;
}
node = node.next;
}
if(!visitedNode.contains(listNode.info))
System.out.println("Occurences of : "+listNode.info+" is "+ count);
visitedNode.add(listNode.info);
listNode = listNode.next;
}
}
}
class ListNode {
int info;
ListNode next;
ListNode(int info){
this.info = info;
next = null;
}
}
class DoublyListNode {
int info;
DoublyListNode previous;
DoublyListNode next;
}
}
I'm trying to implement a removeMax() method in this PQ class. The PQ is implemented with a singly-linked list. I can't seem to wrap my head around how you could scan the entire list for the largest value. Any guidance would be appreciated. Here's the whole class:
import java.util.NoSuchElementException;
public class UnorderedLinkedListMaxPQ<Item extends Comparable<Item>> {
private int N;
private Node first;
private class Node {
private Item item;
private Node next;
}
public UnorderedLinkedListMaxPQ() {
first = null;
N = 0;
}
public boolean isEmpty() {
return N == 0;
}
public int size() {
return N;
}
public void insert(Item item) {
Node oldfirst = first;
first = new Node();
first.item = item;
first.next = oldfirst;
N++;
}
public Item removeMax() {
if (isEmpty()) { throw new NoSuchElementException("PQ underflow"); }
else if (N == 1) {
Item item = first.item;
first = first.next;
N--;
return item;
}
else if (N != 0) {
// ?
}
}
public String toString() {
Node counter = first;
String string = "";
while (counter != null) {
string = string + counter.item + ", ";
counter = counter.next;
}
return string;
}
private boolean less(Item v, Item w) {
return (v.compareTo(w) < 0);
}
public static void main(String[] args) {
UnorderedLinkedListMaxPQ<Integer> pq = new UnorderedLinkedListMaxPQ<Integer>();
pq.insert(32);
pq.insert(7);
pq.insert(18);
pq.insert(2);
StdOut.println("The priority queue contains (" + pq.toString() + "). \n");
while (!pq.isEmpty())
StdOut.println(pq.removeMax());
}
}
Generally when iterating through a linked list manually, you make a variable called walker and initialize it to first. Then you can do something like this
while (walker != null) {
// Do something
walker = walker.next;
}
to traverse through the list. In your case, you'll need to keep track of the maximum value as you traverse.
To remove a value from a linked list, you "link around it", meaning that you set the previous node's next to the next of the value you're trying to remove. Since your list is singly-linked, you also need to keep track of the previous element as you go along, because otherwise you have a pointer to it after you decide which element you're removing.
Example:
aNode.next = aNode.next.next;
This removes the node aNode.next from your linked-list.
java hasPriorityQueue , you dont have to impl yourself
see doc here
http://docs.oracle.com/javase/7/docs/api/java/util/PriorityQueue.html
PQ is impl by HEAP
http://en.wikipedia.org/wiki/Heap_(data_structure)
remove is O(lgn) no need to scan through
You know how to scan the list you do that in toString
The items extend comparable so you can compare them to each other.
Start with a max set to the first and iterate through compaing to max, if the value's greater set max to it.
Because you're doing a remove and the list is a single link one you'll need to remember the previous node to max too you'll need to set it's next to that of max afterwards.
Another approach is to scan down the list on insert and insert in order the the max is then always the first.
So the app reads from an external file a bunch of strings, each on a separate line.
For example:
and
cake
here
It is not arranged in any particular order. I need to read these letters and put them into linked list and finally sort them.
I need help on doing that:
Here is the current code:
import java.util.*;
import java.io.*;
public class LinkedList
{
static File dataInpt;
static Scanner inFile;
public static void main(String[] args) throws IOException
{
dataInpt=new File("C:\\lldata.txt");
inFile=new Scanner(dataInpt);
Node first = insertInOrder();
printList(first);
}
public static Node getNode(Object element)
{
Node temp=new Node();
temp.value=element;
temp.next=null;
return temp;
}
public static void printList(Node head)
{
Node ptr; //not pointing anywhere
for(ptr=head;ptr!=null;ptr=ptr.next)
System.out.println(ptr.value);
System.out.println();
}
public static Node insertInOrder()
{
Node first=getNode(inFile.next());
Node current=first,previous=null;
Node last=first;
int count=0;
while (inFile.hasNext())
{
if (previous!=null
&& ((String)current.value).compareTo((String)previous.value) > 0)
{
last.next=previous;
previous=last;
}
if (previous!=null
&& ((String)current.value).compareTo((String)previous.value) < 0)
{
current.next=last;
last=current;
}
previous=current;
current=getNode(inFile.next());
}
return last;
}
}
But that gives an infinite loop with "Cat".
Here is the data file:
Lol
Cake
Gel
Hi
Gee
Age
Rage
Tim
Where
And
Kite
Jam
Nickel
Cat
Ran
Jug
Here
Okay, self-study. Split the reading and inserting. Though old and new code both have 14 lines of code,
it makes it more intelligable.
public static Node insertInOrder() {
Node first = null;
while (inFile.hasNext()) {
String value = inFile.next().toString();
first = insert(first, value);
}
return first;
}
/**
* Insert in a sub-list, yielding a changed sub-list.
* #param node the sub-list.
* #param value
* #return the new sub-list (the head node might have been changed).
*/
private static Node insert(Node node, String value) {
if (node == null) { // End of list
return getNode(value);
}
int comparison = node.value.compareTo(value);
if (comparison >= 0) { // Or > 0 for stable sort.
Node newNode = getNode(value); // Insert in front.
newNode.next = node;
return newNode;
}
node.next = insert(node.next, value); // Insert in the rest.
return node;
}
This uses recursion (nested "rerunning"), calling insert inside insert. This works like a loop, or work delegation to a clone, or like a mathematical inductive proof.
Iterative alternative
also simplified a bit.
private static void Node insert(Node list, String value) {
Node node = list;
Node previous = null;
for (;;) {
if (node == null || node.value.compareTo(value) >= 0) {
Node newNode = getNode(value);
newNode.next = node;
if (previous == null)
list = newNode;
else
previous.next = newNode;
break;
}
// Insert in the rest:
previous = node;
node = node.next;
}
return list;
}
public static Node insertInOrder()
{
Node first=getNode(inFile.next());
Node current=first,previous=null;
Node last=first;
int count=0;
while (inFile.hasNext())
{
if (previous!=null
&& ((String)current.value).compareTo((String)previous.value) > 0)
{
last.next=previous;
previous=last;
}
if (previous!=null
&& ((String)current.value).compareTo((String)previous.value) < 0)
{
current.next=last;
last=current;
}
previous=current;
current=getNode(inFile.next());
}
return last;
}
First of all, you never do anything with the last line read from the file, so that's not ever inserted. You have to read the line and create the new Node before relinking next pointers.
Then, if last and previous refer to the same Node and the data of current is larger than that of previous,
if (previous!=null
&& ((String)current.value).compareTo((String)previous.value) > 0)
{
last.next=previous;
previous=last;
}
You set last.next = last, breaking the list. From the code (in particular the absence of a sort(Node) function), it seems as though you want to sort the list as it is created. But you only ever compare each new Node with one other, so that doesn't maintain order.
For each new node, you have to find the node after which it has to be inserted, scanning from the front of the list, and modify current.next and the predecessor's next.
In relatively simple code like that in your question, a good exercise to understanding it is to work through a few interations of your loop, inspecting the values of all your local variable to see the effect of your code. You can even do it by hand if the code is simple. If it is too difficult to do by hand, your code is probably too complicated. If you can't follow it, how can you know if you are doing what you intend. For example, I could be wrong, but this appears the be the state at the top of each iteration of the loop. It starts falling apart on the third time through, and by the fourth you have a severe problem as your list becomes disjointed.
1)last = first = Lol, current = previous = null
Lol->null
2)last = first = previous = Lol, current = Cake
Lol->Lol
3)first = Lol, last = Cake, previous = Cake, current = Gel
Cake->Lol->Lol
4)first = Lol, last = Cake, previous = Cake, current = Hi
Cake->Gel, Lol->Lol
Quite honestly, if I were running the course, I would consider the correct answer to be:
List<String> list = new LinkedList<String>();
// read in lines and: list.add(word);
Collections.sort(list);
Ok, I don't remember exactly school theory about insertion sort, but here is somehow a mix of what I think it is and your code:
import java.io.File;
import java.io.IOException;
import java.util.Scanner;
public class LinkedList {
public static class Node {
public String value;
public Node next;
}
static File dataInpt;
static Scanner inFile;
public static void main(String[] args) throws IOException {
inFile = new Scanner("Lol\r\n" + "Cake\r\n" + "Gel\r\n" + "Hi\r\n" + "Gee\r\n" + "Age\r\n" + "Rage\r\n" + "Tim\r\n" + "Where\r\n"
+ "And\r\n" + "Kite\r\n" + "Jam\r\n" + "Nickel\r\n" + "Cat\r\n" + "Ran\r\n" + "Jug\r\n" + "Here");
Node first = insertInOrder();
printList(first);
}
public static Node getNode(String element) {
Node temp = new Node();
temp.value = element;
temp.next = null;
return temp;
}
public static void printList(Node head) {
Node ptr; // not pointing anywhere
for (ptr = head; ptr != null; ptr = ptr.next) {
System.out.println(ptr.value);
}
System.out.println();
}
public static Node insertInOrder() {
Node current = getNode(inFile.next());
Node first = current, last = current;
while (inFile.hasNext()) {
if (first != null && current.value.compareTo(first.value) < 0) {
current.next = first;
first = current;
} else if (last != null && current.value.compareTo(last.value) > 0) {
last.next = current;
last = current;
} else {
Node temp = first;
while (current.value.compareTo(temp.value) < 0) {
temp = temp.next;
}
current.next = temp.next;
temp.next = current;
}
current = getNode(inFile.next());
}
return first;
}
}
And it works like a charm. Of course this far from optimal, both in terms of performance and code reuse.