Creating an edit method using a singly linked list - java

Is there any way I can edit a specific node's data within a linked list? I started writing a method:
public void edit(int index, String data) {
Node pre = head;
Node temp = null;
for(int i=1; i <= index; i++) {
temp = pre;
pre = pre.next();
}
temp.next(new Node(data));
pre.data(data);
}
I have four nodes in my list, I used this method to edit the node at index 1 in the list, however now when I print out all elements in the list it only shows nodes at index 0 and 1, and 2-3 do not appear. Any hints on whats going wrong here?

public void edit(int index, String data) {
Node pre = head;
Node temp = null;
for(int i=1; i <= index; i++) {
temp = pre;
pre = pre.next();
}
Node newNote = new Node(data);
temp.next = newNote;
newNote.next = pre.next;
}
You should also handle the some specific situations. For example: This code doesn't work for index = 0. And This code throws exceptions for linked list size when be 0. And This code also throws exceptions when index bigger then linked list size. And things like that

public void edit(int index, String data) {
if (index==0) {
head.data(data);
return;
}
if (index < 0 || index > size()) {
throw new IndexOutOfBoundsException("Index out of bounds.");
}
Node pre = head;
Node temp = null;
for(int i=1; i <= index; i++) {
temp = pre;
pre = pre.next;
}
Node newNode = new Node(data);
temp.next(newNode);
newNode.next(pre.next);
}
#Mustafa Akıllı Something like this?

Related

how to print the last three nodes of a linked list?

My whole code to try to get the las three nodes of a linked list is:
Node class:
package com.company;
public class Node {
public int data;
public Node nextNode;
public Node(int data) {
this.data = data;
this.nextNode = null;
}
public int getData() {
return data;
}
}
Linked list class;
package com.company;
public class LinkedList {
public Node head;
public int size;
public LinkedList() {
this.head = null;
this.size = 0;
}
public void add(int data) {
Node node = new Node(data);
if (head == null) {
head = node;
} else {
Node currentNode = head;
while(currentNode.nextNode != null) {
currentNode = currentNode.nextNode;
}
currentNode.nextNode = node;
}
size++;
}
public void printData() {
Node currentNode = head;
while(currentNode != null) {
int data = currentNode.getData();
System.out.println(data);
currentNode = currentNode.nextNode;
}
}
public void printLastThree(){
Node currentNode = head;
int i = this.size - 3;
while(i <= this.size) {
int data = currentNode.getData();
System.out.println(data);
currentNode = currentNode.nextNode;
i++;
}
}
}
Main class:
package com.company;
public class Main {
public static void main(String[] args) {
LinkedList ll = new LinkedList();
ll.add(1);
ll.add(2);
ll.add(3);
ll.add(4);
ll.add(5);
ll.add(6);
ll.add(7);
ll.add(8);
ll.add(9);
ll.add(10);
ll.add(11);
ll.add(12);
ll.printData();
System.out.println();
ll.printLastThree();
}
}
As you can see, in the linked list class I try to print the last three nodes of the linked list with the printLastThree() method, but in console I just get:
1
2
3
4
And I would like to get:
10
11
12
Can you say me what I am doing wrong?
I try in printLastThree() method to get the total size of the linked list and substract 3 positions, and then get to the total size of the linked list, but that doesn't work.
Thanks.
Once can see from your code that currentNode starts as the head node, and its value gets printed in the first iteration of the loop. This is not what you want.
You'll first have to skip nodes, which do not get printed. You already calculated how many such nodes need to be skipped (this.size - 3), so you only need to add the loop to actually skip that many nodes:
public void printLastThree(){
Node currentNode = head;
// First SKIP nodes (not to be printed)
for (int i = size - 3; i > 0; i--) {
currentNode = currentNode.nextNode;
}
// ...and only then start printing
while (currentNode != null) {
int data = currentNode.getData();
System.out.println(data);
currentNode = currentNode.nextNode;
}
}
You can also do it with one loop, and make the printing conditional on the current index:
public void printLastThree(){
Node currentNode = head;
for (int i = 0; i < size; i++) {
if (i >= size - 3) { // Are we at the last three nodes?
int data = currentNode.getData();
System.out.println(data);
}
currentNode = currentNode.nextNode;
}
}
the bug is in printLastThree().
You need to move the currentNode from head to position: size-3; But don't print it just yet.
Then after that, move again from size-3 to size-1 and during this move, print it out.
try 2 while loops. Later you can also make it into 1 while loop from start to end with if condition whether to print or not.

