I'm trying to reverse a list, but l want to keep my initial list. My function reverse doesn't keep the initial list
For example I want to reverse this:
Node n = new Node(1,new Node(12, new Node(34, new Node(3, Node.NIL))));
and my function is:
public Node reverse(){
Node p= this;
if(p == NIL)
return Node.NIL;
if(p.n == Node.NIL)
return p;
Node rest = p.getNext();
p.setNext(Node.NIL);
Node reverseRest = rest.reverse();
rest.setNext(p);
return reverseRest;
}
The length of my old list after the reverse is 1, and I want it to be 4 for this example. My old and my new list have to have the same length after the reverse.
In order to preserve the original list your reverse method must create new Nodes objects, rather than making modifications to existing ones.
If you would like to write a recursive reverse() that takes no parameters, you can do it as follows:
Make a new Node, and copy this node's content into it; set next to NIL
If the next of this node is NIL, return the result of previous step
Otherwise, call reverse() on the next
Take the return value from the previous call, and navigate to its end
Add the new node from step one to the end, and return the result.
A better approach is to change the signature of reverse to take the nodes created so far, in reverse order. This would produce an O(n) algorithm, while the unmodified algorithm above is O(n2).
This is a recursive implementation based on dasblinkenlight's (love the handle!) suggestion: "A better approach is to change the signature of reverse to take the nodes created so far, in reverse order"
public class Node {
private static final Node NIL=null;
public Node(int data, Node next) {
super();
this.data = data;
this.next = next;
}
public int getData() {
return data;
}
public Node getNext() {
return next;
}
private int data;
private Node next;
public String toString()
{
String s = "";
Node cur = this;
while (cur != Node.NIL) {
s += cur.data + ",";
cur = cur.getNext();
}
return s;
}
/* Where the recursive magic happens */
/* build the reversed list in the parameter 'reversed' */
public Node reverse(Node n, Node reversed)
{
if (n == Node.NIL) {
return reversed;
} else {
return reverse(n.next,new Node(n.data,reversed));
}
}
/* Kick off the recursion from the head node */
public Node reverseList() {
return reverse(this,Node.NIL);
}
public static void main (String args[]) {
// Create a sample list
Node n = new Node(1,new Node(12, new Node(34, new Node(3, Node.NIL))));
System.out.println(n);
System.out.println(n.reverseList());
}
}
Related
I am supposed to build a method that will remove the first instance of a given value in a singly-linked list. However, whenever I try to test this method it will get stuck and I have to force the code to terminate.
edit: following advice, I have made a modified version method Contains that now works well and eliminates pointless repetition of Contains. so happily now the code works as it should!
Here is my code for the method:
public boolean remove(Anything m) {
//INCOMPLETE
if (this.first==null) {
System.out.println("there are no values in the list");
return false;
}
boolean returnValue;
returnValue=false;
if (this.contains(m)==true) {
Node temp=first;
while(temp.next!=null) {
if (temp.next.data==m) {
temp=temp.next.next;
temp.next=null;
returnValue=true;
}
else
returnValue=false;
}
}
return returnValue;
}
Here is my code for testing the method:
list13.addFirst("node5"); list13.addFirst("node4"); list13.addFirst("node3"); list13.addFirst("node2"); list13.addFirst("node1");
System.out.println("5-element list: " + list13);
System.out.println("Testing remove...");
System.out.println(list13.remove("node3"));
and just in case, here is the prebuilt code my assignment came with, if needed:
public class CS2LinkedList<Anything>
{
// the Node class is a private inner class used (only) by the LinkedList class
private class Node
{
private Anything data;
private Node next;
public Node(Anything a, Node n)
{
data = a;
next = n;
}
}
private Node first;
private Node last;
public CS2LinkedList()
{
first = null;
}
public boolean isEmpty()
{
return (first == null);
}
public void addFirst(Anything d)
{
Node temp = first;
first = new Node(d,temp);
}
public void clear()
{
first = null;
}
public boolean contains(Anything value)
{
for (Node curr = first; curr != null; curr = curr.next)
{
if (value.equals(curr.data)) {
return true;
}
}
return false;
}
public String toString()
{
StringBuilder result = new StringBuilder(); //String result = "";
for (Node curr = first; curr != null; curr = curr.next)
result.append(curr.data + "->"); //result = result + curr.data + "->";
result.append("[null]");
return result.toString(); //return result + "[null]";
}
```
Some issues:
At a match, you are reassigning to temp the node that follows after the node to be deleted, and then you clear temp.next. That is breaking the list after the node to be deleted.
The while loop does not change the value of temp when the if condition is not true. So the loop can hang.
You can stop the search when you have identified the node to delete. By consequence you don't need the else inside the while loop.
while(temp.next!=null) {
if (temp.next.data==m) {
// skip the node by modifying `temp.next`:
temp.next = temp.next.next;
returnValue=true;
break; // we removed the targeted node, so get out
}
temp = temp.next; // must move to next node in the list
}
It is a pity that you first iterate the list with this.contains(m), only to iterate it again to find the same node again. I would just remove that if line, and execute the loop that follows any way: it will detect whether the list contains the value or not.
Be aware that your function has no provision for removing the first node of the list. It starts comparing after the first node. You may want to cover this boundary case.
recursiveSum(Node currentNode) {
if (currentNode == null){
System.out.println("done " );
}else{ recursiveSum(currentNode.next);
}
}
Heres the node class and the recursive method. I have tried everything that I can possibly think of to return all possible subsets... if i add the numbers {`1,2,3} to the list, the recursive method should print: {1,2,3} {1,3} {1,2} {1} {1,3} {2} {3} {0}
private static class Node {
Node next;
int number;
public Node(int numberValue) {
next = null;
number = numberValue;
}
public int getNumber() {
return number;
}
public void setData(int numberValue) {
number = numberValue;
}
public Node getNext() {
return next;
}
public void setNext(Node nextValue) {
next = nextValue;
}
}
Just as a note, recursion is not a data structure, it is an iteration technique. Assuming your linked list looks like the following, and that you are using the Java LinkedList object that contains Node objects, it's relatively simple to recurse through it.
(node 1)->(node 2)->(node N)->NULL
All you need for recursion is a base case and a way to get the next node in the linked list.
public void walk_list(LinkedList<Node> list){
//the poll method retrieves and removes the head of the list
//if the list is empty, it returns null
Node n = list.poll();
//Base case - list is empty
if(n == null){
return;
}
System.out.println(n.toString());
walk_list(list);
}
Now, if your LinkedList looks like this
(node 1)->{ (node 2), (node 3) }
(node 2)->{ (node 4) }
(node 3)->{ (node 5), (node 6) }
(node 6)->{ (node 1) }
you have a cyclic graph. There are a few ways of searching this graph, the easiest being a breadth-first search or depth-first search. Both of which can be recursive much like the given example. All you have to do is keep a list of some sort (queue, array list, etc.) to know what gets searched next, and each node in the graph should have a visited attribute that is a boolean that gets set when you get that node's children.
After clarification of the problem, have a look at this question and answer. You want to do a recursive permutation. So all you need is a Set of Integer objects.
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.
hello im trying to implement a Linked list in java.
As this is a homework assignment I am not allowed to use the built in LinkedList from java.
Currently I have implemented my Node class
public class WordNode
{
private String word;
private int freq;
private WordNode next;
/**
* Constructor for objects of class WordNode
*/
public WordNode(String word, WordNode next )
{
this.word = word;
this.next = next;
freq = 1;
}
/**
* Constructor for objects of class WordNode
*/
public WordNode(String word)
{
this(word, null);
}
/**
*
*/
public String getWord()
{
return word;
}
/**
*
*/
public int getFreq(String word)
{
return freq;
}
/**
*
*/
public WordNode getNext()
{
return next;
}
/**
*
*/
public void setNext(WordNode n)
{
next = n;
}
/**
*
*/
public void increment()
{
freq++;
}
}
and my "LinkedList"
public class Dictionary
{
private WordNode Link;
private int size;
/**
* Constructor for objects of class Dictionary
*/
public Dictionary(String L)
{
Link = new WordNode(L);
size = 1;
}
/**
* Return true if the list is empty, otherwise false
*
*
* #return
*/
public boolean isEmpty()
{
return Link == null;
}
/**
* Return the length of the list
*
*
* #return
*/
public int getSize()
{
return size;
}
/**
* Add a word to the list if it isn't already present. Otherwise
* increase the frequency of the occurrence of the word.
* #param word The word to add to the dictionary.
*/
public void add(String word)
{
Link.setNext(new WordNode(word, Link.getNext()) );
size++;
}
Im having trouble with implementing my add method correctly, as it has to check the list, for wether the word allready exists and if do not exists, add it to the list and store it alphabetic.
Ive been working on a while loop, but cant seem to get it to work.
Edit: Ive been trying to print the list but it wont print more than the first added word
public void print()
{
WordNode wn = Link;
int size = 0;
while(wn != null && size <= getSize()){
System.out.println(wn.getWord()+","+wn.getFreq(wn.getWord()));
size++;
}
}
Any help is appreciated
Your add method is wrong. You're taking the root node and setting its next value to the new node. So you will never have any more than 2 nodes. And if you ever have 0, it will probably crash due to a null pointer.
What you want to do is set a current value to the root node, then continue getting the next node until that node is null. Then set the node.
WordNode current = Link;
// Check if there's no root node
if (current == null) {
Link = new WordNode(word);
} else {
// Now that the edge case is gone, move to the rest of the list
while (current.getNext() != null) {
/* Additional checking of the current node would go here... */
current = current.getNext();
}
// At the last element, at then new word to the end of this node
current.setNext(new WordNode(word));
}
You need to keep the instance of the previous node so you can set the next value. Since this would cause a problem if there are no nodes to begin with, there needs to be some extra logic to handle a root node differently. If you'll never have 0 nodes, then you can remove that portion.
If you also need to check the values of the variables in order to see if it's there, you can add something to the while loop that looks at the current value and sees if it is equal to the current word you're looking for.
WordNode current = Link;
while (current != null) {
//check stuff on current word
current = current.getNext();
}
Without your loop code, it will be hard to help you with your specific problem. However, just to give you a bit of a hint, based on the instructions you don't actually have to search every node to find the word. This will give you the opportunity to optimize your code a bit because as soon as you hit a word that should come after the current word alphabetically, then you can stop looking and add the word to the list immediately before the current word.
For instance, if the word you're adding is "badger" and your words list are
apple-->avocado-->beehive-->...
You know that beehive should come after badger so you don't have to keep looking. What you will need to implement is a method that can do alphabetical comparison letter-by-letter, but I'll leave that to you ;-)
Assuming that you always insert in alphabetical order it should look something like this:
public void add(String word){
WordNode wn = Link;
WordNode prevNode = null;
while(wn != null){
if(word.equals(wn.getWord())){
//match found, increment frequency and finish
wn.increment();
return;
}else if(word.compareTo(wn.getWord) < 0){
//the word to add should come before the
//word in the current WordNode.
//Create new link for the new word,
//with current WordNode set as the next link
WordNode newNode = new WordNode(word, wn)
//Fix next link of the previous node to point
//to the new node
if(prevNode != null){
prevNode.setNext(newNode);
}else{
Link = newNode;
}
//increase list size and we are finished
size++;
return;
}else{
//try next node
prevNode = wn;
wn = wn.getNext();
}
}
//If we got here it means that the new word
//should be added to the end of the list.
WordNode newNode = new WordNode(word);
if(prevNode == null){
//if list was originally empty
Link = newNode;
}else{
//else append it to the end of existing list
prevNode.setNext(newNode);
}
//increment size and finish
size++;
}
Use this code :
class NodeClass {
static Node head;
static class Node {
int data;
Node next;
//constractor
Node(int d) {
data=d;
next=null;
}
}
static void printList(Node node ) {
System.out.println("Printing list ");
while(node!=null){
System.out.println(node.data);
node=node.next;
}
}
static void push(int data) {
Node node = new Node(data);
node.next = head;
head = node;
}
static void addInLast(int data) {
Node node = new Node(data);
Node n = head;
while(n.next!=null){
n= n.next;
}
n.next = node;
node.next = null;
}
public static void main (String[] args) {
NodeClass linklistShow = new NodeClass();
linklistShow.head = new Node(1);
Node f2 = new Node(2);
Node f3 = new Node(3);
linklistShow.head.next = f2;
f2.next =f3;
printList(linklistShow.head);
push(6);
addInLast(11);
printList(linklistShow.head);
}
}
I am looking at examples getting ready for an exam, and frankly, I am not very good with either recursion or lists, but particularly lists.
A node class is given, it will hold strings (not generic) write a recursive java function called concat that takes a node representing the head of a linked list and returns a string representing the concatenation of all the elements of the list if the list is empty the string should be as well.
Any help would be appreciated.
(The following is what I had type before I asked the question:)
public static String FindConcat(Node head) {
String s = "";
if(head == null) return s;
else if(head.next = null) {
s += head.data;
return s;
}
else {
}
}
Thanks for the repsonses.
In this case what recursion is finding the base case and how to "devide" the data down to this base case. So first define your "base case".
Base case: argument to the function is null
Till you get the the base case, append the text of the node and skip the first element
This is your method:
public static String FindConcat(Node head) {
if (head == null)
return ""; // base case
// devide it down (run recursive FindConcat on the _next_ node)
return head.data + FindConcat(head.next);
}
This simple example will print hello this is a linked list:
public class Test {
// this is a very basic Node class
static class Node {
String text;
Node next;
public Node(String text) {
this.text = text;
}
// used for building the list
public Node add(String text) {
next = new Node(text);
return next;
}
}
// this is the recursive method concat
public static String concat(Node node) {
if (node == null)
return "";
return node.text + " " + concat(node.next);
}
public static void main(String[] args) {
// build the list
Node head = new Node("hello");
head.add("this").add("is").add("a").add("linked").add("list");
// print the result of concat
System.out.println(concat(head));
}
}
If your node is null, return an empty string.
Otherwise, get the string, make a recursive call (to get the concatenated result for the rest of the nodes), and append that to the string and return the result.
since this sounds like homework, i'll make a suggestion.
start by writing the method that will work if the list only has one element (ie there is no next node). use that as the basis for your recursive call.
Recursive traversal of a linked list generally looks like seeing if you're at the end of the list (the reference you got was null), and if you're not, doing something to a recursive call upon the next element of the list, and if you are, doing the base case thing. Assuming that nodes look like this from the outside:
public class Node{
public Node getNext();
public String toString();
}
...your method looks like this (inside the class you're using to run this out of):
public String concatList(Node head){
if(head == null){
return ""; //empty list is a null pointer: return empty string
}
return head.toString() + concatList(head.getNext());
}
The end of the list, or no list at all, looks the same- a null pointer- and returns the blank string, as specified; everything else takes the current node and concatenates it to the list created by getting the concatenated version of the entire remainder of the string.
Be careful: if something's corrupted your list so it's actually a loop, this has no checks for that and will run forever until it runs out of stack memory, unless Java correctly detects the loop optimization of this recursive function and it will simply run forever.
Here is a very complete example:
import java.util.Arrays;
import java.util.List;
import java.util.UUID;
public class RecurisveLinkedListExample
{
public static String concat(final Node node)
{
if (node == null)
{
return "";
}
else
{
return node.getData() + concat(node.getNext());
}
}
public static void main(String[] args)
{
final List<String> input = Arrays.asList("A", "B", "C", "D");
final Node head = new Node(null, input.get(0));
Node previous = head;
for (int i = 1; i < input.size(); i++)
{
previous = previous.addNext(input.get(i));
}
System.out.println(concat(head));
}
public static class Node
{
private final UUID id;
private final Node previous;
private final String data;
private Node next;
public Node(final Node previous, final String data)
{
this.previous = previous;
this.data = data;
this.next = null;
this.id = UUID.randomUUID();
}
public Node getPrevious()
{
return previous;
}
public String getData()
{
return data;
}
public Node addNext(final String data)
{
this.next = new Node(this, data);
return this.next;
}
public Node getNext()
{
return next;
}
#Override
public String toString()
{
return String.format("%s:%s:%s",
this.previous == null ? "HEAD" : this.previous.id,
this.data,
this.next == null ? "TAIL" : this.next.id);
}
}
}