how to merge 2 linked lists - java

I am trying to make a method to merge two linked lists for a homework assignment in my programming class. I'm really confused here, the method has to have this method signature:
public UnorderedLinkedListInt merge2(UnorderedLinkedListInt list), so in my tester method it will look like this list3 = list1.merge2(list2). I'm confused on how to make this when the method only takes in one list and not both. Here is my code so far
public class UnorderedLinkedListInt extends LinkedListIntClass {
//Default constructor
public UnorderedLinkedListInt() {
super();
}
public boolean search(int searchItem) {
LinkedListNode current; //variable to traverse the list
current = first;
while (current != null)
if (current.info == searchItem)
return true;
else
current = current.link;
return false;
}
public void insertFirst(int newItem) {
LinkedListNode newNode; //variable to create the new node
//create and insert newNode before first
newNode = new LinkedListNode(newItem, first);
first = newNode;
if (last == null)
last = newNode;
count++;
}
public void insertLast(int newItem) {
LinkedListNode newNode; //variable to create the new node
//create newNode
newNode = new LinkedListNode(newItem, null);
if (first == null) {
first = newNode;
last = newNode;
}
else {
last.link = newNode;
last = newNode;
}
count++;
}
public void deleteNode(int deleteItem) {
LinkedListNode current; //variable to traverse the list
LinkedListNode trailCurrent; //variable just before current
boolean found;
//Case 1; the list is empty
if ( first == null)
System.err.println("Cannot delete from an empty list.");
else {
//Case 2: the node to be deleted is first
if (first.info == deleteItem) {
first = first.link;
if (first == null) //the list had only one node
last = null;
count--;
}
else { //search the list for the given info
found = false;
trailCurrent = first; //trailCurrent points to first node
current = first.link; //current points to second node
while (current != null && !found) {
if (current.info == deleteItem)
found = true;
else {
trailCurrent = current;
current = current.link;
}
}
//Case 3; if found, delete the node
if (found) {
count--;
trailCurrent.link = current.link;
if (last == current) //node to be deleted was the last node
last = trailCurrent;
}
else
System.out.println("Item to be deleted is not in the list.");
}
}
}
public void merge(UnorderedLinkedListInt list2){
UnorderedLinkedListInt list1 = this;
while (list2.first != null) {//while more data to print
list1.insertLast(list2.first.info);
list2.first = list2.first.link;
}
}
public UnorderedLinkedListInt merge2(UnorderedLinkedListInt list2){
UnorderedLinkedListInt list3 = new UnorderedLinkedListInt();
UnorderedLinkedListInt list1 = this;
while (list1.first != null) {//while more data to print
list3.insertLast(list1.first.info);
list1.first = list1.first.link;
}
while (list2.first != null) {//while more data to print
list3.insertLast(list2.first.info);
list2.first = list2.first.link;
}
return list3;
}
}
I'm still having some trouble understanding exactly how linked lists work, any suggestions as to how to design this method would be greatly appreciated.

In a method call like list1.merge2(list2), the method receives list1 as the implicit "current object" that you can access with the this reference.
If you want to you can use another name for it:
public UnorderedLinkedListInt merge2(UnorderedLinkedListInt list2){
UnorderedLinkedListInt list1 = this;
// now merge list1 and list2
}

Your first list would be actual Object pointed to by the this reference.

Try this:
import java.io.*;
class Node1
{
int data;
Node1 link;
public Node1()
{
data=0;
link=null;
}
Node1 ptr,start,temp,ptr1;
void create()throws IOException
{
int n;
BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
System.out.println("Enter first data");
this.data=Integer.parseInt(br.readLine());
ptr=this;
start=ptr;
char ins ='y';
do
{
System.out.println("Wanna Insert another node???");
ins=(char)br.read();
br.read();
if(ins=='y')
{
temp=new Node1();
System.out.println("Enter next data");
temp.data=Integer.parseInt(br.readLine());
temp.link=null;
ptr.link=temp;
temp=null;
ptr=ptr.link;
}
}while(ins=='y');
}
void merge()throws IOException
{
ptr1=this;
ptr=this;
Node1 t=new Node1();
t.create();
while(ptr1.link!=null)
{ ptr1=ptr1.link;}
ptr1.link=t.start;
ptr1=t=null;
System.out.println("---------------------------");
System.out.println("Merged LL :\n");
while(ptr!=null)
{
System.out.print("-->"+ptr.data);
ptr=ptr.link;
}
}
}

