So I am currently trying to create a circle linked list (double linked list with each value having a previous, and a next value not equal to null), and I am not sure if I am properly creating it. My goal is to be able to create a LinkedList of values, and then when I iterate through the list, hasNext() should always return true (no null values). I think there is something wrong with the way I am adding values, but I am not sure. Here is the code, with the CircularList class having an inner node class:
public class CircularList<E> {
//I decided to still have heads and tails, to link them together
private Node<E> first = null;
private Node<E> last = null;
private Node<E> temp;
private int size;
//inner node class
private static class Node<E>{ //In this case I am using String nodes
private E data; //matching the example in the book, this is the data of the node
private Node<E> next; //next value
private Node<E> prev; //previous value
//Node constructors, also since in this case this is a circular linked list there should be no null values for previous and next
private Node(E data, Node<E> next, Node<E> prev){
this.data = data;
this.next = next;
this.prev = prev;
}
}
//end of inner node class
public void addValue(E item){
Node<E> n = new Node<E>(item, first, last);
if(emptyList() == true){ //if the list is empty
//only one value in the list
first = n;
last = n;
}
else{ //if the list has at least one value already
temp = first;
first = n;
first.next = temp;
last.next = first;
}
size++;
}
public boolean emptyList(){
boolean result = false;
if(first == null && last == null){ //if there is no values at all
result = true;
}
return result;
}
}
Just did a quick scan but this is the bit where it goes wrong:
Node<E> n = new Node<E>(item, first, last);
if(emptyList() == true) {
//if the list is empty
//only one value in the list
first = n;
last = n;
}
The prev and next item inside node are still null here. You should set those too.
else {
//if the list has at least one value already
temp = first;
first = n;
first.next = temp;
last.next = first;
}
Additionally you're not updating prev here.
Also consider using a linked list internally as a backing data structure rather then your own node structure. Then you only have to create the circular iterator.
Related
I was reading about queues in java implementation. I want to implement the following task:
public class DoublyLinkedList
{
private Node first; // the first Node in the list
private Node last; // the last Node in the list
private class Node
{
private Point p;
private Node prev; // the previous Node
private Node next; // the next Node
}
public void reverse()
{
// your code
}
}
I did like this:
public void reverse() { // that reverses the order of the entire list
if (first == null && last == null) {
throw new RuntimeException();
}
Node current = first;
while (current!=null) {
current.next= current.next.prev;
current.prev=current.prev.next;
current=current.next;
}
}
Am I doing right?
thanks
You don't change the first and last pointer in your code. Why are you throwing an exception if the list is empty?
I guess I would do something like:
public void reverse()
{
Node current = first;
while (current != null) {
Node next = current.next;
current.next = current.prev;
current.prev = next;
current = next;
}
Node temp = first;
first = last;
last = temp;
}
No it is not. current.next = current.next.prev is like current.next = current and current.prev = current.prev.next is like current.prev = current. Please attach a debugger and follow your code to find the errors and the right solution. We won't do your homework here. ;-)
There is a problem on leetcode called Odd Even Linked List.
It says:
Given a singly linked list, group all odd nodes together followed by the even nodes. Please note here we are talking about the node number and not the value in the nodes.
You should try to do it in place. The program should run in O(1) space complexity and O(nodes) time complexity.
Example:
Given 1->2->3->4->5->NULL,
return 1->3->5->2->4->NULL.
Here is my Node class
public class Node
{
private int value;
private Node next;
public Node(int Value)
{
this.value = Value;
this.next = null;
}
public Node()
{
this.value = -1;
this.next = null;
}
public Node getNext() {
return next;
}public void setNext(Node next) {
this.next = next;
}public int getValue() {
return value;
}public void setValue(int value) {
this.value = value;
}
}
I got 8 items in list which has values 1,2,3,4,5,6,7,8. This is my output -->1-->3-->5-->7-->2-->4-->6-->8
And here is my Linked list method to solve OddEven task.
public void oddEven()
{
if(head.getNext() == null)
return;
Node lastOdd = head.getNext(); // gets the value of last odd even in list.
Node current = lastOdd.getNext(); // Puts the reference on the first even index.
Node before = lastOdd; // This node, will always be one index before current Node
int travel = 1, loop;
while(current != null)
{
loop = travel;
// Prvo petlja putuje do sledeceg neparnog elementa
while(loop-- > 0)
{
before = current;
current = current.getNext();
}
if(current == null) // If it is end of the list, exit loop.
break;
before.setNext(current.getNext());
current.setNext(lastOdd.getNext());
lastOdd.setNext(current);
lastOdd = current;
current = before.getNext();
}
}
It works perfectly fine on my pc. But when i put code in leetcode i get the error that it doesnt work. But it is same code. Here is code from leetcode
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
public class Solution {
public ListNode oddEvenList(ListNode head)
{
if(head.next == null)
return head;
ListNode lastOdd = head.next; // gets the value of last odd even in list.
ListNode current = lastOdd.next; // Puts the reference on the first even index
ListNode before = lastOdd;
int travel = 1, loop;
while(current != null)
{
loop = travel;
// Prvo petlja putuje do sledeceg neparnog elementa
while(loop-- > 0)
{
before = current;
current = current.next;
}
if(current == null)
break;
before.next = current.next;
current.next = lastOdd.next;
lastOdd.next = current;
lastOdd = current;
current = before.next;
}
return head;
}
}
Here is the error i get
for input :[1,2,3,4,5,6,7,8]
Your answer :[1,2,4,6,8,3,5,7]
Expected answer :[1,3,5,7,2,4,6,8]
But it is same method, where did i made mistake ?
I went to the site and put your code in to make it easier to see whats going on, the issue is this line:
ListNode lastOdd = head.next; // gets the value of last odd even in list.
The first element of the list is 1, yet you are starting the last odd as being the next in the list, not the head of the list. Just changing that to:
ListNode lastOdd = head
and it provides the correct answer.
The code itself needs some tidy up, the inner while loop seems to serve no real purpose, not sure why thats there or its a left over element of a previous attempt?
What loop and travel variables are doing? They are constant at 1 in each iteration, then why while(loop-- > 0) loop. Sorry didn't get what you are trying to achieve with that loop.
int travel = 1, loop;
while(current != null)
{
loop = travel;
// Prvo petlja putuje do sledeceg neparnog elementa
while(loop-- > 0)
{
Solution: Find the last node in the list. Move all even positioned nodes to the end, by doing append. Make sure you stop at the node marked as last in first step, else it would run into infinite loop.
I am attempting to create an Deque class (Stack/Queue that can be added to and referenced at both ends) by implementing a doubly linked-list format.
import java.util.Iterator;
public class Deque implements Iterable {
Node first;
Node last;
int size;
public Deque()
{
first = null;
last = null;
size = 2;
first.next = last;
last.prev = first;
}
private class Node
{
Node next;
Node prev;
Item item;
}
private class ListIterator implements Iterator<Item>
{
private Node current = first;
public boolean hasNext()
{
return current.next != null;
}
public Item next()
{
Item item = current.item;
current = current.next;
return item;
}
public void remove()
{
/* not supported */
}
}
public boolean isEmpty()
{
if(first == null&&last == null)
return true;
return false;
}
public int size()
{
return size;
}
public void addFirst(Item item)
{
Node oldfirst = first;
first = new Node();
first.item = item;
first.next = oldfirst;
oldfirst.prev = first;
size++;
}
public void addLast(Item item)
{
Node oldlast = last;
last = new Node();
last.item = item;
last.prev = oldlast;
oldlast.next = last;
size++;
}
public Item removeFirst()
{
Item item = first.item;
first = first.next;
size--;
return item;
}
public Item removeLast()
{
Item item = last.item;
last = last.next;
size--;
return item;
}
#Override
public Iterator<Item> iterator()
{
return (new ListIterator());
}
public static void main(String[] args)
{
Deque<Integer> deque = new Deque<Integer>();
for(int i=0; i<5; i++)
{
deque.addFirst(i);
deque.addLast(9-i);
}
for(Integer i : deque)
{
StdOut.println(i);
}
}
}
When I run the code, I get a NullPointerException when it tries to do first.next = last; I can understand why, but I'm not sure how to fix it without breaking the list. Any solutions? Is it perhaps unnecessary to use a doubly linked format (i.e. remove the prev reference Node altogether)?
You avoid NullPointerException by avoiding access to uninitialized variables.
In that particular example, leave out the:
first.next = last;
last.prev = first;
in your constructor and use defensive programming and check for null if it could be uninitialized, before accessing a variable.
For example in your addFirst method:
public void addFirst(Item item)
{
Node oldfirst;
if (first != null){
oldfirst = first;
}
first = new Node();
first.item = item;
if (oldfirst != null){
first.next = oldfirst;
oldfirst.prev = first;
}
size++;
}
etc.
By the way, is this a learning exercise? If not, Java library does have Deques ready to use, including linked list:
http://docs.oracle.com/javase/7/docs/api/java/util/LinkedList.html
How is your size beginning at 2? It should be 0 until you add an Item.
You initial conditions should be that both prev and next are null. When you add a single item, then size should be 1 and both prev and next should point to that object.
When the Deque is empty, there is no "next" and "previous". It is completely empty. There would be "next" and "previous" only as soon as there is data.
So when you initialize the Deque, you should not attempt to assign a prev and next to null references. The fact that they are null indicates that there's nothing there, so of course there is nothing that comes previously or after it.
And of course, the size should be zero.
Then, in your addFirst and addLast methods, you should handle the case in which your first and last are null. In that case, you have to initialize them both to the same value, where its next and prev are both null. And set the size to 1.
Only proceed as you did (add item, correct the linkage) if the item in first or last respectively is not null.
And remember to check for null in your removeFirst and removeLast methods as well.
Short version: the case of an empty list is special. You should start with an empty list. You should check for this special case in your add and remove methods.
Having a bit of trouble adding a node to the end of my linked list. It only seems to display the very last one I added before I call my addFirst method. To me it looks like on the addLast method I'm trying to first create the node to assign it 5, then for the following numbers use a while loop to assign them to the last node on the linked list. Little stuck on why I can't get my output to display 5 and 6.
class LinkedList
{
private class Node
{
private Node link;
private int x;
}
//----------------------------------
private Node first = null;
//----------------------------------
public void addFirst(int d)
{
Node newNode = new Node();
newNode.x = d;
newNode.link = first;
first = newNode;
}
//----------------------------------
public void addLast(int d)
{
first = new Node();
if (first == null)
{
first = first.link;
}
Node newLast = new Node();
while (first.link != null)
{
first = first.link;
}
newLast.x = d;
first.link = newLast;
first = newLast;
}
//----------------------------------
public void traverse()
{
Node p = first;
while (p != null)
{
System.out.println(p.x);
p = p.link;
}
}
}
//==============================================
class test123
{
public static void main(String[] args)
{
LinkedList list = new LinkedList();
list.addLast(5);
list.addLast(6);
list.addLast(7);
list.addFirst(1);
list.addFirst(2);
list.addFirst(3);
System.out.println("Numbers on list");
list.traverse();
}
}
I've also tried creating a last Node and in the traverse method using a separate loop to traverse the last node. I end up with the same output!
public void addLast(int d)
{
Node newLast = new Node();
while (last.link != null)
{
last = newLast.link;
}
newLast.x = d;
newLast.link = last;
last = newLast;
}
The logic of your addLast method was wrong. Your method was reassigning first with every call the logic falls apart from that point forward. This method will create the Node for last and if the list is empty simply assign first to the new node last. If first is not null it will traverse the list until it finds a Node with a null link and make the assignment for that Nodes link.
public void addLast(int d) {
Node last = new Node();
last.x = d;
Node node = first;
if (first == null) {
first = last;
} else {
while (node.link != null) {
node = node.link;
}
node.link = last;
}
}
Your addLast() method displays the value of the last node because every time you append a node to the end of your list, you are overwriting the reference to "first". You are also doing this when you assign a new reference to first in the following line:
first = new Node();
Try the following:
public void addLast(int d)
{
Node newLast = new Node();
if (first == null)
{
newLast.x = d;
first = newLast;
return;
}
Node curr = first;
while (curr.link != null)
{
curr = curr.link;
}
newLast.x = d;
curr.link = newLast;
}
The method creates a new node and it is added to the end of the list after checking two conditions:
1.) If first is null: in this case the list is empty and the first node should be
initialized to the new node you are creating, then it will return (or you could do
an if-else).
2.) If first is not null: If the list is not empty you'll loop through your list until you
end up with a reference to the last node, after which you will set its next node to the
one you just created.
If you wanted to keep track of the tail of your list called "last", like you mentioned above, then add:
last = newLast
at the end of your method. Hope this helps!
I am trying to add an element to the end of a cyclic Single Linked List for my homework
assignment. But for some reason I am having a lot of problems.
I have a _tail pointer, and _dummy. The add method in JUnit test says that when checking the add method it returns null instead of 1. (1 being what was added to list)
Here is my code
private static class Node<T>{
Node<T> next;
T data;
public Node(T data, Node<T> next){
this.next = next;
this.data = data;
}
}
private Node<T> _tail;
private int _count;
private int _version;
private Node<T> _dummy;
public CyclicLinkedList(){
_dummy = new Node<T>(null, null);
_dummy.next = _dummy;
_tail = _dummy;
_count = 0;
assert _wellFormed();
}
and here is my add method
#Override
public boolean add(T x){
assert _wellFormed();
Node<T> n = new Node<T>(x, _tail.next);
_tail.next = n;
_tail = n;
++_version;
++_count;
assert _wellFormed();
return true;
}
The assertWellformed states that the linked list is wrongly cyclic. The _wellFormed() method has already been implemented by the class instructor so that is not the problem. Need some pointers! Thanks. Here is the test to see if the test is wrongly cyclic.
// check for cycles:
Node<T> fast = _tail.next;
for (Node<T> p = _tail; fast != null && fast.next != null && fast != _tail && fast.next != _tail; p = p.next) {
if (p == fast) return _report("list is wrongly cyclic");
fast = fast.next.next;
}
_tail.next = n;
_tail = n;
You should add one more line at the start of that code in add method:-
n.next = _tail.next;
So, your code becomes: -
n.next = _tail.next;
_tail.next = n;
_tail = n;
You need to make your new node point to the first node, to make it cyclic.
And since, _tail.next I assume must be pointing to the first element, before adding a new node to the List, so assign _tail.next to n.next before adding it to the list to make n also now point to the first node.
So, at the first line, both your nodes: - n node and _tail node, point to the first node. Now, detach your _tail node from first node, and make it point to the n node. And at last, make your n node as _tail node.