Here's what I have:
public class Node{
Object data;
Node next;
Node(Object data, Node next){
this.data = data;
this.next = next;
}
public Object getData(){
return data;
}
public void setData (Object data){
this.data = data;
}
public Node getNext(){
return next;
}
public void setNext(Node next){
this.next = next;
}
}
How do I write the code to add a Node at the end of a list?
So if I had
head -> [1] -> [2] -> null
How do I get to
head -> [1] -> [2] -> [3] -> null
Actually...I'm not even sure if I have to add to the end. I think it's valid to add and then sort? Not sure.
Thanks!
public void addToEnd(Object data){
Node temp = this;
while(temp.next!=null)temp=temp.next;
temp.next=new Node(data, null);
}
It's a linked list. You either have to
A) iterate through all your nodes starting at the head, find the last node, then add one.
or
B) keep track of the tail, add to the tail, then update tail to the new last node.
Start from the head:
Node currentNode = headNode;
while (node.getNext() != null) {
currentNode = currentNode.getNext();
}
currentNode.setNext(newNodeForInsertion);
A faster way is to store the last node of the list somewhere so you don't have to go through the whole list.
Recursively navigate through each node until you hit the end.
public void navigate(Node insertNode)
{
if(next == null)
next = insertNode;
else
next.navigate(insertNode);
}
To add to the end, you'd have to walk to the end of the list (i.e., to where next=null) and add a new node there.
In the real world, you'd use an ArrayList for this and not bother with a linked list or manual structure at all.
In your method to add a node, write a while loop that starts at the head and looks to see if the "next node" is null. If it is not, advance to the "next node" and repeat.
Once you are at the node that points to nothing, adding the node is as simple as reassigning the null reference to the node to be added.
A recursive solution:
public void addToEnd(Object data){
if (next==null)
next = new Node(data, null);
else
next.addToEnd(data);
}
Node n = head;
while(n.getNext() != null){
n = n.getNext();
}
n.setNext(nodeToAdd);
That's not sorted, which I can't tell from your question if you want it sorted. Which opens up another whole can of worms such as what do you want to sort on, if you have a linked list of type Object there isn't really anything meaningful to sort on.
Related
I'm creating my first linked list and while I understand doubly linked lists are really for going backwards I am attempting to create a method that moves the current node backwards in the list by one node in a SINGLY linked list.
Here's what I got so far, I've included my go to next for reference and constructors:
//Paramaterized construct
public ListNode(int aData, ListNode aLink) {
this.data= aData;
this.link = aLink;
}
}
private ListNode head; //First element
private ListNode current; //Current node of interest
private ListNode previous; //Node behind current
public void goToNext () {
previous = current;
current = current.link;
}
//TODO: Fix previous
public void goToPrev () {
if (current != head) {
}
else
System.out.println("Current node is the head, sorry");
I forgot to add my private ListNode class:
private class ListNode
{
private int data;
private ListNode link;
//Default construct
public ListNode ()
{
this.data = data;
this.link = link;
}
//Paramaterized construct
public ListNode(int aData, ListNode aLink)
{
this.data= aData;
this.link = aLink;
}
}
I'm thinking I have to iterate from the start of the list until I find the node that has next equal to my current node. But I'm not sure how to exactly set up that while loop and have the correct body.
To do this you need to iterate over the list with TWO pointers, not one. The trick is to have one ahead of the other by exactly one node, so when pointer #1 finds the node of interest, pointer #2 is the node behind it in the list and you can "move backwards" by accessing #2.
You can not iterate singly linked list backwards. If you want to iterate backwards then you should you doubly linked list. Or you can achieve this take ref of the node before iterate.
I am still learning Java, and currently working problems from Cracking the Coding Interview, and one of the problems on Chapter-2 (LinkedList) asks to remove duplicates from an unsorted linked List. I found a bunch of answers/solution on GitHub, but I would like to create my own Node, and write my own version.
What I have implemented so far is that I created Node class and write the function/method that can remove the duplicates from unsorted LinkedList, but when I try to test it, I tried to create the LinkedList in the main function, but I still have no idea how to figure it out. Can someone please help/guide me how to create a Singly LinkedList?
Basically, I create four nodes (fourth,third,second,head), and connect them all using the Node class.
Thanks in advance,
public class Node {
int data;
Node next;
public Node(int data, Node next){
this.data = data;
this.next = next;
}
public String toString(){
return data + "";
}
}
public class problem1 {
public void Remove_duplicates(Node head){
if(head == null){
return;
}
Node current = head;
while(current != null){
Node runner = current;
while(runner.next != null){
if(runner.next.data == current.data){
runner.next = runner.next.next;
}
else {
runner = runner.next;
}
}
current = current.next;
}
}
public static void main(String[] args) {
Node fourth = new Node(5,null);
Node third = new Node(3,fourth);
Node second = new Node(4,third);
Node head = new Node(3,second);
for(Node a: head){
// ERROR: saying can only iterate over an array (or) java.lang.Iterable
System.out.println(a.toString());
a = a.next;
}
}
}
Try another kind of loop e.g. while
Node head = new Node(3, second);
Node node = head;
while (node.next != null) {
System.out.println(node.toString());
node = node.next;
}
Like it explains it does not know how to iterate over your nodes.
Another approach for using the foreach would be to create an own class which implements the interface Iterable and does contain your LinkedList logic.
For the second approach I would suggest you to read the following: How can I implement the Iterable interface?
Here's what I have:
public class Node{
Object data;
Node next;
Node(Object data, Node next){
this.data = data;
this.next = next;
}
public Object getData(){
return data;
}
public void setData (Object data){
this.data = data;
}
public Node getNext(){
return next;
}
public void setNext(Node next){
this.next = next;
}
}
How do I write the code to add a Node at the end of a list?
So if I had
head -> [1] -> [2] -> null
How do I get to
head -> [1] -> [2] -> [3] -> null
Actually...I'm not even sure if I have to add to the end. I think it's valid to add and then sort? Not sure.
Thanks!
public void addToEnd(Object data){
Node temp = this;
while(temp.next!=null)temp=temp.next;
temp.next=new Node(data, null);
}
It's a linked list. You either have to
A) iterate through all your nodes starting at the head, find the last node, then add one.
or
B) keep track of the tail, add to the tail, then update tail to the new last node.
Start from the head:
Node currentNode = headNode;
while (node.getNext() != null) {
currentNode = currentNode.getNext();
}
currentNode.setNext(newNodeForInsertion);
A faster way is to store the last node of the list somewhere so you don't have to go through the whole list.
Recursively navigate through each node until you hit the end.
public void navigate(Node insertNode)
{
if(next == null)
next = insertNode;
else
next.navigate(insertNode);
}
To add to the end, you'd have to walk to the end of the list (i.e., to where next=null) and add a new node there.
In the real world, you'd use an ArrayList for this and not bother with a linked list or manual structure at all.
In your method to add a node, write a while loop that starts at the head and looks to see if the "next node" is null. If it is not, advance to the "next node" and repeat.
Once you are at the node that points to nothing, adding the node is as simple as reassigning the null reference to the node to be added.
A recursive solution:
public void addToEnd(Object data){
if (next==null)
next = new Node(data, null);
else
next.addToEnd(data);
}
Node n = head;
while(n.getNext() != null){
n = n.getNext();
}
n.setNext(nodeToAdd);
That's not sorted, which I can't tell from your question if you want it sorted. Which opens up another whole can of worms such as what do you want to sort on, if you have a linked list of type Object there isn't really anything meaningful to sort on.
I have been trying to implement a singly linked list in java with generics and I tried to implement a method "headInsert()" to insert a new Node and make it the new head of the list.
I am trying to achieve this by creating a new Node and swapping it with the head.
However, I have an error while I am trying to parameterize the new Node.
Here is the code I have written and I would appreciate any sort of help I could get.
Thank you in advance.
package datastructures;
public class LinkedList<E> {
private Node head;
private Node tail;
private static class Node<E> {
E data;
Node next;
Node (E data) {
this.data = data;
}
}
//Insert at the beginning of a LinkedList
public void headInsert(Node n) {
if(head == null) {
head = n;
}
else {
Node temp = head;
Node n1 = new Node(n1.data); //error here
n1.next=head;
head=n1;
}
}
The error occurs because n1 was not created yet when you try to access n1.data, it should be:
Node n1 = new Node(n.data);
That said, you don't really need to create a new node to place in the head. You can implement headInsert() like this:
public void headInsert(Node n) {
n.next = this.head;
this.head = n;
}
Suppose you have an empty list (head is null) and you want to add node A, A.next will point to null, and head will point to A resulting in the list A->null
Now suppose you have a non-empty list, like A->B->C, and you want to insert node Z, Z.next will point to A, and head will point to Z so you will get Z->A->B->C.
Im trying to make an Add and Delete method to my linked list class. I made 2 references with the names Head and Tail.
Head -> 1 -> 2 -> 3 -> Tail:null
I keep getting problems when I try and delete specific nodes because Java says I'm out of bounds. I think it is because my Head isn't pointing to the first Node? What do you guys think? Or am i going about this the total wrong way...
public class LinkedList{
private Node head;
private Node tail;
private int listCount;
public LinkedList()
{
head = new ListNode(null);
tail = new ListNode(null);
listCount = 0;
}
public void add(Object elem){
ListNode newNode = new ListNode(elem);
if (size() == 0){
newNode = head;
tail = head;
}
newNode.setLink(tail);
tail = newNode;
listCount++;
}
public Object delete(int index)
// post: removes the element at the specified position in this list.
{
// if the index is out of range, exit
if(index < 1 || index > size())
throw new IndexOutOfBoundsException();
ListNode current = head;
for(int i = 1; i < index; i++)
{
if(current.getLink() == null)
throw new IndexOutOfBoundsException();
current = current.getLink();
}
current.setLink(current.getLink().getLink());
listCount--; // decrement the number of elements variable
return current.getInfo();
}
public int size() {
return listCount;
}
}
public class Node {
private Node link;
private Object info;
public Node(Object info)
{
this.info = info;
link = null;
}
public void setInfo(Object info)
{
this.info = info;
}
public Object getInfo()
{
return info;
}
public void setLink(Node link)
{
this.link = link;
}
public Node getLink()
{
return link;
}
}
I think it's because your head never links to anything. What I would do to fix it is in your add method, check the size of your list; if it's 0, set the head to the new element and set the tail equal to the head. If it's 1, link the head to the new node and set tail. If it's 2, just set the tail's link to the new node and set the tail (like you have now).
Also, I'm not sure how you implemented it, but newNode.setLink(tail); seems wrong...the tail should be linked to newNode. From the way it looks, it seems like you're trying to do newNode -> tail
EDIT: Ok, here is why I would try
public void add(Object elem){
ListNode newNode = new ListNode(elem);
if (size() == 0){
newNode = head;
tail = head;
}else if(size() == 1){
head.setLink(newNode);
tail = newNode;
}else{
tail.setLink(newNode);
tail = newNode;
}
listCount++;
}
Looks like you did not initialize the link from head to tail when you set up your initial (empty) linked list.
Ok. Here is a strategy to use when working with singly linked lists (forward link only). You need to determine what actions will be allowed on the list (e.g. add/remove from head or tail only?; or add and remove nodes anywhere in the linked list (bringing the list back together once you have cut a node out). If you will be allowing nodes to be deleted from anywhere, then you will need to have a way of UNIQUELY identifying each node (so you can unambiguously determine the node that will be deleted). You may also want to be able to add a node before or after some other node . and uniqueness may be needed for that. If you do NOT care which value you delete or add before/after then you can relax the uniqueness constraint.
Now for strategy to implement. Start with a head (initially null).
To add a node, walk down your linked list until you find a null next link. Replace that with your node, and have your nodes forward link set to null. (Efficiency improvement, have a tail that always has the last node in the linked list, or null if there is nothing in the list).
To delete a node, walk your list until you find the node you want to delete, change the previous link to the link in the node to be deleted (you are now done)
To add a node at the end of the list, go to the link pointed to by tail (if null, list is emplty); change its link to your node, ensure your new node has a null in its link; and set the tail to your node
To count size of linked list, either walk your tree and count (or, for computational efficiency, keep a running size that is incremented or decremented when you add or delete a node.
Does this help?
Look at this link for a full description!