Related

Is the implementation for Graph using Adjacency list correct?

I am a beginner with DSA, Since the last couple of days, I was trying to find the correct implementation for the Graph using the adjacency list.
Below I provided the entire code for the way I thought the adjacency list should be implemented.
I have created a SinglyLinkedlist from scratch.
And I am using a Hashmap to improve the Time complexity.
The Integer key in the Hashmap acts as the VERTICE & consists of a LinkedList in its VALUE.
In the vertices, I am storing the Integer ID and in the LinkedList, I am storing all the Friend names for that particular ID.
The Graph has 3 methods:
InsertVertice(int ID ) - creates an empty LinkedList at given ID in hashmap.
insertDataAtID (int ID, String data) - inserts the Data into the LinkedList at the given ID.
printAllDataAtID(int ID) - prints all the friend names or Data present in a LinkedList at a given ID/key in the Hashmap.
Can you please go through the Implementation and advice of any mistakes?
Or better some suggestions on how an Adjacency list can be implemented more effectively?
Thank you for this effort.
import java.util.HashMap;
public class demo {
static HashMap<Integer,SinglyLinkedlist> graph = new HashMap<>();
public static void main(String[] args){
Graph graph = new Graph();
graph.insertVertice(101);
graph.insertDataAtID(101,"Deepesh");
graph.insertDataAtID(101,"Kiran");
graph.insertDataAtID(101,"Aryan");
graph.insertVertice(201);
graph.insertDataAtID(201,"Carl");
graph.insertDataAtID(201,"Arun");
graph.insertDataAtID(201,"Kishan");
graph.insertDataAtID(201,"Betth");
graph.printAllDataAtID(101);
graph.printAllDataAtID(201);
}
}
import java.util.HashMap;
public class Graph{
HashMap<Integer,SinglyLinkedlist> maplist = new HashMap<>();
void insertVertice(Integer id ){
maplist.put(id,new SinglyLinkedlist());
}
void insertDataAtID(Integer id, String data){
if (maplist.get(id)==null){
System.out.println("No such Vertice exist with id : " + id);
System.out.println("Create the Vertice first by calling insertVertice() method.");
}
SinglyLinkedlist linkedlist = maplist.get(id);
linkedlist.insertNode(data);
}
void printAllDataAtID(Integer id) throws NullPointerException {
if (maplist.get(id) == null) {
System.out.println("No such Vertice exist with id : " + id);
System.out.println("Create the Vertice first by calling insertVertice() method.");
} else {
SinglyLinkedlist linkedlist = maplist.get(id);
linkedlist.printAll();
}
}
}
public class SinglyLinkedlist {
Node head;
Node tail;
public static class Node {
Node next;
String data;
}
void insertNode(String data) {
Node newNode = new Node();
newNode.data = data;
if (head == null) {
head = tail = newNode;
newNode.next = null;
} else {
Node temp = head;
while (temp.next != null) {
temp = temp.next;
}
temp.next = newNode;
newNode.next = null;
tail = newNode;
}
}
void removeLastNode() {
Node temp = head;
while (temp.next.next != null) {
temp = temp.next;
}
Node removedNode = temp.next;
tail = temp;
tail.next = null;
System.out.println("Removed value : " + removedNode.data);
}
void printAll() {
if (head == null) {
System.out.println("List is Empty !");
} else {
Node temp = head;
while (temp != null) {
System.out.print(temp.data + " ");
temp = temp.next;
}
}
}
boolean search(String data) {
if (head == null) {
System.out.println("List is Empty !");
} else {
Node temp = head;
while (temp != null) {
if (temp.data.equals(data)) {
System.out.println("Value found !");
return true;
}
temp = temp.next;
}
System.out.println("Value not found !");
}
return false;
}
}
You don't need to traverse the list to insert if you are maintaining tail node.
void insertNode(String data) {
Node newNode = new Node();
newNode.data = data;
if (head == null) {
head = tail = newNode;
newNode.next = null;
} else {
tail.next = newNode;
newNode.next = null;
tail = tail.next;
}
}

