Java Splitting integer Linked List - java

I need to write a method that starts with a single linked list of integers and a special value called the splitting value. The elements of the list are in no particular order. The method divides the nodes into two linked lists: one containing all the nodes that contain an element less than the splitting value and one that contains all the other nodes. If the original linked list had any repeated integers (i.e., any two or more nodes with the same element in them), then the new linked list that has this element should have the same number of nodes that repeat this element. The method returns two head references - one for each of the linked lists that were created.
I have been spent countless hours trying to get this right and think this is the closest but I have an error while compiling that my copyTail* IntNodes may not be initialized. I also may be completely wrong with my code....
Any help pointing in me in the right direction??
public static IntNode[ ] listSplitLessGreater(IntNode source, int splitter)
{
IntNode copyHeadLess;
IntNode copyTailLess;
IntNode copyHeadGreater;
IntNode copyTailGreater;
IntNode[ ] answer = new IntNode[2];
boolean less = true;
boolean greater = true;
// Handle the special case of the empty list.
if (source == null)
return answer; // The answer has two null references .
//Split list into two lists less and greater/equal than splitter.
while (source.link != null)
{
if (splitter < source.data)
{
if (less)
{
copyHeadLess = new IntNode(source.data, null);
copyTailLess = copyHeadLess;
less=false;
}
else
{
source = source.link;
copyTailLess.addNodeAfter(source.data);
copyTailLess = copyTailLess.link;
}
}
else
{
if (greater)
{
copyHeadGreater = new IntNode(source.data, null);
copyTailGreater = copyHeadGreater;
greater=false;
}
else
{
source = source.link;
copyTailGreater.addNodeAfter(source.data);
copyTailGreater = copyTailGreater.link;
}
}
}
//Return Head References
answer[0] = copyHeadLess;
answer[1] = copyHeadGreater;
return answer;
}

I think you're making it more complicated than it needs to be, by modelling a list just with a single class (IntNode). If you model it as "the list" and "a node in the list" then it's easy to have an empty list. You also don't need to keep track of both the head and the tail - the list can do that. At that point, it's very simple:
Create two empty lists, one for "lower" and one for "not lower"
Iterate over the original list:
Work out which list to add the element to
Add the element
Return both lists (e.g. using an array as you have done)
Note that even without that, you can make your code simpler by just using null to mean "I haven't got this list yet". At the moment your code won't compile, as copyHeadLess etc aren't definitely assigned when they're used. You know that you won't try to use them until they've been assigned, but the compiler doesn't. I'd still recommend the remodelling approach though :)

If source isn't null, but source.link is null (list is only composed of one element) then you never assign to your copyHeadLess, etc, variables. Try initializing them to null or whatever the default is:
IntNode copyHeadLess = null;
IntNode copyTailLess = null;
IntNode copyHeadGreater = null;
IntNode copyTailGreater = null;
IntNode[ ] answer = new IntNode[2];
boolean less = true;
boolean greater = true;
// Handle the special case of the empty list.
if (source == null)
return answer; // The answer has two null references .
//Split list into two lists less and greater/equal than splitter.
while (source.link != null)
{
// what about case where source isn't null but source.link is null?
}
//Return Head References
answer[0] = copyHeadLess; // this may have never been assigned in your original code
answer[1] = copyHeadGreater; // this may have never been assigned in your original code
return answer;
}

Related

Delete first occurance Doubly Linked List Java

Could someone tell me what's missing in my code. I am trying to remove the first occurrence of a given node value.
It fails very few test cases, but I am not sure what I am missing. Here is my code :
public boolean remove(E obj) {
if (obj == null)
throw new IllegalArgumentException("Violation of precondition : remove(E obj)");
DoubleListNode<E> current = head;
for (int i = 0; i < size; i ++) {
if (current.getData().equals(obj)) {
E result = remove(i);
return true;
}
current = current.getNext();
}
size --;
return false;
}
That recursive call to remove() inside the if block looks wrong.
You are already inside the list, you identified the first matching object. So now your code has to really remove that matching object. Removing would mean to update both links accordingly.
Do these things on paper! Draw a double linked list with nodes and the links between them. Then ask yourself what removing a node that has one or two links coming in (and potentially going out) actually means. You will have to change the links from the previous node and the one following the node that is to removed!

Remove All Occurrences of a Given Value from a Doubly Linked List

