Singly Linked List merge list - java

I have a method that takes in two generic type Singly Link lists the purpose of the method is to merge the two Singly Link lists into a single new list. But the new list cannot have duplicate values. My code already creates the merged list but it won't remove the duplicate item. There seems to be an issue with the removal part of the code in System.out.println("duplicate:) this part shows that the while loop found a duplicate item but it will not remove. Can some one help me out?
//# param mergeList method combines two Singly Linked lists into one while also removing any duplicate elements. (Incomplete will not remove dupilcates.)
public static <T extends Comparable<T>> SinglyLinkedList<T> mergeLists(SinglyLinkedList<T> list1, SinglyLinkedList<T> list2) {
//new list to merge both parameter lists
SinglyLinkedList<T> fin = new SinglyLinkedList<>();
//node variables pointers
SLLNode temp;
SLLNode l1 = list1.getHead();
SLLNode l2 = list2.getHead();
//while loop to traverse list 1 and add to fin list
while(l1 != null){
temp = l1;
fin.append(temp);
l1 = l1.getNext();
}//close while
//While loop to traverse list 2 and add to fin list
while(l2 != null){
temp = l2;
fin.append(temp);
l2 = l2.getNext();
}//close while
//start of duplicate removal
//create node variables and new no duplicate link list
SLLNode removaltemp = null ,removaltemp2 = null , duplicate = null;
SLLNode pointer= null;
SinglyLinkedList<T> last = new SinglyLinkedList<>();
//Set Nodes
removaltemp = fin.getHead();
pointer = fin.getHead();
last.append(pointer);
//while loop to check head with body
while(removaltemp!= null){
removaltemp2 = removaltemp;
System.out.println("Hello");
//while loop to check body with head
while(removaltemp2.getNext() != null ){
System.out.println("Hi");
//if statement for element removal
if(removaltemp.getData().equals(removaltemp2.getNext().getData())){
System.out.println("duplicate");
duplicate = removaltemp2.getNext();
removaltemp2 = removaltemp2.getNext().getNext();
System.gc();
}// close if
//if not duplicate
else if(removaltemp2 != removaltemp2.getNext()) {
removaltemp2 = removaltemp2.getNext();
}//close else if
}//close nested while loop
//assign next head to loop
pointer= pointer.getNext();
removaltemp = removaltemp.getNext();
}//close while loop
//return statement
return last;
}//close merge method

Related

Implementing an AddAtIndex method in a LinkedList

