I am currently writing an implementation of a doubly linked list and am having trouble setting a node to a certain value. Since the data in the nodes is final, I need to replace the entire node, but the code that I wrote for that seems to be working until it exits the method and the original list hasn't been changed at all. Is there anything that I'm missing in the code here?
`public void set(int index, String item) {
if (index < 0 || index >= this.size) {
throw new IndexOutOfBoundsException();
}
Node curr = this.front;
for (int i = 0; i < index; i++) {
curr = curr.next;
}
Node temp = new Node(item);
temp.prev = curr.prev;
temp.next = curr.next;
curr = temp;
}`
You should also change "next of the previous node" and "prev of the next node". Assume prev is the previous node of cur and next is the next node of cur.
Node temp = new Node(item);
temp.prev = prev;
temp.next = next;
next.prev = temp;
prev.next = temp;
You should deal with edge problems.
you can
System.out.println(curr.val);
and you find the print is actually the same as item
but when you return ,you will find nothing change
you just need find the pre node of curr and set pre.next= curr(where is changed)
`public void set(int index, String item) {
if (index < 0 || index >= this.size) {
throw new IndexOutOfBoundsException();
}
Node curr = this.front;
for (int i = 0; i < index; i++) {
curr = curr.next;
}
Node temp = new Node(item);
temp.prev = curr.prev;
temp.next = curr.next;
curr = temp;
//here you need to set maybe
// Node tmp=curr.prev;
// tmp.next=curr;
}`
Related
I have created a doubly-linked list that I fill with nodes in Java. I am trying to make a method that adds a node at a certain index. The problem is that I get NullPointerException if I try to add a node and there are no other nodes. So I would write list.add(0, 0); for example and I would get NullPointerException (the first number is index and second is value). However, if I first use my method that just puts in a node and then tries list.add(0, 0); or list.add(1, 0); it works. I believe the problem lies in how to iterate through the nodes. The code currently looks like this:
void add(int index, T t)
{
ListNode<T> node = header;
ListNode<T> newNode = new ListNode<T>(t);
if(index < 0 || index > size)
{
throw new IndexOutOfBoundsException("Index not allowed");
}
int counter = 0;
while(node.next != null && counter < index)
{
node = node.next;
counter++;
}
if(counter == 0)
{
header = newNode;
newNode.next = node;
}
else
{
node = node.previous;
ListNode<T> temp = node.next;
node.next = newNode;
newNode.next = temp;
}
newNode.previous = node;
newNode.next.previous = newNode;
size++;
}
And I believe that this is where the problem is:
while(node.next != null && counter < index)
Do you have an idea on how to do it instead? I can't think of another way.
My code works fine in Eclipse but not in a compiler in a programming site. This code is about adding a node at given position.
Node InsertNth(Node head, int data, int position) {
Node n = new Node();
Node last = head;
int count = 0;
if (position == 0) {
n.data = data;
n.next = head;
head=n;
return n;
}
while (count < position) {
count++;
last = last.next;
}
n.data = data;
n.next = last.next;
last.next = n;
return head;
}
You go too far with the loop, and also don't check the position is in range:
Node InsertNth(Node head, int data, int position) {
Node n = new Node();
n.data = data;
if (position == 0) {
n.next = head;
return n;
}
Node last = head;
for (int count = 0; count < position-1; count++) {
if (last == null) {
return null;
}
last = last.next;
}
n.next = last.next;
last.next = n;
return head;
}
Also, a for loop is more suitable, and some other things could be rearranged better.
I have been trying to come up with an algorithm to swap 2 nodes (not necesarily right next to each other) in a singly linked list for 2 days but for some reason I cannot do it.
Here is what I have, I am really new to coding and have been really stressed:
I have managed to place a temp node in but can't actually swap the nodes.
public void swap(int i, int j) {
current = head;
current2 = head;
sllNode temp = new sllNode(" ");
sllNode temp2 = new sllNode(" ");
for(int z = 0; i>z; z++)
current=current.next;
for(int q = 0; j>q; q++)
current2 = current2.next;
temp.next = current2.next.next;
current.next = temp;
current.next = current2.next.next;
current2.next = current;
Why exchange nodes, when you can exchange the data?
public void swap(int i, int j) {
sllNode ithNode = head;
for (int z = 0; z < i; z++) {
ithNode = ithNode.next;
}
sllNode jthNode = head;
for (int q = 0; q < j; q++) {
jthNode = jthNode.next;
}
// Swap the data
String data = ithNode.data;
ithNode.data = jthNode.data;
jthNode.data = data;
}
It would make sense to use a method:
public sllNode get(int i) {
sllNode current = head;
while (i > 0) {
current = current.next;
}
return current;
}
By the way:
The convention for class names is a beginning capital: SllNode.
Do not use fields for things like current and current2 where they can be local variables.
Exchanging nodes, the hard way
Here one has to think, so it is best to deal with special cases first, and then only treat i < j.
public void swap(int i, int j) {
if (i >= size() || j >= size()) {
throw new IndexOutOfBoundsException();
}
if (i == j) {
return;
}
if (j < i) {
swap(j, i);
return;
}
// i < j
sllNode ithPredecessor = null;
sllNode ithNode = head;
for (int z = 0; z < i; z++) {
ithPredecessor = ithNode;
ithNode = ithNode.next;
}
sllNode jthPredecessor = ithNode;
sllNode jthNode = ithNode.next;
for (int q = i + 1; q < j; q++) {
jthPredecessor = jthNode;
jthNode = jthNode.next;
}
// Relink both nodes in the list:
// - The jthNode:
if (ithPredecessor == null) {
head = jthNode;
} else {
ithPredecessor.next = jthNode;
}
sllNode jNext = jthNode.next;
//if (ithNode.next == jthNode) {
if (jthPredecessor == ithNode) {
jthNode.next = ithNode;
} else {
jthNode.next = ithNode.next;
}
// - The ithNode:
if (jthPredecessor == ithNode) {
} else {
jthPredecessor.next = ithNode;
}
ithNode.next = jNext;
}
No guarantee that the logic is okay. There are tricks:
//if (ithNode.next == jthNode) {
if (jthPredecessor == ithNode) {
Both conditions test whether i + 1 == j, but testing on a .next and then assigning makes the condition a momentary state. As you see it would have been easier to have one single if (i + 1 == j) { ... } else { ... } and handle both the ithNode and jthNode.
To do this, you need to swap 2 things: the node as next from the previous node, and the next node.
Once you found current and current2 which are the previous nodes of the nodes you want to swap, do this:
Swap the nodes:
sllNode tmp = current.next;
current.next = current2.next;
current2.next = tmp;
Then swap the next:
tmp = current.next.next;
current.next.next = current2.next.next;
current2.next.next = tmp;
// Swapping two elements in a Linked List using Java
import java.util.*;
class SwappingTwoElements {
public static void main(String[] args)
{
LinkedList<Integer> ll = new LinkedList<>();
// Adding elements to Linked List
ll.add(10);
ll.add(11);
ll.add(12);
ll.add(13);
ll.add(14);
ll.add(15);
// Elements to swap
int element1 = 11;
int element2 = 14;
System.out.println("Linked List Before Swapping :-");
for (int i : ll) {
System.out.print(i + " ");
}
// Swapping the elements
swap(ll, element1, element2);
System.out.println();
System.out.println();
System.out.println("Linked List After Swapping :-");
for (int i : ll) {
System.out.print(i + " ");
}
}
// Swap Function
public static void swap(LinkedList<Integer> list,
int ele1, int ele2)
{
// Getting the positions of the elements
int index1 = list.indexOf(ele1);
int index2 = list.indexOf(ele2);
// Returning if the element is not present in the
// LinkedList
if (index1 == -1 || index2 == -1) {
return;
}
// Swapping the elements
list.set(index1, ele2);
list.set(index2, ele1);
}
}
Output
Before Swapping Linked List :-
10 11 12 13 14 15
After Swapping Linked List :-
10 14 12 13 11 15
Time Complexity: O(N), where N is the Linked List length
I have to count nodes in Circular Doubly Linked List in interval [-100;100]. I know how to do that when i'm implementing a node. Here's code :
public void insert(int val){
....
if((val >= -100) && (val <= 100)){
number++;
}
.....
But when i'm deleting a node at given position (pos), i have no idea how to check the value of that node, so i don't know if "number" stays the same or it decreases.
Here is code of deleting node:
public void deleteAtPos(int pos){
if (pos == 1){
if(size == 1){
start = null;
end = null;
size = 0;
number = 0;
return;
}
start = start.getLinkNext();
start.setLinkPrev(end);
end.setLinkNext(start);
size--;
return;
}
if (pos == size){
end = end.getLinkPrev();
end.setLinkNext(start);
start.setLinkPrev(end);
size--;
}
}
Node ptr = start.getLinkNext();
for (int i = 2; i <= size; i++){
if (i == pos){
Node p = ptr.getLinkPrev();
Node n = ptr.getLinkNext();
p.setLinkNext(n);
n.setLinkPrev(p);
size--;
return;
}
ptr = ptr.getLinkNext();
}
}
From what i understand , you can simply check the value of the node by adding
ptr.getval() or start.getval() //depending on the value of pos(aasuming getval is your function to retrieve node data)
I have a linked list of integers. When I insert a new Node I need to insert it not at the end, but in oder... i.e. 2, 4, 5, 8, 11, 12, 33, 55, 58, 102, etc. I don't think I am inserting it in the correct position. Do see what Im doing wrong?
Node newNode = new Node(someInt);
Node current = head;
for(int i=0; i<count; i++){
if(current == tail && tail.data < someInt){
tail.next = newNode;
}
if(current.data < someInt && current.next.data >= someInt){
newNode.next = current.next;
current.next = newNode;
}
}
I think this might be closer to what you are looking for.
Node newNode = new Node(someInt);
Node current = head;
//check head first
if (current.data > newNode.data) {
newNode.next = head;
head = newNode;
}
//check body
else {
while(true){
if(current == tail){
current.next = newNode;
tail = newNode;
break;
}
if(current.data < someInt && current.next.data >= someInt){
newNode.next = current.next;
current.next = newNode;
break;
}
current = current.next;
}
}
You're never moving forward in the list. you need an else that sets:
current = current.next
You can also add a break statement after you've inserted the node since at that point you're done with the loop.
It doesn't look like you're updating current... try inserting something like this in your loop:
current = current.next;
Looks like you missing the case, when the new element is lesser than all existing ones.