I searched for this alot found alota similar answers but nothing to help my exact problem.
I'm doing a push method for my double linked list, while the pointers on the head work fine, the tail next and previous pointers do not work please help.
public class MyStack<E> implements MyDeque {
private Node<E> head;
private Node<E> tail;
private int size;
public MyStack() {
head = null;
tail = null;
size = 0;
}
public void push(Object element) {
Node<E> newNode = new Node(element);
if(size == 0) {
Node temp = new Node(head);
head = newNode;
head.next = head;
head.previous = head;
tail = head;
tail.next = head;
tail.previous = temp;
}
else {
newNode.previous = head;
head = newNode;
newNode.next = tail;
(tail.next).previous = tail;
}//else statement
size++;
}//push()
public Object peek() {
if (size==0) return null;
else
return head;
}
public Object pop() {
size--;
if(size == 0)
return null;
else {
Node temp = new Node(head.previous);
head = head.previous;
head.next = tail;
head.previous = temp;
return head;
}//else
}//pop()
#Override
public int size() {
return size;
}
private class Node<E> {
private E data;
private Node<E> next;
private Node<E> previous;
public Node(E data) {
this.data = data;
this.next = null;
this.previous = null;
}
public Node(E data, Node<E> next, Node<E> previous) {
this.data = data;
this.next = next;
this.previous = previous;
}//constructor
public String toString() {
return data+"";
}
}//class Node<E>
public String toString() {
return (head+" Head\n" + head.next +" Head.Next\n" + head.previous+ " Head.previous\n"
+ tail+" Tail\n" + tail.next+" tail.next\n" + tail.previous+" tail.previous\n");
}
}
The case where you push an object when the stack is empty does not look correct. The first node added should be assigned to head. Then the tail becomes the new node's head, this new node becomes the tail node's tail, and the new node itself becomes the tail.
Usually in a stack you add and remove elements at the end (the tail). The code doesn't make it very clear what you are trying to do with the head and tail members. Maybe it would be clearer for you if you name them firstNode and lastNode.
I can actually see a few issues with this code
public class MyStack<E> implements MyDeque {
private Node<E> head;
private Node<E> tail;
private int size;
public MyStack() {
head = null;
tail = null;
size = 0;
}
This looks fine
public void push(Object element) {
Node<E> newNode = new Node(element);
if(size == 0) {
Node temp = new Node(head);
head = newNode;
head.next = head;
head.previous = head;
tail = head;
tail.next = head;
tail.previous = temp;
}
else {
newNode.previous = head;
head = newNode;
newNode.next = tail;
(tail.next).previous = tail;
}//else statement
size++;
}//push()
Bit confused why you are taking in an object instead of your generic E.
You really don't need the temp value here, in fact it looks like you are breaking your previous when you set tail.previous = temp
In your else you aren't setting the tail.previous correctly. The last line should be tail.previous = head. You also missed the head.next
So cleaned up a bit
public void push(E element) {
Node newNode = new Node(E);
if(size == 0) {
head = newNode;
head.next = head;
head.previous = head;
tail = head;
} else {
newNode.previous = head;
head.next = newNode;
newNode.next = tail;
tail.previous = newNode;
head = newNode;
}
size++;
}
In your pop method you probably want to move your size decrement after your size check, otherwise a 1 element stack will return null when popped.
edit: This would probably be easier with a singly linked list, or at least not a circular doubly linked list.
and adding at the end would probably be the more conventional way to do things.
Related
I am trying to implement it recursively but it is not returning the correct linked list with all the correct nodes.
I tried printing the node out after the recursive call and that gave me the correct linked list in reverse order but for some reason when i return head that does not work.
public Node<E> insertNodeAtPosition(Node<E> head,E element,int position)
{
Node<E> node = new Node<E>(element,null);
if(head==null){
return node;
}
if(position==0)
{
Node<E> current = head;
head = node;
head.next = current;
}
insertNodeAtPosition(head.next,element,position-1);
return head;
}
I expect the output to include the inserted node but it doesnt appear there
This code:
public static <E> Node<E> insertNodeAtPosition(Node<E> head, E element, int position) {
return insertNodeAtPosition(null, head, element, position);
}
private static <E> Node<E> insertNodeAtPosition(Node<E> prev, Node<E> head, E element, int position) {
if (position == 0) {
Node<E> newNode = new Node<>(element, null);
if (prev != null) {
prev.next = newNode;
}
newNode.next = head;
return newNode;
}
return insertNodeAtPosition(head, head.next, element, position - 1);
}
Will return the newly-inserted node.
EDIT: without the additional method:
private static <E> Node<E> insertNodeAtPosition(Node<E> prev, Node<E> head, E element, int position) {
if (position == 0) {
Node<E> newNode = new Node<>(element, null);
if (prev != null) {
prev.next = newNode;
}
newNode.next = head;
return newNode;
}
return insertNodeAtPosition(head, head.next, element, position - 1);
}
This question already has answers here:
Delete Last Node of a Linked List
(15 answers)
Closed 5 years ago.
I am trying to create a double linked list and am having trouble with the removeLast method.
public class Node<E> {
E data;
public Node<E> next;
public Node<E> prev;
public Node(E d)
{
data = d;
}
public E getData()
{
return data;
}
}
public class TestList<E> {
Node<E> head;
Node<E> tail;
public void addLast(E data)
{
Node<E> newData = new Node<E>(data);
if (head == null)
{
head = newData;
tail = newData;
}
else
{
Node<E> current = head;
while (current.next != null)
current = current.next;
current.next = newData;
tail = current.next;
}
}
public void removeLast()
{
if (head == null)
System.out.println("List is empty!");
else
{
Node<E> current = tail;
}
}
If for example I had a list of integers with the values 1, 3, 5 with 1 being the head and 5 being the tail, in my removeLast method I would like to know how I could make current.prev point to 3 and current.prev.prev point to 1 as right now it would just point to the next values which in this case would be null.
You have to modify both addLast() and removeLest() with check 3 different situations in both methods.
public final class TestList<E> {
private Node<E> head;
private Node<E> tail;
public void addLast(E data) {
Node<E> node = new Node<>(data);
if (head == null)
head = tail = node;
else if (head == tail) {
tail = node;
head.next = tail;
tail.prev = head;
} else {
tail.next = node;
node.prev = tail;
tail = node;
}
}
public void removeLast() {
if (tail == null)
System.err.println("List is empty!");
else if (head == tail)
head = tail = null;
else {
Node<E> prev = tail.prev;
tail.prev = null;
tail = null;
tail = prev;
tail.next = null;
}
}
private static final class Node<E> {
E data;
Node<E> next;
Node<E> prev;
public Node(E data) {
this.data = data;
}
}
}
You can do:
If the list is already empty, do nothing
Or else, if head is the same as the tail (there is only one element in list), then clear the list
Or else, make tail.prev.next point to null, and then make tail = prev
Like this:
public void removeLast() {
if (head == null) {
System.out.println("List is empty!");
return;
}
if (head == tail) {
head = tail = null;
return;
}
Node<E> prev = tail.prev;
prev.next = null;
tail = prev;
}
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;
}
}
}
This question already has answers here:
Is Java "pass-by-reference" or "pass-by-value"?
(93 answers)
Closed 5 years ago.
I am trying to write a program for quicksort using singly linked list in java.
Below is the code.
public class QuickSortInSLinkedList {
Node head;
private static class Node{
private int data;
private Node next;
Node(int data){
this.data = data;
this.next = null;
}
}
public void printList(Node head){
Node node = head;
while(node != null){
System.out.print(node.data+" ,");
node = node.next;
}
}
private Node getLastNode(Node head){
Node node = head;
while(node != null && node.next != null){
node = node.next;
}
return node;
}
public void push(int data){
Node node = new Node(data);
if(head == null){
head = node;
return;
}
node.next = head;
head = node;
}
void quickSort(Node head){
Node lastnode = getLastNode(head);
head = _quickSort(head, lastnode);
return;
}
Node _quickSort(Node low, Node high){
Node newHead = null, newTail = null;
if(low == null || low == high){
return low;
}
Node part = partition(low, high, newHead, newTail);
if (newHead != part){
Node temp = newHead;
while(temp.next != part){
temp = temp.next;
}
temp.next = null;
newHead = _quickSort(newHead, temp);
temp = getLastNode(newHead);
temp.next = part;
}
part.next = _quickSort(part.next, newTail);
return newHead;
}
private Node partition(Node low, Node high, Node newHead, Node newTail){
Node pivot = high;
Node previous = null, current = head, tail = pivot;
while(current != pivot){
if (current.data < pivot.data){
if (newHead == null)
newHead = current;
previous = current;
current = current.next;
}else{
if(previous != null)
previous.next = current.next;
Node temp = current.next;
current.next = null;
tail.next = current;
tail = current;
current = temp;
}
}
if(newHead == null){
newHead = pivot;
}
newTail = tail;
return pivot;
}
public static void main(String[] args){
QuickSortInSLinkedList list = new QuickSortInSLinkedList();
list.push(5);
list.push(35);
list.push(7);
list.push(8);
list.push(34);
list.push(23);
System.out.println("Linked list before sorting");
list.printList(list.head);
System.out.println("\n Linked list after sorting");
list.quickSort(list.head);
list.printList(list.head);
}
}
I understand that since in java we have pass by reference value, this code should work but in line 62 i.e. variables newHead and newTail is always received as null after the call to partition method.
below is the error
Exception in thread "main" java.lang.NullPointerException
23 ,34 ,8 ,7 ,35 ,5 ,
at implementation.sorting.QuickSortInSLinkedList$Node.access$100(QuickSortInSLinkedList.java:6)
Linked list after sorting
at implementation.sorting.QuickSortInSLinkedList._quickSort(QuickSortInSLinkedList.java:62)
at implementation.sorting.QuickSortInSLinkedList.quickSort(QuickSortInSLinkedList.java:47)
at implementation.sorting.QuickSortInSLinkedList.main(QuickSortInSLinkedList.java:123)
Please help me understand why is it so.
Thanks
Java does manipulate objects by reference, and all object variables are references. However, Java doesn't pass method arguments by reference; it passes them by value.
I am trying to implement the reverse function of my own LinkedList implementation. Using my implementation of LinkedList:
public class LinkedList<T> {
public Node head;
public LinkedList(){
// Add HEAD
head = new Node(null);
}
public void add(T data){
getLastNode().next = new Node(data);
}
public void insert(int index, T data){
if(index == 0){
throw new Error(); // TODO: What is the Error Type?
}
Node current = head;
for (int i = 0; i != index - 1 ; i ++) {
current = current.next;
if (current == null){
throw new IndexOutOfBoundsException();
}
}
Node next = current.next;
Node newNode = new Node(data);
current.next = newNode;
newNode.next = next;
}
public T get(int index){
return getNode(index).data;
}
public void delete(int index){
if (index == 0){
throw new IndexOutOfBoundsException("Cannot delete HEAD node");
}
Node prev = getNode(index - 1);
Node next = prev.next.next;
prev.next = null;
prev.next = next;
}
public void reverse(){ // TODO: Last node links to a null node
Node prev = null;
Node current = head;
Node next = null;
while(current != null){
next = current.next;
current.next = prev;
prev = current;
current = next;
}
head = new Node(null);
head.next = prev;
}
public void display(){
Node current = head;
String diagram = String.format("head->");
while(current.next != null){
current = current.next;
diagram += String.format("%s->", current.data);
}
System.out.println(diagram);
}
private Node getNode(int index){
Node node = head;
for(int i = 0; i != index; i++){
node = node.next;
if(node == null){
throw new IndexOutOfBoundsException();
}
}
return node;
}
private Node getLastNode(){
Node current = head;
while(current.next != null){
current = current.next;
}
return current;
}
public class Node {
private Node next;
private T data;
public Node(T data){
this.data = data;
}
public Node getNext(){
return this.next;
}
}
}
And this main function:
LinkedList list = new LinkedList();
list.add("e1");
list.add("e2");
list.add("e3");
list.add("e4");
list.display();
list.reverse();
list.display();
The displayed result is:
head->e1->e2->e3->e4->
head->e4->e3->e2->e1->null->
This has happened due to the fact that e1 is still connected to the head. If I use the implementation of reverse available online:
Node prev = null;
Node current = head;
Node next = null;
while(current != null){
next = current.next;
current.next = prev;
prev = current;
current = next;
}
head = prev;
Then the result will ditch e4: head->e3->e2->e1->null->
What am I doing here? Why is my implementation different than everybody else's?
Also: Why does everyone use a reverse function that has head as an argument which could be problematic if the developer enters a different node?
You are using a first node as a head of your list. The solution for the reverse function is this:
head.next = prev;
You have to preserve the 'head' node, but change its 'next' field.
The rest of the function don't change at all:
public void reverse(){ // TODO: Last node links to a null node
Node prev = null;
Node current = head.next;
Node next = null;
while(current != null){
next = current.next;
current.next = prev;
prev = current;
current = next;
}
head.next = prev; // *** The only change ***
}
In your constructor you have:
public LinkedList(){
// Add HEAD
head = new Node(null);
}
then, 'head' is a Node that points to nothing initially.
In the reverse function, the 'head' node don't change, you don't need to create another out. But it has to point to the correct first Node.
If the list was empty, this 'head' points to null.
If the list has only one Node, this 'head' points to it yet.
If the list has more than one Node, this 'head' has to point to the last node.
Because of this, you need to change its 'next' field.