I have to shift all of the tokens left by one position in a Linked List.
Here's my code for the method:
private LLNode<E> head; // the first node in the list
private LLNode<E> tail; // the last node in the list
public void shiftLeft()
{
LLNode<E> temp = new LLNode<E>();
temp = head;
head = head.next;
tail.next = temp;
}
/*from main method
TopSpinLinkedList<Integer> ll = new TopSpinLinkedList<Integer>(numTokens, spinSize);
//fills LinkedList with tokens
for(int i = 1; i <= numTokens; i++) {
ll.add(i);
}
*/
A nullpointer error appears during runtime when I call the method. Any help would be appreciated. Thanks.
If it is circular linked list and your add method works properly.
public void shiftLeft(){
head = head.next; tail = tail.next;
}
You have to think about some points:
1) If your link list does not contain any element then what?
2) For all tokens to be shifted you have to use while-loop.
I assume that head and tail are properly updated on insert and remove
public void shiftLeft()
{
if(head == null || head.next == null){
return;
}
LLNode<E> temp = new LLNode<E>();
temp = head;
head = head.next;
temp.next = null;
tail.next = temp;
tail = temp;
}
UPDATE:
From the comment I see that the OP mentions about a circular list. This is not mentioned in the OP or apparent from the code. I will leave the answer as is.
Related
My teacher guides us in this activity on how to delete the tail of the double link list. He created an step by step process or algorithm for us to follow. I followed it, but it doesn't work. Or maybe I am following it wrong. Here is the algorithm
Check if the list is empty
If not Empty
Check if there is only one node in the list
If only one node, set the head and tail reference to null.
if more than one node
create a temptail to point to next tail (tail.prev)
set the prev of the tail and next of temptail to null
assign the temptail value to the tail
Here is my code
public void delTail(){
DoubleNode temp;
if(isEmpty()){
return;
}
else if(!isEmpty()){
if(head == tail){
head = tail = null;
}
else{
temp = tail.next;
tail.prev = null;
temp.next = null;
temp = tail;
}
}
}
This is the error that i saw error in my terminal
I think that I am following it right or maybe not? Thank you so much for your help :)
This is my constructor*
public class DoubleNode{
public DoubleNode prev;
public int data;
public DoubleNode next;
public DoubleNode(int d){
this(null, d, null);
}
public DoubleNode(DoubleNode p, int d, DoubleNode n){
prev = p;
data = d;
next = n;
}
}
this is mt entire operator code*
public class operator{
DoubleNode head;
DoubleNode tail;
DoubleNode laman;
String output = "";
public operator(){
head = tail = null;
}
public boolean isEmpty(){
return head == null;
}
public void addHead(int i){
if(isEmpty()){
head = tail =new DoubleNode(i);
}
else{
head = new DoubleNode(null, i, head);
head.prev = head;
}
}
public void addTail(int i){
DoubleNode last = new DoubleNode(i);
if(isEmpty()){
head = tail = new DoubleNode(i);
}
else{
tail.next = last;
tail = last;
}
}
public void delHead(){
DoubleNode temp = head.next;
if(head==tail){ //this if condition is testing if the head and tail is one only,
head = tail =null; //if there is only one this will set the tail and head to null
}
else{
head = head.next;
head = temp;
}
}
public void delTail(){
DoubleNode temp;
if(isEmpty()) {
return;
}
else {
if(head != tail) {
tail = tail.prev;
temp = tail;
}
else {
head = tail = null;
}
}
}
public void display(){
DoubleNode tmp = head;
output = "<html>";
for(tmp = head; tmp != null; tmp = tmp.next){
output = output + "<br>" + tmp.data + "<b>" + "<br>";
}
output = output + "</html>";
}
}
This is my entire code so far, i have a main class with a jframe but i think its fine because i also use it for single link list. But I do have a problem here at double link list regarding on deleting the last node
Your problem is that you're just assigning to temp but don't actually use it. Additionally you're not setting the link back to the previous element correctly.
Assuming tail.next points to head again you might do the following:
tail.prev.next = tail.next; //you might need to check for `tail.prev` being null
tail.next.prev = tail.prev; //you might need to check for `tail.next` being null
//delete tail
To illustrate:
A -next-> Tail -next-> Head
^---prev--+ ^---prev--+
Step 1:
+----next--------------V
A Tail -next-> Head
^---prev--+ ^---prev--+
Step 2:
+----next--------------V
A Tail -next-> Head
^---prev--+ |
^--------------prev----+
Actually if tail.next == head removing the tail is no different than removing any other node.
You have two errors in your else block:
You never change the tail reference. The last statement should really be an assignment to tail.
You seem to assume that the tail has a non-null next reference, but that is a contradiction. The tail is supposed to be the last node, so its next reference will always be null (unless you are supposed to create a circular list). By consequence, temp will be null, and the statement temp.next = tail will trigger the Null Pointer Exception.
The more interesting property of tail is its prev property, which refers to the node that will become the tail after the current tail node has been removed. This tail.prev is explicitly mentioned in your assignment.
So:
else {
temp = tail.prev; // <--- should point to the new tail
tail.prev = null;
temp.next = tail;
tail = temp; // <--- reverse the assignment
}
Several other issues...
In addHead you do not set the prev property correctly. You make it a self-reference. Realise that head is already referencing the new node. Change:
head.prev = head;
to:
head.next.prev = head;
In addTail the assignment to prev is missing. Change:
tail.next = last;
tail = last;
to:
tail.next = last;
last.prev = tail; // needed!
tail = last;
In delHead you must make sure the new head's prev is null. So change:
head = temp;
to:
head = head.next;
head.prev = null;
NB: you don't need DoubleNode temp = head.next; in that method.
I am trying to reverse a linked list iteratively using a stack. I have identified where the problem is occurring, but for the life of me, can't figure out why the code isn't iterating correctly when I call the next method of a ListNode. I have marked in the code below, where the bug occurs.
This is the result when I run the code:
Before: 1->2->3->4->null
After: 4->3->3->4->null
This is what the result should be:
Before: 1->2->3->4->null
After: 4->3->2->1->null
Can anyone point me to the right direction as to what is going on? Thanks!
Here is the code:
public class Solution {
public static void main(String[] args) {
private static Solution soln = new Solution();
ListNode head = makeLinkedList(4);
System.out.print("Before: ");
printLinkedList(head);
System.out.println();
soln.reverseList(head);
System.out.print(" After: ");
printLinkedList(head);
System.exit(0);
}
public ListNode reverseList(ListNode head) {
Stack<ListNode> listContents = new Stack<ListNode>();
// iterate list and add to stack
ListNode tmp = head;
while (tmp != null) {
listContents.push(tmp);
tmp = tmp.next;
}
// iterate list again and replace each val with stack val
tmp = head;
while (tmp != null) {
tmp.val = listContents.pop().val;
// this is where the code seems to fail
tmp = tmp.next;
}
return head;
}
}
How the ListNode is defined:
public class ListNode {
int val;
ListNode next = null;
public ListNode(int item) {
val = item;
}
}
Here is how I create a linked list:
private static ListNode makeLinkedList(int numNodes) {
ListNode head = null;
ListNode tmp = null;
for (int i = 1; i < numNodes + 1; i++) {
if (tmp == null) {
tmp = new ListNode(i);
head = tmp;
} else {
tmp.next = new ListNode(i);
tmp = tmp.next;
}
}
return head;
}
A helper method:
private static void printLinkedList(ListNode head) {
ListNode tmp = head;
while (tmp != null) {
System.out.print(tmp.val + "->");
tmp = tmp.next;
}
System.out.print("null");
}
Why does it not work?
The problem is you're storing the ListNodes in the Stack instead of just the values. This way, you're overwriting the values of the nodes you're then reading:
You start with stack (top first): 4 - 3 - 2 - 1
You take former head, pop stack, and write the value
New list: 4
Stack however now is: 3 - 2 - 4 (you overwrote value in head)
Next element
New list: 4 - 3
Stack: 3 - 4 (you overwrote value in second list node)
Next element
New list: 4 - 3 - 3
Stack: 4
Last element
New list: 4 - 3 - 3 - 4
What to do to make it work?
Several possible ways to fix it:
Only store the values in the stack.
Create new ListNodes for the reversed list.
Reconnect the nodes instead of rewriting their values. Note that this can be done without even using the Stack - see how in #xenteros' answer.
Reversing a linked list should be done by reversing links if possible. I'd try the following:
public static ListNode reverseList(ListNode head) {
// iterate list and add to stack
ListNode current = head;
ListNode previous = null;
ListNode temp = null;
while (current.next != null) {
temp = previous;
previous = current;
current = current.next;
previous.next = temp;
}
current.next = previous;
return current;
}
It returns a new head. Example usage:
public static void main(String[] args) {
ListNode head = makeLinkedList(4);
System.out.print("Before: ");
printLinkedList(head);
System.out.println();
head = reverseList(head);
System.out.print(" After: ");
printLinkedList(head);
System.exit(0);
}
>>Before: 1->2->3->4->null
>>After: 4->3->2->1->null
>>Process finished with exit code 0
The algorithm description would be:
For each node in a list, instead of linking next element, link the previous one and return the last element as head.
This is happening because you are mutating your LinkedList without being aware of it. In other words, when you overwrite the value of any more in your LinkedList, the nodes that you've pushed on the stack previously would also get modified. Therefore, one way ensure this would not happen is to instantiate and push a new node (copy) on the stack:
public ListNode reverseList(ListNode head) {
Stack<ListNode> listContents = new Stack<ListNode>();
// iterate list and add to stack
ListNode tmp = head;
while (tmp != null) {
ListNode newNode = new ListNode(temp);
listContents.push(newNode);
tmp = tmp.next;
}
// iterate list again and replace each val with stack val
tmp = head;
while (tmp != null) {
tmp.val = listContents.pop().val;
tmp = tmp.next;
}
return head;
}
Simple modification to the ListNode class to add copy constructor:
public class ListNode {
int val;
ListNode next = null;
public ListNode (ListNode that){
this.val = that.val;
this.next = null; //Could be that.next
}
public ListNode(int item) {
val = item;
}
}
I try printing a reverse linked list without recursion and reversing the linked list. How can I do that?
Questions: How to print a reverse linked list without using recursion and not reversing the list?
Requirements: No extra space, cannot reverse a linked list, cannot use recursion.
Here is the definition of the linked list Node
class Node {
int value;
Node next;
public Node(int val) {
this.value = val;
}
}
Here is my recursion version of printReverseLinkedList:
public void printReverseList(Node head) {
Node temp = head;
if (temp.next != null) {
printReverseList(temp.next);
}
System.out.print(temp.value);
}
Performace does not matter, because I just want to do in this way.
If you may neither reverse the list, nor use recursion, the only way to do this is this:
public void printReversList(Node head) {
Node current = head; // used to search through the list
Node last = null; // stores the last element that we printed
while (last != head) { // = we didn't print everything yet
// find next element to print - it's one element before we reach "last"
while (current.next != last) {
current = current.next;
}
// Store the current element as the new last and print it
last = current;
system.out.print(last.value);
// reset current and start all over
current = head;
}
}
It is highly ineffective, but there is no other way I can think of.
How about using a Stack and then poping ? You said using another data-structure will be fine. This is not the fine code, but, should get the job done.
public void printReversList(Node head) {
Stack<Node> stack = new Stack<>();
while (head != null){
stack.push(head);
head = head.next;
}
while (!stack.isEmpty()){
System.out.println(stack.pop());
}
}
you can try this:
public void printReverseList(Node head) {
if(head == null) return;
Node prev = null;
Node revers = head;
Node nex = null;
while (revers != null){
nex = revers.next;
revers.next = prev;
prev = revers;
revers = nex;
}
System.out.println(prev);
}
void ReversePrint(Node head) {
// This is a "method-only" submission.
// You only need to complete this method.
Stack<Node> stk=new Stack<>();
Node temp=head;
while(temp!=null){
stk.push(temp);
temp=temp.next;
}
while(!stk.isEmpty()){
System.out.println(stk.pop().data);
}
}
public void printReverseList(Node head) {
Node node = head;
List<Integer> list = new ArrayList<Integer>();
if (head == null){
System.out.println(head.data);
}
else{
while (node != null){
list.add(0, node.data);
node = node.next;
}
for (int item:list){
System.out.println(item);
}
}
}
I'm currently taking a Java class and the professor told us that a good practice to understand links would be to make a doubly linked list. I have made a singly linked list but I am having trouble converting it to a doubly linked list. So I was wondering if anybody could give me any suggestions on making sure my last number is connected to the previous one? And if the front number and last number connected to the null. Here is part of the code, if you wish for more of it just ask and I shall post.
The code for adding elements and such. This is my attempt of trying to make the tail which is the end connect to the last number.
public void add(int element){
Node n = new Node();
n.setItem(element);
n.setNext(head);
head = n;
>
//The tail connected to the new number added.
n.setItem(element);
n.setBefore(tail);
tail = n;
The code below is the insert function which I need to make sure the new inserted blocks connect but I'm having troubles thinking of a way to make it connect for both.
public void insert(int element, int position){
int currentposition = 0;
Node currentNode = head;
//Traverse to the right position
while(currentposition < position-1){
currentposition++;
}
Node n = new Node();
n.setItem(element);
n.setNext(currentNode.getNext());
currentNode.setNext(n);
//The previous number connecting to the new number
currentNode = tail;
}
You add an extra Node field to each Node that holds its previous Node
Insertion Pseudocode:
insert(Node n, index i) {
currentIndex = 0
currentNode = head
while (currentIndex < i) {
currentNode = currentNode.next
currentIndex++
}
n.prev = currentNode
n.next = currentNode.next
currentNode.next = n
}
For doubly linked list, you need to add both head and tail fields in the class so that it maintains a doubly linked data structure.
private Node<T> head = null;
private Node<T> tail = head;
private int size = 0;
To add a new node to the end of the linked list, you can do
public void add(T element) {
Node<T> node = new Node<T>(element);
Node<T> current = head;
if(current == null) {
current = node;
head = tail = current;
} else {
tail.next = node;
node.prev = tail;
tail = node;
}
size++;
}
Note that you also need to deal with the empty list case which is the first if clause. Also you can set next and prev references for tail when you add the node.
To insert a node to the list at a certain position, you need to consider that if the specified position is less than 0 or great than the existing list size, then error occurs because you can't insert element with out of bound index. So you can throw exception. Also you need to separate the case when the inserted position is at 0 (head) or at size (tail). Considering all these cases, the solution is:
public void insert(T a, int position) {
if (position < 0 || position > size)
throw new IndexOutOfBoundsException();
Node<T> node = new Node<T>(a);
Node<T> temp;
if(position == 0) {
if(head == null)
add(a);
else {
temp = head;
head = node;
node.next = temp;
temp.prev = node;
}
return;
} else if (position == size) {
temp = tail;
tail = node;
temp.next = tail;
tail.prev = temp;
return;
}
Node<T> current = head;
int i = 0;
while (current != null && i < position-1) {
current = current.next;
i++;
}
temp = current.next;
current.next = node;
node.prev = current;
node.next = temp;
temp.prev = node;
}
I am reviewing some snippets of code for an upcoming test. I saw this in my notes, and just now realized that this code for method 1 doesn't actually remove duplicates if the list is in this way A -> B -> C -> A. I wrote an alternative function (method 2) that I think will actually work. What do you guys think? Does method 1 actually not work, and I'm tracing it wrong? p.s. We are not allowed compilers at this time :)
Here is the code, and a short introduction of what it should do.
METHOD 1: What I think doesn't work when there are 2 exact things at the head and tail.
Write code to remove duplicates from an unsorted list WITHOUT a buffer. Wwe can iterate with two pointers: “current” does a normal iteration, while “runner” iterates through all prior nodes to check for dups. Runner will only see one dup per node, because if there were multiple duplicates they would have been removed already.
public static void deleteDuplicates1(LinkedListNode head) {
if (head == null) return;
LinkedListNode previous = head;
LinkedListNode current = previous.next;
while (current != null) {
LinkedListNode runner = head;
while (runner != current) { // Check for earlier dups
if (runner.data == current.data) {
LinkedListNode tmp = current.next; // remove current
previous.next = tmp;
current = tmp; // update current to next node
break; // all other dups have already been removed
}
runner = runner.next;
}
if (runner == current) { // current not updated - update now
previous = current;
current = current.next;
}
}
}
I was thinking this would work.
METHOD 2:
public void removeDuplicates2(){
Node current = null;
Node tracer = null;
for( current = head.next; current!=null; current=current.next){
for(tracer=head; tracer!=current; tracer=tracer.next){
if(tracer.data == current.data)
//DELETE THE NODE IN CURRENT
}
}
}
The best way is sort the linked list. then iterate and check if adjacent elements are the same. If yes, delete the adjacent element. This is an O(nlogn) method without using an extra buffer.
I'm not sure what "without an extra buffer" means to you, but since I'm a lazy person and since I think other people are far better at writing out algorithms than me, I'd put the whole linked list into a HashSet and back to a linked list. That will remove duplicates easily:
LinkedList result = new LinkedList(new HashSet(inputList));
Or, if you want to preserve the order of elements
LinkedList result = new LinkedList(new LinkedHashSet(inputList));
Now since this is a homework question and you seem to be implementing a LinkedList yourself, it may well be that this solution is not viable ;-) But in any case, it will be of O(n) complexity, and not O(n^2) like both your methods 1 and 2, which might already be a lot better for you...?
I have added my code here but I am confused about the time complexity will it be O(n) or O(nlogn)? Let me know about this.
public Node removeDuplicatesFromUnsortedLinkedListWithoutExtraSpace(Node head)
{
if(head == null || head.next == null)
return head;
Node prev = head;
Node curr = head.next;
Node temp = curr;
while(prev.next!=null)
{
if(prev.data == curr.data)
{
temp.next = curr.next;
curr = curr.next;
}
else
{
if(curr != null)
{
temp = curr;
curr = curr.next;
}
if(curr == null)
{
prev = prev.next;
curr = prev.next;
temp = curr;
}
}
}
return head;
}
Modification made to the function above to rectify the logic
But i am not sure what is the time complexity of the function. Is it O(n^2) or O(n)
public static Node removeDuplicatesFromUnsortedLinkedListWithoutExtraSpace(Node head){
if(head == null || head.next == null)
return head;
Node prev = head;
Node curr = head.next;
Node temp = prev;
while(prev.next!=null){
if(curr != null){
if(prev.data == curr.data){
temp.next = curr.next;
curr = curr.next;
}else {
temp = curr;
curr = curr.next;
}
}else{
prev = prev.next;
curr = prev.next;
temp = prev;
}
}
return head;
}
public static Node removeDuplicates(Node head) {
Node cur = head;
Node next = cur.next;
while (cur != null && cur.next != null) {
next = cur;
while (next.next != null) {
if (cur.data == next.next.data) {
Node d = next.next;
next.next = next.next.next;
} else {
next = next.next;
}
}
cur = cur.next;
}
return head;
}
This uses the double pointer method. Without using any extra space, we can have two points cur(Slow) and next(Fast) pointers. For each cur pointer the data in the next pointer is checked. If a match is found then the pointers are adjusted to point to the next respective node. Hope this helps.