currently, I am working on implementing an AddAtIndex method and for the most part it seems to be working fine. However, my method is not passing my JUnit test and I can't seem to understand why. Thus, I have chosen to show the code I have done thus far:
**
* Add an element to the list at the specified index
* #param The index where the element should be added
* #param element The element to add
*/
public void add(int index, E element ) //Method should be O(1) time.
{
// TODO: Implement this method
if (index < 0) {
System.out.println("Can't add an element at a negative index.");
}
int i = 0;
LLNode<E> currentNode = head.next;
while ( i < size ) {
if ( i == index ) {
LLNode<E> newNode = new LLNode<E>(element);
LLNode<E> tempNode = new LLNode<E>(currentNode.data);
currentNode.next = tempNode;
currentNode.data = newNode.data;
newNode.prev = currentNode.prev;
newNode.next = tempNode;
tempNode.prev = newNode;
size++;
}
currentNode = currentNode.next;
i++;
}
}
My thought process behind the code is that the method creates a new Node, then it replaces the data at the specified index of the linked list. However, the data at the node it is replacing is stored in a temporary node which is incremented in position to the next node after the new node. I am about 80% confident in my implementation though the code looks a bit sloppy. I have created a driver to demonstrate the implementation. The drivers code is as follows:
public class LinkedListDriver {
public static void main(String[] args) {
// TODO Auto-generated method stub
MyLinkedList<String> nameList = new MyLinkedList<String>();
nameList.add("Hamadi");
nameList.add("Ballo");
nameList.add(1, "Salisu");
nameList.add(2, "Galo");
System.out.println(nameList.toString());
System.out.println(nameList.size());
nameList.set(2, "Abdullahi");
System.out.println(nameList.toString());
nameList.remove(1);
System.out.println(nameList.toString());
MyLinkedList<Integer> list1 = new MyLinkedList<Integer>();
list1.add(65);
list1.add(21);
list1.add(42);
System.out.println(list1.toString());
list1.remove(0);
System.out.println(list1.toString());
}
}
The Output from the driver is as follows:
List: Hamadi, Salisu, Galo, Ballo,
4
Replacing Galo with Abdullahi
List: Hamadi, Salisu, Abdullahi, Ballo,
Removing Salisu from the list
List: Hamadi, Abdullahi, Ballo,
List: 65, 21, 42,
Removing 65 from the list
List: 21, 42,
The unit test fails however with the following error:
It fails at the AssertEquals method:
shortList.add(2, "E");
shortList.add(3, "F");
**assertEquals("AddAtIndex: at position 2 ", "E", shortList.get(2)); //fails here**
assertEquals("AddAtIndex: at position 3 ", "F", shortList.get(3));
assertEquals("AddAtIndex: List size is ", 6, shortList.size());
I would like to know what I'm doing wrong. I have this literally completely figured out, though I know that there is something a bit off about my AddAtindex method. Thanks!
You don't need that tempNode. Just create the newNode and insert it properly between currentNode and its previous node.
You should also consider the possibility of adding an element at the beginning (no previous) or end (no next) of the list.
I used head and tail as sentinel nodes. Created a new node to be added in the list.
public boolean add(E element) {
// create new element
LLNode<E> variable = new LLNode(element);
variable.next = null;
variable.prev = null;
// if element is null, throw exception
if (element == null) {
// return false;
throw new NullPointerException("Element is null");
} else {
// get the value stored in tail.prev in variable temp.
variable.prev = tail.prev;
variable.next = tail;
// now modify the tail node prev and new node next
tail.prev = variable;
// get prev node next link changed
variable.prev.next = variable;
// update size
if (head.next.next != tail) {
size++;
}
return true;
}
}

How can I display which elements were removed from list in custom OrderedLinkedList class?