How do I write an addElement method to a sorted LinkedList?

I have an assignment that goes:
implement a linked list of String objects by use of the class Node (see Big >Java Early Objects 16.1.1). Write methods, that make it possible to insert >and delete objects, as well as print all objects in the list. It is a >requirement that all elements in the list are sorted, at all times, according >to the natural ordering of Strings(Comparable).
The method that I can't seem to get right, is the addElement method
The entire class is here: https://pastebin.com/Swwn8ykZ
And the mainApp: https://pastebin.com/A22MFDQk
I've looked through the book (Big Java Early Objects), as well as looked on geeksforgeeks
public void addElement(String e) {
Node newNode = new Node();
if (first.data == null) {
first.data = e;
System.out.println("Success! " + e + " has been
added!");
} else if (first.data.compareTo(e) == 0) {
System.out.println("The element already exists in the
list");
} else {
while (first.next != null) {
if (first.next.data.compareTo(e) != 0) {
first.next.data = e;
} else {
first.next = first.next.next;
}
}
}
}
public static void main(String[] args) {
SortedLinkedList list = new SortedLinkedList();
String e1 = new String("albert");
String e2 = new String("david");
String e3 = new String("george");
String e4 = new String("jannick");
String e5 = new String("michael");
// ----------------SINGLE LIST--------------------------
list.addElement(e1);
list.addElement(e2);
list.addElement(e3);
list.addElement(e4);
list.addElement(e5);
System.out.println("Should print elements after this:");
list.udskrivElements();
}
}
Expected result: The five names printed in a list
Actual result: The first name printed
Given this Node class:
private class Node {
public String data;
public Node next;
}
and a class-level field of private Node first; that is initially null to signal an empty list,
the addElement could be like this:
public void addElement(String text) {
if (text == null) return; // don't store null values
Node extra = new Node();
extra.data = text;
if (first == null) {
// no list yet, so create first element
first = extra;
} else {
Node prev = null; // the "previous" node
Node curr = first; // the "current" node
while (curr != null && curr.data.compareTo(text) < 0) {
prev = curr;
curr = curr.next;
}
if (curr == null) {
// went past end of list, so append
prev.next = extra;
} else if (curr.data.compareTo(text) == 0) {
System.out.println("Already have a " + text);
} else {
// between prev and curr, or before the start
extra.next = curr;
if (prev != null) {
prev.next = extra;
} else {
// append before start, so 'first' changes
first = extra;
}
}
}
}
By the way, also try and add the names in an unsorted order to check that the list sorts them (I found a bug in my code when I tried that).

i can't print the linkedlist elements in reverse order using recursion

I am a beginner in java .I am implementing recursion in linked lists to print the elements in reverse order but i think that there is a semantic error in my code , check my code(especially that reverse method) thanks in an advance.
output:78 30 52 send after which item count from head u need to insert
package practice;
public class Linkedlist {
Node head;
public Linkedlist() {
head = null;
}
public void insert(int data) {
Node obj1 = new Node(data);
obj1.next = head;
head = obj1;
}
public void append(int data) {
Node newn = new Node(data);
if (head == null) {
newn.next = null;
head = newn;
return;
}
Node n = head;
while (n.next != null) {
n = n.next;
}
newn.next = null;
n.next = newn;
}
void delete(int data) {
if (head == null) {
return;
} else if (head.data == data) {
head = head.next;
return;
}
Node curr = head;
while (curr.next != null) {
if (curr.next.data == data) {
curr.next = curr.next.next;
}
curr = curr.next;
}
}
void insertAt(int count, int data) {
Node h = head;
if (count == 0) {
this.insert(data);
return;
}
while (h.next != null) {
if (count == 0) {
Node f = new Node(data);
f = h.next;
h = f;
return;
}
count--;
h = h.next;
}
}
public void reverse() {
if (head == null) {
System.out.println("null");
} else {
this.reverseRecursive(head);
}
}
private void reverseRecursive(Node nod) {
if (nod == null) {
return;
}
reverseRecursive(nod.next);
System.out.print(nod.data + " ");
}
class Node {
Node next;
int data;
public Node(int data) {
this.data = data;
}
}
public static void main(String args[]) {
Linkedlist obj = new Linkedlist();
obj.insert(78);
obj.insert(30);
obj.insert(52);
obj.reverse();
System.out.println("send after which item count from head u need to insert");
obj.insertAt(2, 5);
}
}
Looking at your code, I don't think there is anything wrong with your Reverse method. It is actually printing in reverse order. What's throwing you off is probably the way you are inserting the elements. Your insert() method is actually a stack. ( It inserts at top ). So after all insertions, head points to 52 and not 78. So when you print, the reverse list is printed as :
78 30 52
Also, your code needs a bit of formatting and should follow java conventions. Method names start with lower case and class names with uppercase. Good luck :)
In your LinkedList instead of using the insert method, which add an element at the head use the method append which adds the element at the end of the LinkedList and then call the reverse method.