Alright, so cut a long story short, what I'm trying to do here is remove all instances of value e from a doubly linked list. As far as I know, my logic is at least mostly right, but for some off reason it isn't actually removing any of the nodes in my test cases.
public boolean removeAll(int e) {
DIntNode dummy = head,next = null;
if (head == null)
return false;
while (dummy != null) {
if (dummy.getData() == e) {
next = dummy.getNext();
dummy.getNext().setPrev(null);
dummy = next;
return true;
}
else
dummy = dummy.getNext();
}
return false;
}
This is what I currently have for my code of the metho. My logic here was to use a dummy DIntNode that starts at the head and a "next" node to help me shrink the list, so to speak. In other words, if the list was something like "1<-> 1 <-> 2 <-> 3", the function would change it to "2<->3", in theory. The reason this is a boolean function is because I'm required to return true if the given value is removed form the list.
Is there just another step in the logic that I'm missing, or is the methodology itself just unreliable? I'm very unsure at this point, so any and all help would be greatly appreciated.
You set
dummy.getNext().setPrev(null);
But previous node also have reference to next node you try to remove. You should set this reference to next active value.
That because when you want to get all linked list previous value still know about node you remove, because of next node reference
You can try with the following code:
if (dummy.getData() == e) {
DIntNode temp = dummy.getPrevious();
temp.next = dummy.getNext();
temp = dummy.getNext();
temp.previous = dummy.getPrevious();
return true;
}
This used the previous reference. So the previous node will now have reference to the next node of your dummy node (node to be deleted). And similarly, the next node of dummy node will have reference of previous node of your dummy node. So, the dummy node will loose its connection/link from its doubly link list and that's what we want!
Please try.
Two issues with the code:
When relinking a doubly linked list, where removing B from A - B - C, you need to set the next node for A to be C as well as the previous node for C to be A. With trying to keep you method names:
A.setNext(current.getNext());
C.setNext(current.getPrev());
With your code, if you find an occurrence, you return, which means that no other instances will be removed since you jump out of that method. You will probably need a new boolean removed variable, that is set to false, return true changed to removed = true and return false changed to return removed.
The method exits after the first encounter of 'e'.
If you want to remove all instances of 'e', then you should have something like this:
boolean listChanged = false;
while (dummy != null) {
if (dummy.getData() == e) {
// update list
...
listChanged = true;
}
...
}
return listChanged;
Also, you should not write your code like this:
dummy.getNext().setPrev(...); // throws NPE if next is null

How does ListNodes work in java implementation