I am implementing a custom Ordered LinkedList class with a nested Ordered ListNode class. Everything is working fine, but I am trying to expand on it by accessing the elements that are removed.
This is not a requirement, but I am curious how this would work since I can only use the methods I was instructed to create, which are boolean add(), boolean remove(), and clear().
I am also keeping track of each modification, which is incremented with each successful addition, removal, or call to clear(). I can simply create another OrderedLinkedList, and add the removed elements to it, but I feel like I'm adding an unnecessary modification count.
Again, this part is just for fun and not required. I feel this will give me a deeper understanding of creating custom classes.
I'll show the remove and main methods. The remove method signature cannot be changed.
public boolean remove(Comparable obj) {
for(OrderedListNode element = head.next; element != tail; element = element.next) {
if(obj.equals(element.dataItem)) { //if element being removed is at the cursor
OrderedListNode previousNode = element.before;
OrderedListNode nextNode = element.next;
nextNode.before = previousNode; //places next element that's after before to the element after current element [prev -> current -> next]
previousNode.next = nextNode; //places prev of next element to the element before current
element.dataItem = (Comparable)NOT_FOUND; //removed element is now null
modCount++; //another modification
theSize--; //reduce the size by 1
return true; //if remove is successful
}
}
return false; //otherwise, not successful removal
}
Main method:
public static void main(String[] args) {
OrderedLinkedList list = new OrderedLinkedList();
OrderedLinkedList removedList = new OrderedLinkedList();
modCount = 0;
list.add("Dog");
list.add("Bird");
list.add("dog");
list.add("bird");
list.add("Cat");
System.out.println("Before removal of element");
System.out.println(list);
list.remove("Dog");
removedList.add("Dog"); //not what I'm wanting to do
System.out.println("Removed " + removedList);
System.out.println("After removal of element");
System.out.println(list);
System.out.println("Total modifications = " + modCount);
System.out.println();
}
Output:
Before removal of element
Bird, Cat, Dog, bird, dog
Removed Dog //not actually accessing the element originally removed. just printing a new list
After removal of element
Bird, Cat, bird, dog
Total modifications = 7 //unnecessary modification due to additional add
If you just want to store the elements that you have removed without increasing your modification count, you can use ArrayList and put your removed elements into it. This way your modification count will not be impacted.
You can store the removed values by implementing an additional pop method. The return type should be Comparable and when the object to be removed found, store it in a temporary object and return that, instead of returning a boolean true. When the object is not found, simply return null.
If the Comparable object is found which is to be removed, the method will return that object so that you can store it. If not, a null will return so that you can use an if-check for the pop method to get that if remove is successful or not.
Here is a sample method I've just written for you;
Sample Pop Method
public Comparable pop(Comparable obj) {
for (OrderedListNode element = head.next; element != tail; element = element.next) {
Comparable temp = null; // declaration of the temporary object
if (obj.equals(element.dataItem)) { // if element being removed is
// at the cursor
temp = obj; // store obj in temp
OrderedListNode previousNode = element.before;
OrderedListNode nextNode = element.next;
nextNode.before = previousNode; // places next element that's
// after before to the element
// after current element [prev
// -> current -> next]
previousNode.next = nextNode; // places prev of next element to
// the element before current
element.dataItem = (Comparable) NOT_FOUND; // removed element is
// now null
modCount++; // another modification
theSize--; // reduce the size by 1
return temp; // if remove is successful
}
}
return null; // otherwise, not successful removal
}
Test Demo
Your test code should be like this;
public static void main(String[] args) {
OrderedLinkedList list = new OrderedLinkedList();
OrderedLinkedList removedList = new OrderedLinkedList();
modCount = 0;
list.add("Dog");
list.add("Bird");
list.add("dog");
list.add("bird");
list.add("Cat");
System.out.println("Before removal of element");
System.out.println(list);
// list.remove("Dog"); // not needed anymore
// removedList.add("Dog"); //not what I'm wanting to do
// pop returns the removed object
removedList.add(list.pop("Dog"));
System.out.println("Removed " + removedList);
System.out.println("After removal of element");
System.out.println(list);
System.out.println("Total modifications = " + modCount);
System.out.println();
}

Java referencing and modifying linked list

I am a bit new to Java and one thing is currently bothering me a bit regarding referencing.
I have a method that returns void. I passed in a linked list to this method. There is another linked list variable called noDuplicateLL that references to the same linked list. noDuplicateLL skips nodes in the linked list.
code:
public static void removeDuplicate(LinkedListNode a) {
LinkedListNode noDuplicateLL = null;
if (a == null) {
//return null;
} else {
HashMap<Integer, Boolean> duplicateCheck = new HashMap<Integer, Boolean>();
while (a != null) {
// check in hashtable O(1)
if (duplicateCheck.containsKey(a.data)) {
noDuplicateLL.next = a.next;
} else {
noDuplicateLL = a;
duplicateCheck.put(a.data, true);
}
// update
a = a.next;
}
}
}
LinkedListNode a gets iterated through the whole list. LinkedListNode noDuplicateLL stops moving once a reaches null. So once this method is done, both pointers are pointing somewhere else in the list, not the front.
The method below prints on the list from beginning to end.
public static void printLinkedList(LinkedListNode head) {
while (head != null) {
System.out.println(head.data);
head = head.next;
}
}
My main:
LinkedListNode LL = LinkedList.randomLinkedList(nodeVal);
removeDuplicate(LL);
printLinkedList(LL);
How come the output still prints from beginning to end of the linked list when LL is passed into the method as a? Is it because a simply points to the nodes in the linked list while LL maintains the reference to the front of the linked list?
LL --> some head node
// invoke method
// LL's value bound to parameter a
a --> some head node
// method executes
a --> head's next
a --> that next's next
...
a --> null
// method exits
LL still points to the original head node.
Is it because a simply points to the nodes in the linked list while LL
maintains the reference to the front of the linked list?
Yes. Read this as soon as you can.