Java LinkedList inserting Object at index

I am having a bit of trouble understanding how to place an object in a linked.
In this case, if there is already an object at the specific index, it won't replace it (that is for another method). I guess I am having trouble understanding how to get to a specific index, retrieve the data from that index, and then either put data there and connect the nodes or tell the user there is already an object there.
Here is my code:
public class CourseList {
private Coursenode head;
int currentSize;
public void insertAtIndex(Course c, int index) {
Coursenode insert =new Coursenode(c,head);
Coursenode temp = new Coursenode();
if (index > currentSize - 1 || index < 0) {
throw (new IndexOutOfBoundsException());
}
for(int x = 0; x < index; x++) {
if (insert.getNext()!= null) {
temp = insert;
insert.setNext(insert);
insert.setData(temp.getData());
}
if (insert.getNext() == null && x == index) {
insert.setNext(insert.getNext());
}
if (insert.getNext() != null && x == index) {
System.out.println("There is already a Course at that Index");
}
}
}
}
Here is the inner class Coursenode:
public class Coursenode {
private Course data;
private Coursenode next;
public Coursenode() {
this.data = null;
this.next = null;
}
public Coursenode(Course course, Coursenode next) {
this.data=course;
this.next= next;
}
public Coursenode(Coursenode x) {
this.data = x.getData();
this.next = x.getNext();
}
public Course getData() {
return data;
}
public void setData(Course data) {
this.data = data;
}
public Coursenode getNext() {
return next;
}
public void setNext(Coursenode next) {
this.next = next;
}
//Clone method
public void clone(Coursenode new_cn){
new_cn = new Coursenode (this.getData(),this.getNext());
}
}
Any thought would be appreciated, I suspect I am getting lost within the head reference between nodes but I can't quite figure out how to solve the problem.
There are three ways (assuming positive index values) to make an insertion at an index in a linked list:
At the head (index == 0)
After the tail (index >= currentSize)
In the middle (at an occupied index) (index > 0 && index < currentSize)
There may be a tendency to think that inserting at the tail is another case, but later we'll see that insertion at the tail is the same as an insertion in the middle, because the tail will be slid forward.
If the insertion is at the head, you need to set the next of the inserted node to the old head and then set head to the inserted node:
private void insertAtHead(Course course) {
Coursenode insertedNode = new Coursenode(c, head);
head = insertedNode;
}
If the insertion occurs past the tail, a common way of dealing with this is to throw some sort of exception, such as an IndexOutOfBoundsException:
throw new IndexOutOfBoundsException("Cannot insert course after the tail of the course list");
If the insertion occurs at an occupied index, the existing node (and all nodes after the existing node) must be pushed forward. This means that the next of the inserted node must be set to the node that currently occupies the index and the next of the node previous to the node at the current index must be set to the inserted node. In essence, the inserted node is fused into the list. To do this, the list must be traversed until the occupied node is found:
private void insertAtOccupied(Course course, int index) {
Coursenode previous = null;
Coursenode current = head;
for (int i = 1; i <= index; i++) {
// Track the previous and current nodes
// previous = node at i - 1
// current = node at i
previous = current;
current = current.next;
}
Coursenode insertedNode = new Coursenode(c, current.next);
previous.next = insertedNode;
}
Pulling these cases together, we can create the following logic:
public void insertAt(Course course, int index) {
if (index == 0) {
insertAtHead(course);
}
else if (index >= currentSize) {
throw new IndexOutOfBoundsException("Cannot insert course after the tail of the course list");
}
else if (index > 0 && index < currentSize) {
insertAtOccupied(course, index);
}
}
First of all in a linkedlist if
index < linkedlistsize
then there is an object already in a linkedlist. If you have a null node in node.next that how you know you have reached the end of your linked list.
public class CourseList {
private Coursenode head;
int currentSize;
public void insertAtIndex(Course c, int index) {
Coursenode insert =new Coursenode(c,head);
Coursenode temp = new Coursenode();
if (index > currentSize - 1 || index < 0) {
throw (new IndexOutOfBoundsException());
}
//tempnode = head;
for(int x=1; x< index;x++) {
//tempnode = tempnode.next;
}
//nodeatindex = tempnode;
//you can get details of the node
}
Hope this helps!

ArrayStoreException when attempting to store an array of linked list

I'm attempting to create an array of linked list which will deal with hash value collisions. I have an array of an objects which I have tried to store the linkedList but it doesn't seem to work. Is there something I'm doing wrong, or is there a more efficient route I should take.
This is the error I get when running my code.
Exception in thread "main" java.lang.ArrayStoreException: linkedList
at p7b.Insert(p7b.java:57)
at p7b.main(p7b.java:31)
Here is my method
public static void Insert(int hashVal, String key,int[] arrayNums, Object[] arrayString){
Node newNode = new Node(key,null);
linkedList list = new linkedList();
if (arrayString[hashVal] == null){
arrayString[hashVal] = list;
}
Here is the linkedList code:
public class linkedList{
private Node head;
private int size;
public linkedList(){
size = 0;
head = null;
}//end default constructor
public boolean isEmpty(){
return size == 0;
}//end isEmpty
public int size(){
return size;
}//end size
protected Node find(int index){
Node curr = head;
for(int skip = 0; skip < index; skip++){
curr = curr.getNext();
}//end for
return curr;
}//end find
public Object get(int index){
if (index >=0 && index < size) {
// get reference to node, then data in node
Node curr = find(index);
Object dataItem = curr.item();
System.out.println(dataItem);
return dataItem;
}
else
return "error";
}//end get
public void add(int index, String item){
if(index>= 0 && index < size+1){
if(index == 0) {
//insert the new node containing item at
//beginning of list
Node newNode = new Node(item,head);
head = newNode;
head.setNext(head);//--------------------
}
else {
Node prev = find(index-1);
//insert the new node containing item after
//the node that prev references
Node newNode = new Node(item,head.getNext()); //changed prev to head
head.setNext(newNode); //prev.next = newNode --//changed prev to ead
head = newNode;
}//end if
}
sizeplus();
/*if(index == 16){//fffff
for(int i = 0; i < 50; i++){
System.out.println(head.item());-------------EXR
head = head.getNext();
System.out.println("----------");
}//ifffffff
}
*/
}//end add
public int sizeplus(){
size+=1;
return size;
}
public void remove(int index){
int num = index;
while(size>0){
//System.out.println("strt");
if(index>= 0 /*&& index < size*/){
if(index == 0) {
//delete the first node from the list
System.out.println("REMOVED :"+head.item());//----------------EXR
head = head.getNext();
}
else {
Node prev = find(index-1);
// delete the node after the node that prev
//references, save regerence to node
Node curr = prev.getNext();
System.out.println(curr.item());
if(size > 1){
}
else{
System.out.print("is the last one left");
}
prev.setNext(curr.getNext());
curr = prev.getNext();
index+=num-1;
}//end if
size--;
//System.out.println(size+" <-size || index-> " +index);
}//end if
}
}//end remove
public Node getH(){
return head;
}
}//end class
ALSO: how would i change from linked list to the next
here is what i tried.
linkedList list = new linkedList();
list = arrayString[i];
p7b.java:44: error: incompatible types
list = arrayString[i];
^
required: linkedList
found: Object
1 error
From your main method :
Object[] arrayString = new String[40];
...
Insert(hashVal,key,arrayNums,arrayString);
You are passing a String array to your method.
Therefore you can't put linkedList instances in this array.
If you want this array to contain linkedList instances, change the code to :
Object[] arrayString = new linkedList[40];
...
Insert(hashVal,key,arrayNums,arrayString);
or even better :
linkedList[] arrayString = new linkedList[40];
...
Insert(hashVal,key,arrayNums,arrayString);
and change the signature of Insert to accept a linkedList[] instead of Object[].
Here's the culprit:
Object[] arrayString = new String[40];
You're claiming that it's an Object[], but it's actually backed by a String[] instead. Java can't make the determination at compile time that you're not going to be able to store any old Object into that array, so it blows up at run time.
What you should do is type the array correctly - if it's going to hold linkedList entities, it should be linkedList entities.
linkedList[] linkedLists = new linkedList[40];
More specifically, you are using the array in a lot of different places. Be consistent with its usage.
Having a few thoughts about your code: it's not...correct. You're creating a linked list, right? There's no reason to use arrays unless the list itself is backed by them.
I can't vouch for the correctness of your linkedList.add method right now, but you don't want to use arrays for this at all. Create a single instance of a linked list outside of that method and store all of the data you care about in it.
public static void insert(String key, int index, linkedList list) {
list.add(index, key);
}
(As a general thought, linked lists don't have index positions that you simply insert into, so the index portion is completely superfluous.)

Practicing Singly Linked List implementation, stumped by my list reversal method throwing NullPointerException

Here is my singly linked list code:
public class SinglyLinkedList {
private static Node head;
private static int listSize;
private static class Node {
int value;
Node next;
Node(int i) {
value = i;
next = null;
}
}
public static void main(String[] args) {
head = null;
listSize = 0;
for (int i = 0; i < 10; i++) {
Node n = new Node(i);
if (head == null) {
head = n;
} else {
getLastNode(head).next = n;
}
listSize++;
}
printNodeValues(head);
Node revHead = reverseList(head);
printNodeValues(revHead);
}
private static Node reverseList(Node head) {
Node reverseHead = getLastNode(head);
Node reference = reverseHead;
while (listSize>0){
Node temp = getPreviousNode(reference, head);
Node last = getLastNode(reverseHead);
temp.next = null;
last.next = temp;
reference = temp;
listSize--;
}
return reverseHead;
}
private static Node getPreviousNode(Node reference, Node head) {
Node temp = head;
while (temp != null) {
if (temp.next == reference) {
break;
} else {
temp = temp.next;
}
}
return temp;
}
private static Node getLastNode(Node n) {
Node temp = n;
while (temp != null) {
if (temp.next == null) {
break;
} else {
temp = temp.next;
}
}
return temp;
}
public static void printNodeValues(Node h) {
while (h != null) {
System.out.print(h.value + " ");
h = h.next;
}
System.out.println();
}
}
The problem is with my reverseList(Node) method. When I run the program, I get the following error:
Exception in thread "main" java.lang.NullPointerException
at SinglyLinkedList.reverseList(SinglyLinkedList.java:44) -> temp = null;
at SinglyLinkedList.main(SinglyLinkedList.java:33) -> Node revHead = reverseList(head);
My printNodeValues works fine, and prints
0 1 2 3 4 5 6 7 8 9
and I'm trying to use reverseList to print
9 8 7 6 5 4 3 2 1 0.
There are many very bad things in your code. Worst of all : why is everything static ? What's the point of writing a list class that can be instantiated only once ?
Then, the size of the list should never be affected by a reverse operation, and you don't even need a counter since you just have to iterate over the list until you find a node which has no successor.
private static Node reverseList(Node head) {
Node res = null;
while (head != null) {
Node node = new Node(head.value);
node.next = res;
res = node;
head = head.next;
}
return res;
}
Your reverseList() method needs to skip the iteration when it has reached the first node in the original list because it's previous node doesn't exist. This first node has already be assigned as the next node (i.e. the last node in the reversed list) in the second last iteration (of your original loop).
private static Node reverseList(Node head) {
Node reverseHead = getLastNode(head);
Node reference = reverseHead;
int counter = listSize;
while ( counter > 1) {
Node temp = getPreviousNode(reference, head);
Node last = getLastNode(reverseHead);
temp.next = null;
last.next = temp;
reference = temp;
counter--;
}
return reverseHead;
}
Secondly, you shouldn't modify your listSize variable directly because the number of elements in the reversed list remains the same. Here, I'm storing it in a temporary counter first before iterating the list.
And, finally the reversed list should become your current head. Since, you've modified the linking between all the elements, it can only be traversed if your head now points to the new head.
printNodeValues(head);
head = reverseList(head);
printNodeValues(head);

What is wrong with the set method of my LinkedList

Im trying to implement a linkedlist.. All of my methods work except for the set method. It is only supposed to change the replace the element at the given index. But after setting the element in the index it is making the rest of the elements in the list to null, can anyone point out what I'm doing wrong in the set method?
public class LArrayList<E> {
private static class Node<E> {
Node<E> next;
E data;
public Node(E dataValue) {
next = null;
data = dataValue;
}
#SuppressWarnings("unused")
public Node(E dataValue, Node<E> nextValue) {
next = nextValue;
data = dataValue;
}
public E getData() {
return data;
}
public Node<E> getNext() {
return next;
}
public void setNext(Node<E> nextValue) {
next = nextValue;
}
}
private Node<E> head;
private static int listCount;
public LArrayList() {
head = new Node<>(null);
listCount = 0;
}
public void add(int index, E e) throws IndexOutOfBoundsException{
if (index < 0 || index >= listCount + 1) {
throw new IndexOutOfBoundsException("Bad index, please use index within range");
}
else{
Node<E> positionTemp = new Node<>(e);
Node<E> positionCurrent = head;
for (int i = 0; i < index && positionCurrent.getNext() != null; i++) {
positionCurrent = positionCurrent.getNext();
}
positionTemp.setNext(positionCurrent.getNext());
positionCurrent.setNext(positionTemp);
listCount++;
}
}
public E set(int index, E e) throws IndexOutOfBoundsException {
if (index < 0 || index >= listCount)
throw new IndexOutOfBoundsException("Bad index, please use index within range");
Node<E> positionTemp = new Node<>(e);
Node<E> positionCurrent = head;
for (int i = 0; i < index; i++) {
positionCurrent = positionCurrent.getNext();
}
positionCurrent.setNext(positionTemp);
return positionCurrent.getData();
}
public E get(int index) throws IndexOutOfBoundsException
{
if (index < 0 || index >= listCount)
throw new IndexOutOfBoundsException("Bad index, please use index within range");
Node<E> positionCurrent = head.getNext();
for (int i = 0; i < index; i++) {
if (positionCurrent.getNext() == null)
return null;
positionCurrent = positionCurrent.getNext();
}
return positionCurrent.getData();
}
public static void main(String[] args) {
LArrayList<String> aa = new LArrayList<String>();
aa.add(0, "0");
aa.add(1, "1");
aa.add(2, "2");
aa.add(3, "3");
aa.add(4, "4");
aa.add(5, "5");
System.out.println("The contents of AA are: " + aa);
aa.set(0, "a");
System.out.println("The contents of AA are: " + aa);
System.out.println(aa.get(0));
System.out.println(aa.get(1));
System.out.println(aa.get(2));
System.out.println(aa.get(3));
System.out.println(aa.get(4));
System.out.println(aa.get(5));
//OUTPUT IS: The contents of aa are: [0][1][2][3][4][5]
//The contents of AA are: [a][b][c][d][e]
//a
//A
//null
//null
//null
//null
}
}
After a quick look over your code:
positionCurrent.setNext(positionTemp);
Don't you need to also link positionTemp to the element after it?
First get the item just before current index:
for (int i = 0; i < index; i++) {
positionCurrent = positionCurrent.getNext();
}
You are missing a link between currently set item and rest of your list, Establish that by:
positionTemp.setNext(positionCurrent.getNext().getNext());
positionCurrent.setNext(positionTemp);
And return
positionCurrent.getNext().getData()
Hope it helps.
ok, so you have many problems in your code, i will help you with some but not all.
I really advise you to use Eclipse debugger(If you use eclipse), check this out:
http://www.vogella.com/tutorials/EclipseDebugging/article.html
First of all, the reason that your whole list is null after a set is that your index is 0 than you use a for loop that does nothing(cause the index is 0), so in the line after that:
positionCurrent.setNext(positionTemp);
You are setting head's next to be positionTemp, and than you are loosing the rest of the list cause you are not setting next for postionTemp(postionTemp next is null)
second, when you are adding the first item to the list, or when the list is empty and you are adding something, you need to make this new node the list's head, otherwise your list head will always be null.
third, when you want to print list, you cant use:
System.out.println("The contents of AA are: " + aa);
You need to do this instead:
Node<E> head = aa.head;
while(head != null){
system.out.println(head.data)
}
It looks like you have more bugs on your code, so i simply advise you use debugger.
Good luck

Categories