I was reading about nodes in java .. I found this example .. I just can not understand how the ListNode works in java .. I did read about it but I still can not understand it .. Here is the code :
public class SingleLinkedList<E> {
private ListNode<E> first;
/ ** Creates an empty list. * /
public SingleLinkedList() {
first = null;
}
/ ** Returns a list of the elements that match e.
otherwise returned an empty list. * /
public SingleLinkedList<E> allMatches(E e) {
SingleLinkedList<E> res = new SingleLinkedList<E>();
ListNode<E> n = first; // why we create a new node and put it equal to first ?
while (n != null) {
if (n.element.equals(e)) {
ListNode<E> tmp = new ListNode<E>(n.element);
tmp.next = res.first; // what is happening here ?
res.first = tmp; // why we do this step?
}
n = n.next;
}
return res;
}
private static class ListNode<E> {
private E element;
private ListNode<E> next;
/* Creates a listnode which contains e. */
private ListNode(E e) {
element = e;
next = null;
}
}
}
I do not understand the allMatches method ... I put some comments next to each line I did not understand it ...
First question: ListNode<E> n = first; // why we create a new node and put it equal to first ?
Second question: tmp.next = res.first; // what is happening here ?
Third question : res.first = tmp; // why we do this step?
Fourth question :if (n.element.equals(e)) { // can we use == instead of equals in this case?
Please can you answer my questions? thanks
First question: ListNode n = first; // why we create a new node and put it equal to first ?
No new node is created here. A reference is created and it refers to first. New Node is created only when new operator is used. It is assigned with first because we are going to scan through the linked list one by one. Just having the reference to first node is sufficient because first contains reference to the second if it exists.
Second question: tmp.next = res.first; // what is happening here ?
the method allMatches(e) returns a linked list of all nodes which has element value equal to e.element. Whenever there is a match, create a new node. This new node points to the current first element. This is half complete. Read the next question answer and then try to understand.
Third question : res.first = tmp; // why we do this step?
Here res.first is updated with the newly created node. Why? Because we made our new node to point to the current first element. As this new element precedes current first element, we have to update the first element to point to newly created node.
Fourth question :if (n.element.equals(e)) { // can we use == instead of equals in this case?
Nope. Because == works only if both are same object. Here there might be chances that objects are different but there contents are equal. It really depends on how it is being used in the application. In general, the answer is NO.
I think the reason why the the new node n is pointed at first is because you're going to create a new separate linked list called res that is a new linked list of just the results of the search and you want it pointed at the first node in the linked list you will examine namely the list that calls the method.
The reason why tmp.next = res.first is because we are going to insert tmp as the new first element in res and we will attach the old res on after it. Does that make sense? I think drawing a picture of what is going on will help clear up what is happening.

Investigate a queue with linked lists in java

.. I have to use a piece of code in java but I don't understand some parts of it.
The code uses methods (.isEmpty() etc. ) from a simple Queue i made in another document.
It is suppposed to investigate an array (which has linked lists in each address) and do some sort of processing with its values.
The problem is that i dont know what marked[s] = true; ,marked[t.v] = true; and parent[t.v] = k; are and how do they work as variables (?)
void BFS(int s)
{
Queue<Integer> Q = new Queue<Integer>();
marked[s] = true;
Q.put(s);
while (!Q.isEmpty())
{
k = Q.get();
for (Node t = adj[k]; t != null; t = t.next)
if (!marked[t.v]) {
marked[t.v] = true;
parent[t.v] = k;
Q.put(t.v);
}
}
}
}
edit: I wrote matrix instead of array, sorry.
marked[] parent and adj are all arrays.
t as you can see from the code, is a Node object. That node object will have a member variable called v. t.v therefore fetches the value of the variable v in the Node object t.
marked[t.v] finds the element in the array with index equal to t.v. e.g. if t.v is equal to 0, then you are fetching marked[0] which is the first element in the marked array.

Confused about linked list deletion

I am trying to implement the deletion function in
public static boolean delete(Object d, ListElement head){
ListElement p=find(d,head);
if(p.data==null){return false;}
else {
System.out.println("Delete Successfully!");
if(head.data==d){head=head.next;}
else{
while(head.next.data!=d){
head=head.next;
}
head.next=head.next.next;}
return true;}
}
This function basically check if the element d is in the list,
-if not->return false;
-else check whether the element is the first element of the list, if true, change the head to its next,
-else traverse to the list element in front of it.
The problem is case the element to delete is the first element, such as boolean s=ListElement.delete(1,d); I cannot use "head=head.next;" to assign new value to head. But java is passed by reference, why cannot I change that?
//actually I found my question is whether we can change the reference passed to the function inside the function
like:
void fun(dog a){
a=new dog("Po");
}
main()
{dog b=new dog("Jo");fun(b);}
//so will b be changed?
The reference to the first list element is either held by the list object itself or by an "invisible" root element (in case of single linked list).
So you either have to pass the entire list to the method or, if you have that invisible root, pass the root as head.
public static boolean delete(Object d, MyLinkedList<ListElement> list) {
ListElement head = list.getHead();
if (head.data.equals(d)) { // <- ALWAYS use equals, never == to compare objects!!
list.setHead(head.next);
} else {
ListElement element = head.next;
// ... the rest is similiar to your algorithm
}
}
The Java Pass by Reference idea means, that when you call a method, and give some object as an argument, you'll get a new reference pointing to the same object.
Altering values, will change the object, in turn also affecting other references. But if you give a new value to the parameter, only that will be changed, to point to some different object. (It's worth mentioning that there are languages that do allow changing the argument, to change the first passed parameter.)
void delete(visit_ptr_node_type this_is_the_node)
{
visit_ptr_node_type one_back;
if(anchor == NULL)
printf("\n The list is empty");
else
{
if(this_is_the_node==anchor)
anchor=anchor->next_ptr;
else
{
one_back=anchor;
while(one_back->next_ptr != this_is_the_node)
one_back=one_back->next_ptr;
one_back->next_ptr = (this_is_the_node) ->next_ptr;
}
free(this_is_the_node);
}
}

Categories