i have this code for singly linked list and it works. I understand theoretically the principle of singly linked list, but when it comes to code I dont understand how the pointer works. my problem is in this two lines code which is part of the code mentioned in the last
p.next = new Node<>(a[i], null);
p = p.next;
why we call next by p and create new node then assign null to next at the same time through parameter.? then giving p value of p.next which supposed to be null? i tried to print out p.next and next to see if they are the same or there is difference and I got in console an address for p.next and null for next. how they differ from each other ? I need some explanation in this part of code and how the node and the pointer is created.
public class EnkeltLenketListe<T> implements Liste<T> {
private static final class Node<T>
{
private T value;
private Node<T> next;
private Node(T value, Node<T> next)
{
this.next = next;
this.value = value;
}
}
private Node<T> head, tail;
private int counter;
public EnkeltLenketListe(T[] a)
{
this();
int i = 0; for (; i < a.length && a[i] == null; i++);
if (i < a.length)
{
head = new Node<>(a[i], null);
Node<T> p = head;
counter = 1;
for (i++; i < a.length; i++)
{
if (a[i] != null)
{
p.next = new Node<>(a[i], null);
p = p.next;
counter++;
}
}
tail = p;
}
}
There are two pointers here to think about.
Pointer p pounts to the current node, which is the last node in the list.
p.next points to what will be the next node if there will be a new node added.
p.next = new Node<>(a[i], null);
This line creates a new node in the next spot (you are adding a node to the end of the list).
p = p.next;
This line tells the current pointer p to point to the newly created node at the end of the list (it is not null, you just created a new node there).
Related
I have been grinding leetcode all day, so far 3 of the problems I did on Eclipse have worked 100% but when I run them on leetcode's IDE I always get null pointer errors. Here is a current example of my code and the problem I am currently doing: 138. Copy List with Random Pointer , which is just supposed to copy a linked list but by value and not reference.
/*
// Definition for a Node.
class Node {
int val;
Node next;
Node random;
public Node(int val) {
this.val = val;
this.next = null;
this.random = null;
}
}
*/
//MY CODE STARTS BELOW ==============================================================
class Solution {
Node n, r, pointer, output;
public Node copyRandomList(Node head) {
//Handling weird inputs
if (head == null){return head;}
Node output = new Node(head.val);
n = output; r = output;
pointer = head;
nextHandler();
randHandler();
return output;
}
public void nextHandler(){
if (pointer.next != null){
n.next = new Node(pointer.next.val);
n = n.next;
pointer = pointer.next;
nextHandler();
}
}
public void randHandler(){
if (pointer.random != null){
r.random = new Node(pointer.random.val);
r = r.next;
pointer = pointer.next;
randHandler();
}
}
}
I guess Java is not like C/C++, does not have passing by reference, uses passing by value. Probably, there is a bug in your algorithm. You can just use a debugger for that, even on LeetCode you can simply print things out.
We'd simply use a HashMap for solving this problem.
This'll pass:
public final class Solution {
public static final Node copyRandomList(
final Node head
) {
HashMap<Node, Node> map = new HashMap<>();
return clone(head, map);
}
private static final Node clone(
final Node head,
final HashMap map
) {
if (head == null) {
return null;
}
Node ptr = new Node(head.val);
map.put(head, ptr);
ptr.next = clone(head.next, map);
ptr.random = (Node) map.get(head.random);
return ptr;
}
}
Here is LeetCode's most efficient solution (which is better), O(N) runtime, constant memory:
/*
// Definition for a Node.
class Node {
public int val;
public Node next;
public Node random;
public Node() {}
public Node(int _val,Node _next,Node _random) {
val = _val;
next = _next;
random = _random;
}
};
*/
public class Solution {
public Node copyRandomList(Node head) {
if (head == null) {
return null;
}
// Creating a new weaved list of original and copied nodes.
Node ptr = head;
while (ptr != null) {
// Cloned node
Node newNode = new Node(ptr.val);
// Inserting the cloned node just next to the original node.
// If A->B->C is the original linked list,
// Linked list after weaving cloned nodes would be A->A'->B->B'->C->C'
newNode.next = ptr.next;
ptr.next = newNode;
ptr = newNode.next;
}
ptr = head;
// Now link the random pointers of the new nodes created.
// Iterate the newly created list and use the original nodes' random pointers,
// to assign references to random pointers for cloned nodes.
while (ptr != null) {
ptr.next.random = (ptr.random != null) ? ptr.random.next : null;
ptr = ptr.next.next;
}
// Unweave the linked list to get back the original linked list and the cloned list.
// i.e. A->A'->B->B'->C->C' would be broken to A->B->C and A'->B'->C'
Node ptr_old_list = head; // A->B->C
Node ptr_new_list = head.next; // A'->B'->C'
Node head_old = head.next;
while (ptr_old_list != null) {
ptr_old_list.next = ptr_old_list.next.next;
ptr_new_list.next = (ptr_new_list.next != null) ? ptr_new_list.next.next : null;
ptr_old_list = ptr_old_list.next;
ptr_new_list = ptr_new_list.next;
}
return head_old;
}
}
References
For additional details, please see the Discussion Board where you can find plenty of well-explained accepted solutions with a variety of languages including low-complexity algorithms and asymptotic runtime/memory analysis1, 2.
I'm currently working on creating a doubly linked list, but I'm struggling to do so because the constructor requires the previous element and the next element. However, checking the list just results in two null elements, the head and the tail. The constructor for a node is
public Node(Node prev, Node next, String link) {
this.prev = prev;
this.next = next;
this.link = link;
}
The constructor for the empty list that I have is
public DoublyLinkedList() {
head = tail = null;
}
My code for adding an element is
public void addElement(String link) {
Node n = new Node(tail.prev, tail, link);
if (head == null) {
head = n;
head.next = n;
}
tail.prev = n;
tail = n;
}
I know that the reason I'm resulting in null is because tail == null when I pass it into the constructor. However, I don't know how to update the value of tail before creating a new Node. I tried constructing the empty list with
public DoublyLinkedList() {
head = tail = null;
head.prev = null;
head.next = tail;
tail.next = null;
tail.prev = head;
}
But that isn't showing the elements as being added either.
Am going to assume that addElement adds an element to the end of the list
if that is the case try this instead
Node n = new Node(tail, null, link); // The new tail
if (head == null) {
head = n;
tail = n;
}else{
tail.next = n;
tail = n;
}
For that you can create a class like this:
Just for start.
public class DLinkedList{
private node pHead;
private node pTail;
public DLinkedList()
{
this.pHead=null;
this.pTail=null;
}
public insert(String newLink)
{
node newNode = new node():
newNode.link = newLink;
if(pHead==null)
{
pHead=newNode;
pTail=pHead;
}
else
{
newNode.prev=pTail;
pTail.next=newNode;
pTail= pTail.next;
}
}
}
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.
I know we can change element position by creating new node and play with node references. How can i change element position without creating or deleting node, only by play with node references? many thanks!
public class LinkedList<E extends Comparable<E>> implements Iterable<E>
{
private Node head; // reference to the first node
private int N; // number of elements stored in the list
private class Node
{
public E item;
public Node next;
public Node()
{
item = null; next = null;
}
public Node(E e, Node ptr)
{
item = e; next = ptr;
}
}
public boolean Move(E e){
Node current=head;
while(current !=null){
if(e.equals(current.item)){
System.out.println("True");
return true;
*****Then how to move this node to the front? Without creating and deleting nodes******
}
current=current.next;
}
System.out.println("False");
return false;
your algorithm should be something like this
int count = 1; // change to 0 if zero-indexed
Node p = null; // previous
Node n = head; // current
while(count < k) {
if(n.next != null) {
p = n;
n = n.next;
count++;
} else
break;
}
if(count == k){
p.next = n.next;
n.next = head;
head = n;
}
public void changeOrder(){
//keep the pointer to next element of the first
ListNode current=front.next;
//make first point to the next element
first.next=current.next;
current.next=first;
first=current;
//the current one was moved one step back and it points to first.
//change the position
current=current.next;
while(current.next!=null && current.next.next!=null){
ListNode temp = current.next.next;
current.next.next=temp.next;
temp.next=current.next;
current.next=temp;
current=temp.next;
}
}
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.