An code instance of expressing the characters of LinkedList:
public class SimpleLinkedListTest {
private class Node{
public Node(Object o) {
this.o = o;
}
Object o;
Node next;
}
private Node first;
public void add(Object elem){
Node node = new Node(elem);
if (first == null) {
first = node;
} else {
append(node);
}
}
private void append(Node node){
Node last = first;
while(last.next != null){
last = last.next;
}
last.next = node;
}
}
The instance describes the "Chain characteristic" to encapsulating new Objects,how can I understand the "append" method in it?And what is the exact
"encapsulating process" LinkedList type performs?
LinkedList has two pointers first and last Node.
public class LinkedList<E>
extends AbstractSequentialList<E>
implements List<E>, Deque<E>, Cloneable, java.io.Serializable
{
transient int size = 0;
transient Node<E> first;
transient Node<E> last;
And Node class has two pointers next and previous:
private static class Node<E> {
E item;
Node<E> next;
Node<E> prev;
Node(Node<E> prev, E element, Node<E> next) {
this.item = element;
this.next = next;
this.prev = prev;
}
}
Now when you add new element to the end of list it takes last Node and uses its next reference to link it to new node that contains your element:
void linkLast(E e) {
final Node<E> l = last;
final Node<E> newNode = new Node<>(l, e, null);
last = newNode;
if (l == null)
first = newNode;
else
l.next = newNode;
size++;
modCount++;
}
The same happens when you add element to beginning of list but this time it goes to Node first pointer.
And when you want to remove element it assigns null to Node next pointer of Node class.
Related
I would like to ask: how to add a new node before the head of a linked list:
Here is my code:
// Definition for singly-linked list.
public class ListNode {
int val;
ListNode next;
ListNode() {}
ListNode(int val) { this.val = val; }
ListNode(int val, ListNode next) { this.val = val; this.next = next; }
public void addAfter(ListNode thisnode, int x) {
ListNode newNode = new ListNode(x);
if(thisnode == null) {
//add before the head
newNode.next = this;
}//wrong here
else {
ListNode currentNext = thisnode.next;
thisnode.next = newNode;
newNode.next = currentNext;
}
return;
}//done addAfter this node
}
For example, with the input list 2 100 300 800, l.addAfter(null,500); the output should be
500 2 100 300 800 but my output is still 2 100 300 800. Thank you.
Inserting before head would change the value of head. Which you can't do from inside the method.
public ListNode addAfter(ListNode thisnode, int x) {
ListNode newNode = new ListNode(x);
if(thisnode == null) {
//add before the head
newNode.next = this;
return newNode;
} else {
ListNode currentNext = thisnode.next;
thisnode.next = newNode;
newNode.next = currentNext;
}
return this;
}
And the caller would call it like l = l.addAfter(null,500);
First of all, make your code clear, readable and consistent. Here is what you asked for:
public class Node {
private int value;
private Node next;
public Node(int value) {
this.value = value;
next = null;
}
public int getValue() {
return value;
}
public void setValue(int value) {
this.value = value;
}
public Node getNext() {
return next;
}
public void setNext(Node next) {
this.next = next;
}
}
public class ListNode {
private Node head;
public ListNode(Node head) {
this.head = head;
}
public Node getHead(){
return head;
}
// Here is your function
public void insertBeforeHead(int value) {
Node node = new Node(value);
node.setNext(head);
head = node;
}
}
// Node Class
public class SinglyListNode {
int val;
SinglyListNode next;
SinglyListNode(int x) { val = x; }
}
//Singly Linked List class
public class SinglyLinkedList {
private SinglyListNode head;
public SinglyLinkedList() {
head = null;
}
// add at beginning
public void addAtBeginning(int value){
SinglyListNode node = new SinglyListNode(value);
if (head != null) {
node.next = head;
}
head = node;
}
// print list
public void printList(){
System.out.println("printing linked list");
SinglyListNode curr = head;
while (curr != null){
System.out.println(curr.val);
curr = curr.next;
}
}
}
//main method
public static void main(String[] args) {
SinglyLinkedList linkedList = new SinglyLinkedList();
linkedList.addAtBeginning(5);
linkedList.addAtBeginning(6);
linkedList.addAtBeginning(7);
linkedList.printList();
}
You can always make one head that is constant and add all the new elements after it.
Example:
Head - Link1 - Link2 - Link3
Whenever you want to add newLink you can just add it in this manner.
Head - newLink - Link1 - Link2 - Link3
In this way you head information is never lost and it reduce the chances of losing your entire list.
You can explore my codebase here which implements it.
https://github.com/SayefReyadh/tutorials/tree/master/LinkedList-Bangla-Tutorial/LinkedListExample/src/linkedlistexample
The method is implemented as insertFront in LinkedList.java
The question is this:
Define a constructor that takes a TreeSet as a parameter and initializes a linked list with the elements in the set. The new list must be sorted in increasing lexicographic order.
This method is to be implemented using the class below:
public class LinkedList<T extends Comparable<T>> {
private class Node{
private T data;
private Node next;
private Node(T data){
this.data = data;
next = null;
}
}
private Node head;
public LinkedList(){
head = null;
}
Now I know a TreeSet is inherently sorted so all I'd really have to do here is take the element from the TreeSet and put it to the front of this linked list. But I'm having trouble retrieving the element from the set and adding it to the LinkedList. I wrote a private helper add(T data) method and am using it but I don't know if this is how I should approach it. I'm new to data structures so have little idea about sets and their implementations.
public class LinkedList<T extends Comparable<T>> {
private class Node{
private T data;
private Node next;
private Node(T data){
this.data = data;
next = null;
}
}
private Node head;
public LinkedList(){
head = null;
}
public void add(T data){
Node n = new Node(data);
if(head == null){
head = n;
}
else{
n.next = head;
head = n;
}
}
public LinkedList(TreeSet<T> test){
Iterator<T> itr = test.iterator();
while(itr.hasNext()){
this.add(itr.next());
}
}
The main problem you have to solve is that you need to add each item to the end of the list not the start.
Adding a node to the start of the list is easy:
public void addToHead(T data) {
Node node = new Node(data);
node.next = head;
head = node;
}
Adding to the end is harder because you don't have a reference to the tail. But the solution is fairly simple: in the constructor you are developing, keep a reference to the tail of the list so that you can add each value at the end of the links rather than the start.
The question includes "increasing lexicographic order."
My solution is without helper method:
public LinkedList(TreeSet<T> test){
Node currNode = null;
for(T data : test) {
Node newNode = new Node(data);
if(head == null) {
head = newNode;
currNode = head;
}
else {
currNode.next = newNode;
currNode = currNode.next;
}
}
}
Alright, I'm trying to implement a (Singly) Linked List via my textbook (Goodrich & Tamassia, Algorithm Design, 2001), and so far so good.
Now, the problem I'm running into, is that I cannot test it properly For example, if I would insert a node via my insertFirst method, how would I still be able to retrieve it to be able to use it for a method like swapElements?
I thought about working via elements, but then I'll run into problems when I have nodes with the same element. So, how should this work in general? I'm sorry if my question is relatively easy or vague, in that case please let me know how I can improve it as I'm fairly new to data structures.
Here's my code;
public class Node<E> implements Position<E> {
private Node<E> next;
private E element;
public Node(Node<E> next, E element) {
this.next = next;
this.element = element;
}
public Node(E element) {
this.element = element;
}
public void setNext(Node<E> next) {
this.next = next;
}
public Node<E> getNext() {
return next;
}
public void setElement(E element) {
this.element = element;
}
public E element() {
return element;
}
public String toString() {
return ("Element: " + element);
}
}
and
public class SinglyLinkedListImp<E> implements List<E> {
private Node<E> head;
private int size;
public SinglyLinkedListImp() {
this.head = null;
this.size = 0;
}
public Node<E> first() {
return head;
}
public Node<E> last() {
Node<E> current = head;
while (current.getNext() != null) {
current = current.getNext();
}
return current;
}
public boolean isFirst(Node<E> n) {
return (head == n);
}
public boolean isLast(Node<E> n) {
return (n.getNext() == null);
}
public Node<E> before(Node<E> n) {
Node<E> current = head;
while (current.getNext() != n) {
current = current.getNext();
}
return current;
}
public Node<E> after(Node<E> n) {
return n.getNext();
}
public Node<E> replaceElements(Node<E> n, E element) {
Node<E> current = head;
Node<E> previous = null;
while (current != n) {
previous = current;
current = current.getNext();
}
Node<E> newLink = new Node<E>(current.getNext(), element);
previous.setNext(newLink);
return current;
}
public void swapElements(Node<E> n, Node<E> k) {
E tmp = n.element();
n.setElement(k.element());
k.setElement(tmp);
}
public void insertFirst(E element) {
head = new Node<E>(head, element);
size++;
}
public void insertLast(E element) {
if (head == null) {
head = new Node<E>(head, element);
} else {
Node<E> current = head;
while (current.getNext() != null) {
current = current.getNext();
}
current.setNext(new Node<E>(null, element));
}
size++;
}
public void insertBefore(Node<E> n, E element) {
Node<E> current = head;
Node<E> previous = null;
while (current.getNext() != n) {
previous = current;
current = current.getNext();
}
previous.setNext(n);
}
public void insertAfter(Node<E> n, E element) {
Node<E> current = head;
while (current != n) {
current = current.getNext();
}
current.setNext(n);
}
public void remove(Node<E> n) {
Node<E> current = head;
Node<E> previous = null;
while (current != n) {
previous = current;
current = current.getNext();
}
previous.setNext(current.getNext());
size--;
}
public int size() {
return size;
}
public boolean isEmpty() {
return (size == 0);
}
public void display() {
if (head == null) {
System.out.println("Empty list.");
} else {
Node<E> current = head;
while (current != null) {
System.out.println(current.toString());
current = current.getNext();
}
}
}
}
Note that the SinglyLinkedListImp class is not totally done yet (some methods will give errors if the list is empty).
I don't think it's needed to provide the code for the two interfaces, but let me know if so.
In your implementation, you have set some methods (like getNext etc) that can be used in order to iterate the collection. A scenario that I can think of it is having retrieved any element of the list in one operation and then apply the editing on the collection based on the element (like swapElements) afterwards.
What I suggest you do though (and will probably make things clear) is add a retrieval method of an element by index:
a method get(int index) would return the element placed on the index given as argument. In fact, the LinkedList collection standard API in Java has such a method. The logic behind this is simple: get the next node till the iteration cycles number reaches the index number.
UPDATE: In order to apply element swapping, obviously the Nodes involved MUST be a part of the list, otherwise there is no meaning in this. As also suggested, swapElements might be basically used for in-class purposes, so unless you have a good reason for it, declare it private.
I am creating a singly linked circular list and I don't seem to understand why it is not working. Here is my code. Would someone help me and point out what am I doing wrong? I am able to add the first node but I don't understand how to add the second node. Could someone show me how to change it. I think my list is traversing endlessly that's why.
public class CircularList <E> {
private Node<E> head;
private class Node <E>
{
E data;
Node <E> next;
public Node(E data, Node<E> next)
{
this.data = data;
this.next = next;
}
public Node(E data)
{
this.data = data;
this.next = null;
}
}//node
public CircularList()
{
head = null;
}
public void add(E data)
{
Node <E> temp = new Node <E> (data);
if(head==null)
{
head=temp;
temp.next=temp;
System.out.println(head.next.data);
}
else
{
Node<E> temp2 = head.next;
while(temp2!=head)
{
if(temp2.next==head)
{
temp2.next=temp;
temp.next=head;
}
temp2=temp2.next;
}
}
}
Update your else part with this;
Node<E> temp2 = head;
while(temp2.next != head)
{
temp2=temp2.next;
}
temp2.next=temp;
temp.next=head;
If you would like to make your singly linked list circular, it would be a good idea to have a tail, then your code can be something along the lines of (pseudo code)
function addElement(data){
Node n = new Node(data)
if(list.isEmpty() ){
head = n
tail = n
n.setNext(n)
} else {
n.setNext(head)
tail.setNext(n)
head = n
}
}
I am getting this error "Type mismatch: cannot convert from Object to E" in the last line of the pop() method.
Node
public class Node<E> {
E item;
Node next;
Node(E item) {
this.item = item;
this.next = null;
}
Node(E item, Node next) {
this.item = item;
this.next = next;
}
}
Stack
import java.util.NoSuchElementException;
public class Stack<E> {
private Node head;
private int size;
Stack() {
head = null;
size = 0;
}
public void push(E item) {
head = new Node (item, head);
size++;
}
public E pop() throws NoSuchElementException {
Node nodeToBePopped;
if (size == 0) {
throw new NoSuchElementException();
}
nodeToBePopped = head;
head = head.next;
size--;
return nodeToBePopped.item;
}
}
I don't understand why that error occurs despite item being declared as type E in the Node class. Why do I have to make an explicit cast in this instance?
This is the problem in Stack<E>:
private Node head;
and likewise later:
Node nodeToBePopped;
And in Node<E> itself:
Node next;
You're using the raw type Node here, so all the generics are lost, effectively. See the Java Generics FAQ for more information about raw types.
Just change the variable types to Node<E> and it should be fine.
I'd also recommend using private fields, and only declaring local variables at the point of first use - so your pop method would become:
public E pop() throws NoSuchElementException {
if (size == 0) {
throw new NoSuchElementException();
}
Node<E> nodeToBePopped = head;
head = head.next;
size--;
return nodeToBePopped.item;
}
Or in fact, just find the value to return from head before you change what head refers to:
public E pop() throws NoSuchElementException {
if (size == 0) {
throw new NoSuchElementException();
}
E previousHeadValue = head.item;
head = head.next;
size--;
return previousHeadValue;
}
Change the types of head and nodeToBePopped to Node<E>
This is because you have not specified that Stack<E> will have only elements of type Node<E>
Similarly change the push method and also the next variable in Node<E>.