I've just started learning about linked lists and need help with this piece of code. I need to write a method that copies all the items from one single linked list to another.
Any help would be appreciated. Thanks.
public static ListNode copy(ListNode list){
//code
}
Just from the top of my head something to start with, but as mentioned above in the comments you should probably ask more specific questions.
class ListNode {
int value;
ListNode next;
public ListNode(int value) {
super();
this.value = value;
}
}
public class Test {
public static ListNode copy(ListNode list){
if (list == null)
return null;
ListNode res = new ListNode(list.value);
ListNode resTmp = res;
ListNode listTmp = list;
while (listTmp.next != null){
listTmp = listTmp.next;
resTmp.next = new ListNode(listTmp.value);
resTmp = resTmp.next;
}
return res;
}
public static void main(String[] args) {
ListNode input = new ListNode(11);
input.next = new ListNode(12);
input.next.next = new ListNode(13);
ListNode output = copy(input);
while (output != null){
System.out.println(output.value);
output = output.next;
}
}
}
Related
I doesnt quite get why the part with the object names down there works? I invoke the method append(int number) with a parameter in my main method and create a List of Node Objects that store integer values this way. However, why wont the object names "temp" and "current" be replaced when a call append a second, a third.... time. They are always the same object names and one object name cant refer to multiple objects, I thought. When I call the method elementAt(), I get everytime the response I wanna have, but I dont know exactly why it did work.
Heres my Code for the Class MyList
public class MyList
{
Node head;
int count;
Node temp;
Node current;
public MyList(){
head= new Node(0);
count = 0;
}
public void append(int number){
temp = new Node(number);
current = head;
while(current.getNext() != null){
current = current.getNext();
}
current.setNext(temp);
count++;
}
public int elementAt(int number){
if(head != null){
current = head.getNext();
for(int i = 0; i < number ; i++){
if(current.getNext() == null){
return 0;
}
current = current.getNext();
}
return current.item;
}
return 0;
}
}
Heres the Code for the Class Node
public class Node {
public int item;
public Node next;
public Node(int item){
this.item = item;
}
public Node getNext(){
return next;
}
public void setNext(Node next){
this.next = next;
}
}
Heres the code for my the Main Class
public class MainList {
public static void main(String[] args) {
MyList list = new MyList();
list.append(10);
list.append(20);
list.append(30);
list.append(40);
list.append(50);
list.append(60);
list.append(40);
System.out.println(list.elementAt(0));
}
}
I'm running below simple linked list program in java, but I'm getting one element short.
The output I'm getting
10
8
1
public class SinglyLinkedList {
ListNode head;
private static class ListNode {
int data;
ListNode next;
public ListNode(int data) {
this.data=data;
this.next = null;
}
}
public void display() {
ListNode curentNode = head;
while (curentNode.next != null) {
System.out.println(curentNode.data);
curentNode = curentNode.next;
}
}
public static void main(String[] args) {
SinglyLinkedList sll = new SinglyLinkedList();
sll.head = new ListNode(10);
ListNode second = new ListNode(8);
ListNode third = new ListNode(1);
ListNode fourth = new ListNode(10);
sll.head.next = second;
second.next = third;
third.next = fourth;
sll.display();
}
}
You need to traverse the LinkedList till the node is not null. If current node is not null, print the node's data and move ahead. But if you check curentNode.next != null you can print the data till second last node only.
public class SinglyLinkedList
{
ListNode head;
private static class ListNode
{
int data;
ListNode next;
public ListNode(int data)
{
this.data=data;
this.next = null;
}
}
public void display()
{
ListNode curentNode = head;
while (curentNode != null) <------// Modified //
{
System.out.println(curentNode.data);
curentNode = curentNode.next;
}
}
public static void main(String[] args)
{
SinglyLinkedList sll = new SinglyLinkedList();
sll.head = new ListNode(10);
ListNode second = new ListNode(8);
ListNode third = new ListNode(1);
ListNode fourth = new ListNode(10);
sll.head.next = second;
second.next = third;
third.next = fourth;
sll.display();
}
}
Your while condition checks for next item in the list. Your last item in the list does not satisifies your condition.
Last item's next item is always null.
change the condition
I already wrote a small program of single linked list with add and traverse method in that. Now I want to convert it into a doubly linked list. I know all the concept of doubly linked list but I am facing little difficulty to implement it in my program.
public class SingleLinkList<T> {
private Node<T> head;
private Node<T> tail;
public void add(T element)
{
Node<T> nd = new Node<T>();
nd.setValue(element);
if (head==null)
{
head = nd;
tail = nd;
}
else
{
tail.setNextRef(nd);
tail = nd;
}
}
public void traverse(){
Node<T> tmp = head;
while(true){
if(tmp == null){
break;
}
System.out.println(tmp.getValue());
tmp = tmp.getNextRef();
}
}
public static void main (String args[])
{
SingleLinkList<Integer> s1 = new SingleLinkList<Integer>();
s1.add(2);
s1.add(3);
s1.add(3);
s1.traverse();
}
}
class Node<T> {
private T value;
private Node<T> nextRef;
public T getValue() {
return value;
}
public void setValue(T value) {
this.value = value;
}
public Node<T> getNextRef() {
return nextRef;
}
public void setNextRef(Node<T> nextRef) {
this.nextRef = nextRef;
}
public int compareTo(T arg)
{
if (arg==this.value)
{
return 0;}
else
{return 1;}
}
}
Add a Node<T> prevRef field to your list class with appropriate getters and setters and then add this method:
public void linkReverse(Node<T> head) {
if (head == null) {
return;
}
head.setPrevRef(null);
if (head.getNextRef() == null) {
return;
}
Node<T> prev = head;
Node<T> curr = head.getNextRef();
while (curr != null) {
curr.setPrevRef(prev);
prev = curr;
curr = curr.getNextRef();
}
}
This method will walk down a currently singly linked list and will link each node in reverse, leaving the list doubly linked.
Of course, you would need to modify the other methods as well, but this is at least a good starting point.
just add private Node<T> prevRef; instance variable to Node class, and set it during add() method. I suggest that traverse() will receive a boolean (or even better, enum) direction argument
I have been diligently watching YouTube videos in an effort to understand linked lists before my fall classes start and I am uncertain how to proceed with iterating over the following linked list. The 'node' class is from a series of videos (same author), but the 'main' method was written by me. Am I approaching the design of a linked list in an illogical fashion (assuming of course one does not wish to use the predefined LinkedList class since the professor will expect each of us to write our own implementation)?:
class Node
{
private String data;
private Node next;
public Node(String data, Node next)
{
this.data = data;
this.next = next;
}
public String getData()
{
return data;
}
public Node getNext()
{
return next;
}
public void setData(String d)
{
data = d;
}
public void setNext(Node n)
{
next = n;
}
public static String getThird(Node list)
{
return list.getNext().getNext().getData();
}
public static void insertSecond(Node list, String s)
{
Node temp = new Node(s, list.getNext());
list.setNext(temp);
}
public static int size(Node list)
{
int count = 0;
while (list != null)
{
count++;
list = list.getNext();
}
return count;
}
}
public class LL2
{
public static void main(String[] args)
{
Node n4 = new Node("Tom", null);
Node n3 = new Node("Caitlin", n4);
Node n2 = new Node("Bob", n3);
Node n1 = new Node("Janet", n2);
}
}
Thanks for the help,
Caitlin
There are some flaws in your linked list as stated by some of the other comments. But you got a good start there that grasps the idea of a linked list and looks functional. To answer your base question of how to loop over this particular implemention of the linked list you do this
Node currentNode = n1; // start at your first node
while(currentNode != null) {
// do logic, for now lets print the value of the node
System.out.println(currentNode.getData());
// proceed to get the next node in the chain and continue on our loop
currentNode = currentNode.getNext();
}
Maybe this will be useful:
static void iterate(Node head) {
Node current = head;
while (current != null) {
System.out.println(current.getData());
current = current.getNext();
}
}
// or through recursion
static void iterateRecursive(Node head) {
if (head != null) {
System.out.println(head.getData());
iterateRecursive(head.getNext());
}
}
class List {
Item head;
class Item {
String value; Item next;
Item ( String s ) { value = s; next = head; head = this; }
}
void print () {
for( Item cursor = head; cursor != null; cursor = cursor.next )
System.out.println ( cursor.value );
}
List () {
Item one = new Item ( "one" );
Item two = new Item ( "three" );
Item three = new Item ( "Two" );
Item four = new Item ( "four" );
}
}
public class HomeWork {
public static void main( String[] none ) { new List().print(); }
}
Good luck!!
You can have your linked list DS class implement 'Iterable' interface and override hasNext(), next() methods or create an inner class to do it for you. Take a look at below implementation:
public class SinglyLinkedList<T>{
private Node<T> head;
public SinglyLinkedList(){
head = null;
}
public void addFirst(T item){
head = new Node<T>(item, head);
}
public void addLast(T item){
if(head == null){
addFirst(item);
}
else{
Node<T> temp = head;
while(temp.next != null){
temp = temp.next;
}
temp.next = new Node<T>(item, null);
}
}
private static class Node<T>{
private T data;
private Node<T> next;
public Node(T data, Node<T> next){
this.data = data;
this.next = next;
}
}
private class LinkedListIterator implements Iterator<T>{
private Node<T> nextNode;
public LinkedListIterator(){
nextNode = head;
}
#Override
public boolean hasNext() {
return (nextNode.next != null);
}
#Override
public T next() {
if(!hasNext()) throw new NoSuchElementException();
T result = nextNode.data;
nextNode = nextNode.next;
return result;
}
}
}
Hey, so I wanted to insert one data after the input data (not index).
I've tried but it always at the end, the data that i want to insert end up at the dront of the link list..
**public static void insertAfter(Object o,Object c){
Node newN = new Node();
Node help = new Node();
Node help2 = new Node();
newN.data = o;
help = head.next;
if(isEmpty()){
head = newN;
newN.next=head;
newN.prev=head;
}
else{
do{
help=help.next;
System.out.println(help);
}while(help.next!=head || !help.data.equals(c));
help2 = help.next;
newN.next = help2;
help2.prev = newN;
help.next=newN;
newN.prev=help;
}**
anyone could help?
thx a bunch!
What are the objects that you are comparing? if they are something other than string than you will have to override equals() method in order to get the correct comparison.
I think you should try another ending condition:
while(help.next!=head && !help.data.equals(c));
By the way, I can only advise you to avoid do...while without serious reasons, and to use getters and setters.
Your code should also be structured diffently. Why are you not writing a private method which just make the insert, i.e. your 5 last lines? Everything would be more readable and reusable.
Also, your variables need clear and meaningful names.
Do it yourself
I begun fixing your solution but ended writing a whole new implementation when wanting to test it... so here goes:
public class DoubleLinkedList<T> {
private class Node {
private Node prev;
private Node next;
private T data;
Node(T data) {
this.data = data;
}
}
Node head;
public boolean isEmpty() {
return head == null;
}
public void insertAfter(T afterThis, T objectToAdd) {
// cannot insert after in a empty list?!
if(isEmpty())
throw new NoSuchElementException("list is empty?");
// find the node where we want to insert the element
Node after = findNodeByObject(afterThis);
// create the node and update the links
addAfter(after, new Node(objectToAdd));
}
private void add(T objectToAdd) {
if (isEmpty()) {
head = new Node(objectToAdd);
head.next = head;
head.prev = head;
}
else {
addAfter(head.prev, new Node(objectToAdd));
}
}
private void addAfter(Node after, Node toAdd) {
Node afterAfter = after.next;
after.next = toAdd;
afterAfter.prev = toAdd;
toAdd.prev = after;
toAdd.next = afterAfter;
}
private Node findNodeByObject(T object) {
Node current = head;
while (true) {
if (current.data.equals(object))
return current;
if (current.next == head)
break;
current = current.next;
}
throw new NoSuchElementException("" + object);
}
#Override
public String toString() {
List<T> printList = new LinkedList<T>();
Node current = head;
while (true) {
printList.add(current.data);
if (current.next == head)
break;
current = current.next;
}
return printList.toString();
}
public static void main(String[] args) throws Exception {
DoubleLinkedList<String> list = new DoubleLinkedList<String>();
list.add("first");
list.add("third");
list.insertAfter("first", "second");
System.out.println(list);
}
}
Extend LinkedList
... and add the insertAfter method like this:
import java.util.LinkedList;
import java.util.ListIterator;
public class MyList<T> extends LinkedList<T> {
private void insertAfter(T first, T second) {
ListIterator<T> iterator = listIterator();
while (iterator.hasNext()) {
if (iterator.next().equals(first)) {
iterator.add(second);
return;
}
}
throw new IndexOutOfBoundsException("Could not find " + first);
}
public static void main(String[] args) throws Exception {
MyList<String> list = new MyList<String>();
list.add("first");
list.add("third");
list.insertAfter("first", "second");
System.out.println(list); // prints "[first, second, third]"
}
}