Non-destructive recursive intersect of two singly linked lists

I want to take two singly linked lists (this function is called from within one) and create a third singly linked list that contains all intersections between the two. So if p=[0,1,2,3] and q=[1,3,7,9] then out=[1,3], while leaving the old lists intact.
As you can see I need to declare "out" in two places. But if I hit the declaration by calling the function again, it naturally wipes what I previously wrote to it. I really can't figure out how to avoid it.
Singly linked lists can be generated with http://docs.oracle.com/javase/7/docs/api/java/util/LinkedList.html . first is my header.
public List intersection(List l) {
if(first.data == l.first.data) {
List lTail = new List(l.first.next);
List tail = new List(first.next);
List out = new List(new Node(first.data, null)); //Bad idea #1
// System.out.println(out);
return tail.intersection(lTail);
} else if (first.data > l.first.data && l.first.next != null) {
List lTail = new List(l.first.next);
return intersection(lTail);
} else if (first.data < l.first.data && first.next != null) {
List tail = new List(first.next);
return tail.intersection(l);
} else { //When both lists are at the end position
List out = new List(new Node(0, null)); // Bad idea #2
return out;
}
}
List<T> p = new LinkedList<T>();
p.add...
...
List<T> q = new LinkedList<T>();
q.add...
...
List<T> intersection = new LinkedList<T>(p);
intersection.retainAll(q);
Now intersection contains only elements, which are in both lists, while lists theirselves remain untouched.

Bubble Sort Doubly Linked List Java

I am trying to create a bubble sort on a doubly linked linked list in Java but am getting Null Pointer Exception errors. I believe it to have an issue with when I call the getPrevious method on the head which of course has a value of null. However, I cannot think how to do the bubble sort without accessing the getPrevious method for the other nodes.
I can implement an if statement to check if its the head or tail of the list first, but I feel like there is a smarter way to do this.
I also have been unable to run a successful build of this, so am not even sure the code will work. If you have a different idea of how to implement this please let me know.
Any suggestions are welcome!
public static void bubbleSort(DoubleLinkedList list) //static method used to sort the linked list using bubble sort
{
int i = 0;
int j = 0;
Node currentNode = list.head;
Node previousNode = currentNode;
Node tempNext = currentNode;
Node tempPrevious = currentNode;
for(i=0; i<list.getSize(); i++)
{
for(j=0; j<list.getSize()-1; i++)
{
if(currentNode.getData() > currentNode.getNext().getData())
{
tempNext = currentNode.getNext().getNext();
tempPrevious = currentNode.getPrevious();
currentNode.getPrevious().setNext(currentNode.getNext());
currentNode.getNext().setNext(currentNode);
currentNode.setPrevious(currentNode.getNext());
currentNode.setNext(tempNext);
}
currentNode = currentNode.getNext();
}
}
}
So you have a double linked list. I assume each element contains some information... say an integer. It must also contain two pointers: one to the previous element and one to the next element.
Assuming this is true, notice that you don't have to modify the pointers because they already point from one element to another. all you have to do is sort the values of the list elements so that the first item in the list has the lowest value, the second has the second lowest value and so on.
You can do it like this:
public static void bubbleSort(DoubleLinkedList list) //static method used to sort the linked list using bubble sort {
int i = 0;
Node currentNode = list.head;
Node auxNode;
int foundChange = 1;
while(foundChange) {
foundChange = 0;
for(i=0; i<list.getSize()-1; i++) {
if (currentNode.getData() > currentNode.getNext().getData()) {
auxNode.setData(currentNode.getData());
currentNode.setData(currentNode.getNext.getData());
currentNode.getNext.setData(auxNode.getData());
foundChange = 1;
}
currentNode = currentNode.getNext();
}
}
If you haven't defined the setData method yet, then do so. It must be similar to getData, but it will set the data of an object to the value it gets as a parameter instead of returning the value of the data in that object.

Categories