How do I add objects into a linked list?

I have been working on a project where I must implement a java class that implements the use of doubly linked lists. I have the LinkedList class finished with all my methods. I'm just unsure how to actually add node objects into the list. Here is my code so far with test at the bottom. Any help would be appreciated. Thanks
public class LinkedList {
private Node first;
private Node current;
private Node last;
private int currentIndex;
private int numElements;
public LinkedList() {
this.first = null;
this.last = null;
this.numElements = 0;
this.current = null;
this.currentIndex = -1;
}
private class Node {
Node next;
Node previous;
Object data;
}
public boolean hasNext() {
return (current != null && current.next != null);
}
public Object next() {
if (!this.hasNext()) {
throw new IllegalStateException("No next");
}
current = current.next;
return current.data;
}
public boolean hasPrevious() {
return (current != null && current.previous != null);
}
public Object previous() {
if (!this.hasPrevious()) {
throw new IllegalStateException("No previous");
}
current = current.previous;
return current.data;
}
int nextIndex() {
int index = numElements;
if (hasNext()) {
index = this.currentIndex + 1;
}
System.out.println(index + "The current index is " + current);
return index;
}
int previousIndex() {
int index = -1;
if (hasPrevious()) {
index = this.currentIndex - 1;
}
System.out.println(index + "The current index is " + current);
return index;
}
public void set(Object o) {
if (this.current == null) {
throw new IllegalStateException("No node found, cannot set.");
}
current.data = o;
}
public int size() {
return numElements;
}
public void add(Object o) {
Node newNode = new Node();
newNode.data = o;
if (first == null) {
first = newNode;
last = newNode;
newNode.next = null;
} else if (first != null) {
if (current == null) {
newNode.previous = null;
newNode.next = first;
first.previous = newNode;
first = newNode;
} else if (current == last) {
newNode.previous = current;
newNode.next = null;
current.next = newNode;
last = newNode;
} else {
newNode.previous = current;
newNode.next = current.next;
current.next.previous = newNode;
current.next = newNode;
}
}
current = newNode;
numElements++;
currentIndex++;
}
public void remove() {
if (current != null) {
if (current == first && current == last) {
first = null;
last = null;
} else if (current == last) {
current.previous = null;
last = current.previous;
} else if (current == last) {
current.previous.next = null;
last = current.previous;
} else {
current.previous.next = current.next;
current.next.previous = current.previous;
}
current = current.next;
numElements--;
}
}
}
import java.util.Scanner;
public class LinkedListTest {
public static void main(String[] args) {
Scanner keyboard = new Scanner(System.in);
String name;
int index;
LinkedList<Object> listOne = new LinkedList<Object>();
listOne.add(object o);
}
}
The posted class LinkedList looks functional to me.
Make sure that your test code does not confuse this class and java.util.LinkedList, which Java provides for you (It's a part of the existing Collections framework).
For clarity, I would recommend renaming your class to something like MyLinkedList
The following code works and the output is "0","2":
public class MyLinkedListTest {
public static final void main(String[] args) {
MyLinkedList list = new MyLinkedList();
System.out.println("Number of items in the list: " + list.size());
String item1 = "foo";
String item2 = "bar";
list.add(item1);
list.add(item2);
System.out.println("Number of items in the list: " + list.size());
// and so on...
}
}
I'd be surprised if your code compiled, since your class isn't actually generic. Just initialize it as LinkedList listOne = new LinkedList(); (no angle brackets).
As to actually adding elements, you just need an instance of some Object to add; anything will do (assuming your internal code works properly). Try this down at the end there:
Object objectToAdd = "Strings are Objects";
listOne.add(objectToAdd);
objectToAdd = new File("C:\\foo.bar"); // Or use any other Objects!
listOne.add(objectToAdd);
Think of numbered list and look at the relations between the elements
Say I have the list:
A
B
C
What do I have to do to the relations get the list:
A
B
NewNode
C
The new next node of B is NewNode
The new previous node of C is NewNode. So an insert function would want to know the immediate previous node or the immediate next node and then adjust the relationships.
Your LinkedList doesn't have generic types so you can't declare it as
LinkedList<Object> listOne = new LinkedList<Object>();
but rather as
LinkedList listOne = new LinkedList();
And now to add elements just use your add method
listOne.add("something");
listOne.add(1);//int will be autoboxed to Integer objects
Also if you want to add data from keyboard you can use something like
String line="";
do{
System.out.println("type what you want to add to list:");
line = keyboard.nextLine();
listOne.add(line);
}while(!line.equals("exit"));
The line
LinkedList<Object> listOne = new LinkedList<Object>();
won't compile unless you change your class declaration to
class LinkedList<T>
or alternately you can just write
LinkedList listOne = new LinkedLis();
After that you should be able to add objects to your list. However, you'll need to create an Object to add to it, listOne.add(object o); won't do--at the very least you'll have to write listOne.add(new Object()). (Your code does not instantiate an Object, there is no Object that you already have called o, and besides, object o does not mean anything in Java and would not compile.
As people have mentioned your list is not generic. However as they advise you to get rid of the parameter, you can also just add <Object> or <E> to your linked list implementation and leave your initialization of the list as it is.
So in your linked list class you should do something like:
public class LinkedList<E>
This will make sure when you're using LinkedList<Object> listOne = new LinkedList<Object>();, E will be covnerted to Object
Let's improve your test a little bit so that it becomes apparent where your problems are (if any) I commented out the call to the current() method since you have not included one. (I would leave this alone as it may confuse you.) The general idea would be to add items to the linked list and walk forward and backward through it checking the items with each step.
public class LinkedListTest {
public static void main(String[] args) {
Scanner keyboard = new Scanner(System.in);
String name;
int index;
LinkedList listOne = new LinkedList();
//Initially we should be empty so we are positioned
// at both the beginning and end of the list
assert listOne.size() == 0 :"List should be empty";
assert listOne.hasPrevious()==false: "Should be at the beginning of the list";
assert listOne.hasNext()==false : "Should be at the end of the list";
Object firstNode = "I am the first node";
listOne.add(firstNode); //we've added something
//I left this commented out since you don't have a current() method.
// assert firstNode == listOne.current() : "Our current item should be what we just added";
assert listOne.hasPrevious()==false : "Should not have moved forward in our list yet";
assert listOne.hasNext()==true : "should have an item after our current";
assert listOne.size() == 1 : "Should only have one item in the list";
Object secondNode = "I am the second node";
listOne.add(secondNode);
assert listOne.size() == 2 : "Should only have two items in the list";
assert firstNode == listOne.next() : "1st call to next should return the 1st node";
assert listOne.hasPrevious()==true : "We should be positioned after the 1st node";
assert listOne.hasNext()==true : "We should be positioned before the 2nd node";
}
}

java combine two linkedlist

I have a question for combining two linkedlist. Basically, I want to append one linkedlist to the other linkedlist.
Here is my solution. Is there a more efficient way to do it without looping the first linkedlist? Any suggestion would be appreciated.
static Node connect(LinkedList list1, LinkedList list2) {
Node original = list1.first;
Node previous = null;
Node current = list1.first;
while (current != null) {
previous = current;
current = current.next;
}
previous.next = list2.first;
return original;
}
Use list1.addAll(list2) to append list2 at the end of list1.
For linked lists, linkedList.addAll(otherlist) seems to be a very poor choice.
the java api version of linkedList.addAll begins:
public boolean addAll(int index, Collection<? extends E> c) {
checkPositionIndex(index);
Object[] a = c.toArray();
so even when you have 2 linked lists, the second one gets converted to an array, then re-constituted into individual elements. This is worse than just merging 2 arrays.
I guess this is your own linked list implementation? With only a pointer to next element, the only way to append at the end is to walk all the elements of the first list.
However, you could store a pointer to the last element to make this operation run in constant time (just remember to update the last element of the new list to be the last element of the added list).
The best way is to append the second list to the first list.
1. Create a Node Class.
2. Create New LinkedList Class.
public class LinkedList<T> {
public Node<T> head = null;
public LinkedList() {}
public void addNode(T data){
if(head == null) {
head = new Node<T>(data);
} else {
Node<T> curr = head;
while(curr.getNext() != null) {
curr = curr.getNext();
}
curr.setNext(new Node<T>(data));
}
}
public void appendList(LinkedList<T> linkedList) {
if(linkedList.head == null) {
return;
} else {
Node<T> curr = linkedList.head;
while(curr != null) {
addNode((T) curr.getData());
curr = curr.getNext();
}
}
}
}
3. In the Main function or whereever you want this append to happen, do it like this.
LinkedList<Integer> n = new LinkedListNode().new LinkedList<Integer>();
n.addNode(23);
n.addNode(41);
LinkedList<Integer> n1 = new LinkedListNode().new LinkedList<Integer>();
n1.addNode(50);
n1.addNode(34);
n.appendList(n1);
I like doing this way so that there isn't any need for you to pass both these and loop again in the first LinkedList.
Hope that helps
My Total Code:
NOTE: WITHOUT USING JAVA API
class Node {
Node next;
int data;
Node(int d){
data = d;
next = null;
}
}
public class OddEvenList {
Node head;
public void push(int new_data){
Node new_node = new Node(new_data);
new_node.next = head;
head = new_node;
}
Node reverse(Node head){
Node prev = null;
Node next = null;
Node curr = head;
while(curr != null){
next = curr.next;
curr.next = prev;
prev = curr;
curr = next;
}
head = prev;
return head;
}
Node merge(Node head1, Node head2){
Node curr_odd = head1;
Node curr_even = head2;
Node prev = null;
while(curr_odd != null){
prev = curr_odd;
curr_odd = curr_odd.next;
}
prev.next = curr_even;
return head1;
}
public void print(Node head){
Node tnode = head;
while(tnode != null){
System.out.print(tnode.data + " -> ");
tnode = tnode.next;
}
System.out.println("Null");
}
public static void main(String[] args) {
// TODO Auto-generated method stub
OddEvenList odd = new OddEvenList();
OddEvenList even = new OddEvenList();
OddEvenList merge = new OddEvenList();
odd.push(1);
odd.push(3);
odd.push(5);
odd.push(7);
odd.push(9);
System.out.println("Odd List: ");
odd.print(odd.head);
System.out.println("Even List: ");
even.push(0);
even.push(2);
even.push(4);
even.push(6);
even.push(8);
even.print(even.head);
System.out.println("After Revrse: --------------------");
Node node_odd =odd.reverse(odd.head);
Node node_even = even.reverse(even.head);
System.out.println("Odd List: ");
odd.print(node_odd);
System.out.println("Even List: ");
even.print(node_even);
System.out.println("Meged: --------------");
Node merged = merge.merge(node_odd, node_even);
merge.print(merged);
}
}

Categories