Linked List Manual Sort - java

I'm having a really difficult time solving this problem. I have spent hours on it and can't figure it out.
I have a linked list that I am trying to manually sort. My nodes are called CNodes. There is a start CNode, a tail CNode and a newNext CNode.
Each Node contains a contact. The contact has a firstname that I am trying to sort the list by.
I know there are more automatic ways to do this, but I need to demonstrate that I understand how to sort (which clearly I do not at this point).
I am trying to do this by iterating over each node and comparing it to start, then changing the start entity if it qualifies.
This code is not working...I've been working on it for two days and am really stuck.
Any specific suggestions would be really appreciated.
CNode nextNode=start;
while(nextNode.getNext()!=null) {
CNode newNext;
tail=nextNode;
while(tail!=null) {
if(start.getContact().getStrFirstName().compareTo(tail.getContact().getStrFirstName()) > 0) {
//We put the starting node in a temp node
newNext=start;
newNext.setNext(tail.getNext());
//We set our current node to the start
start=tail;
start.setNext(newNext);
//Set the next node of start to the original next one of the one we
//just removed from the chain
//Set current marker to the new first nodes' next entity
tail=start.getNext();
//Set the next node for the marker to the one we just removed
} else {
tail=tail.getNext();
}
}
nextNode=nextNode.getNext();
}

The best thing you can do is start with an array, and get the sorting concept down. You also need to figure out what type of sort you are going to do, you're currently trying to do a bubble sort. There is also a merge sort, quick sort, and others. Once you pick the type of sort you want, you can then do it on an array, then move to node.
Here are some sorts:
https://github.com/BlaineOmega/MergeSort Bubble sort:
http://en.wikipedia.org/wiki/Bubble_sort Quick sort:
http://en.wikipedia.org/wiki/Quicksort

So what you're doing is a bubble sort. For a visual representation of what the is, look at this (from Wikipedia): http://upload.wikimedia.org/wikipedia/commons/c/c8/Bubble-sort-example-300px.gif
So in the while loop, when two nodes need to be switched, we're going to store the 'next' (current) node into a temp, put the tail in the next node, and put the temp into the tail, like a triangle.
temp
/ ^
/ \
V \
tail -- next
I attempted to rewrite your code, but was confused as to if start is you're root node, and if not, what is you're root node. If it is, it should be only used once, and that is declaring you're tail node.
Good luck, hope I helped,
Stefano

Related

Find the pairings such that the sum of the weights is minimized?

When solving the Chinese postman problem (route inspection problem), how can we find the pairings (between odd vertices) such that the sum of the weights is minimized?
This is the most crucial step in the algorithm that successfully solves the Chinese Postman Problem for a non-Eulerian Graph. Though it is easy to implement on paper, but I am facing difficulty in implementing in Java.
I was thinking about ways to find all possible pairs but if one runs the first loop over all the odd vertices and the next loop for all the other possible pairs. This will only give one pair, to find all other pairs you would need another two loops and so on. This is rather strange as one will be 'looping over loops' in a crude sense. Is there a better way to resolve this problem.
I have read about the Edmonds-Jonhson algorithm, but I don't understand the motivation behind constructing a bipartite graph. And I have also read Chinese Postman Problem: finding best connections between odd-degree nodes, but the author does not explain how to implement a brute-force algorithm.
Also the following question: How should I generate the partitions / pairs for the Chinese Postman problem? has been asked previously by a user of Stack overflow., but a reply to the post gives a python implementation of the code. I am not familiar with python and I would request any community member to rewrite the code in Java or if possible explain the algorithm.
Thank You.
Economical recursion
These tuples normally are called edges, aren't they?
You need a recursion.
0. Create main stack of edge lists.
1. take all edges into a current edge list. Null the found edge stack.
2. take a next current edge for the current edge list and add it in the found edge stack.
3. Create the next edge list from the current edge list. push the current edge list into the main stack. Make next edge list current.
4. Clean current edge list from all adjacent to current edge and from current edge.
5. If the current edge list is not empty, loop to 2.
6. Remember the current state of found edge stack - it is the next result set of edges that you need.
7. Pop the the found edge stack into current edge. Pop the main stack into current edge list. If stacks are empty, return. Repeat until current edge has a next edge after it.
8. loop to 2.
As a result, you have all possible sets of edges and you never need to check "if I had seen the same set in the different order?"
It's actually fairly simple when you wrap your head around it. I'm just sharing some code here in the hope it will help the next person!
The function below returns all the valid odd vertex combinations that one then needs to check for the shortest one.
private static ObjectArrayList<ObjectArrayList<IntArrayList>> getOddVertexCombinations(IntArrayList oddVertices,
ObjectArrayList<IntArrayList> buffer){
ObjectArrayList<ObjectArrayList<IntArrayList>> toReturn = new ObjectArrayList<>();
if (oddVertices.isEmpty()) {
toReturn.add(buffer.clone());
} else {
int first = oddVertices.removeInt(0);
for (int c = 0; c < oddVertices.size(); c++) {
int second = oddVertices.removeInt(c);
buffer.add(new IntArrayList(new int[]{first, second}));
toReturn.addAll(getOddVertexCombinations(oddVertices, buffer));
buffer.pop();
oddVertices.add(c, second);
}
oddVertices.add(0, first);
}
return toReturn;
}

How to determine the direction of a Linked List

I have to make a linked list that adds to itself to the left so I'm thinking it's something like this where the boxes are nodes and the arrow is the link:
tail [] <- [] <- [] <- ... [] head
But how do you determine the direction of the linked list when you are adding the second node?
How do you know which side it's going to be placed on?
2nd? 1st 2nd?
[] [] []
For example this code: head = new IntNode(5,head)
would add to the right if the linked list is like this:
head tail
[] -> [] -> [] -> []
But that's only when adding to an already made list with that format, so which side will it start from when creating a new linked list?
Well, there is no left and right with linked lists.
That direction is just used for convenient graphical representation since we can easily picture it. You can technically draw a linked list sideways, up to down, down to up, left to right, doesn't really matter.
All linked lists have is a single direction from head to tail. Or in case of doubly linked lists, a bi-direction from head to tail and from tail to head.
I guess you could technically make a doubly linked list where all "left" or "prev" pointers are null to make it seem like it goes right. Or make all of its "right" or "next" pointers null and make it seem like it goes left. In either case, such direction has no actual meaning.
In memory, linked list node's value of Node.next just contains a memory address of the next node. That memory location doesn't have to physically be right next to the node. Technically, linked list pointers can zig-zag all over memory, connecting blocks wherever the OS and underlying system decided to allocate memory for them. There is no "natural" order like we are used to in real life, just sequence of pointers from head to tail
For example, these two lists are equivalent as far as the computer is concerned. I just drew them in different directions :)

Find the 3rd last element in the Singly Link List - Algorithm

I am thinking on the Algo to find the 3rd last element in the Singly Link List and I come up with one by myself(space in-efficient)
Put the Link List in a ArrayList using a loop with O(n)time complexity [a lot of space complexity]
then find the size of Arraylist and retrieve the element[required element] at (size-2) index location
Please guide me if my algo make sense
FYI
Other I searched is :
Put two pointers and keep 1st pointer on 1st element and 2nd pointer on 3rd element and move them parallel
When the second pointer reaches the end of LinkList, retrieve the node[required node] which is pointed by the 1st pointer
Use two pointers: pointer-1 and pointer-2
make pointer-1 points to third node in single linked list.
pointer-1 = node1->next->next; // point to 3rd nd
node1-->node2-->node3-->node4---> ...... -->node-last
^
|
pointer-1
Now set pointer-2 points to first-node
pointer-2 = node1; // point to 1st nd
node1-->node2-->node3-->node4---> ...... -->node-last
^ ^
| |
pointer-2 pointer-1
Now, travel in linked list in a loop till pointer-1 points to last node, in loop also update pointer-2 (every time to next node of itself )
while (pointer-1->next!=NULL){// points to last node
pointer-1 = pointer-1 -> next;
pointer-2 = pointer-2 -> next;
}
When loop ends pointer-1 points to last-node, pointer-2 points to third last
node1-->node2-->........ ->node-l3-->node-l2-->node-last
^ ^
| |
pointer-2 pointer-1
It works in O(n) times, where n is number of nodes in linked-list.
Since the linked list is singly linked, you need to traverse it from the beginning to end to know what the 3rd to last element is, os O(n) time is unavoidable (unless you maintain a pointer to the 3rd to last element in your linked list).
Your 2 pointers idea, will use constant space. This is probably the better option, since creating an ArrayList will have more overhead, and use more space.
Get two pointers. pA, pB
Move pA to 3 elements advance and pB to the head:
1->2->3->4-> .... ->99->100
| |
pB pA
After this, move both pointers in the same loop till pA reaches to the last element.
At that point pB will be pointing to the last 3rd element
1->2->3->4-> .... ->98->99->100
| |
pB pA
Edited:
traversal will be one:
while(pA->next!=null){
pA = pA->next;
pB = pB->next;
}
Here pB will be 3rd last
An alternative view to solve this even though it is O(n)
Create an empty array(n), start a pointer into this array at 0, and start from the beginning of the linked list as well. Every time you visit a node store it in the current index of the array and advance the array pointer. Keep filling the nodes in the array, and when you reach the end of the array please start from the beginning again so as to overwrite.
Now once you end the final end of the list the pointer nth elemtn from end :)
In practice, a Java LinkedList keeps track of its size, so you could just go to 'list.get(list.size()-2)', but with a constructed linked list, I'd do the following:
Keep an array of 3 values. As you traverse the list, add the update the value at array[i%3]. When there are no more values, return the value at array[(i-2)%3].
The first thing I'd do is ask you to reconsider your use of a singly linked list. Why not just store your data in an ArrayList? It does everything you seem to want, and it's a builtin so it's relatively efficient compared to what most people would write.
If you were bound and determined to use a linked list, I'd suggest keeping a direct pointer to the 3rd last element (tle). Insertions are easy - if they come before the tle, do nothing; if after, advance the tle pointer to the tle's next. Removals are more of a hassle, but probably not most of the time. If the removal occurs before the tle, it's still the tle. The annoying situation is if the element to be removed is the tle or later, in which case you get to iterate through from the beginning until the next() reference of the current node is the tle. The current node will become the new tle, and you can then proceed with the removal. Since there are only three nodes which invoke this level of work, you'll probably do all right most of the time if the list is sizable.
A final option, if removals from the end are a frequent occurrence, is to maintain your list from back to front. Then the tle becomes the third from the front for maintenance purposes.
//We take here two pointers pNode and qNode both initial points to head
//pNode traverse till end of list and the qNode will only traverse when difference
// between the count and position is grater than 0 and pthNode increments once
// in each loop
static ListNode nthNode(int pos){
ListNode pNode=head;
ListNode qNode=head;
int count =0;
while(qNode!=null){
count++;
if(count - pos > 0)
pNode=pNode.next;
qNode=qNode.next;
}
return pNode;
}

Traverse a graph, but only n levels deep

I have a graph which is essentially an ArrayList of Nodes, each of which stores their neighbors.
public class Node {
ArrayList<Node> neighbors;
String data;
public Node() {
data = null;
neighbors = new ArrayList<Node>();
}
}
I print out every path in this graph, but only do it n-levels deep. How should I go about coding this?
Or, if I should store this differently, feel free to let me know. But more importantly I want to know how to print out every path n-levels deep.
Just do a depth-limited traversal of the graph. This is just like depth-first search, except in the recursive step, you also add a variable called depth which is incremented every time you go down a depth. Then simply stop recursing once you've hit the desired depth.
Add an extra variable called visited in every node.
Do a breadth first search using a Queue and use the visited to prevent from forming a loop.
Do it for length n.

Converting a Breadth First Search to Depth first Search in Java

its been a long time since I touched Java so this may seem like an odd question. Currently have this Breadth First Search code I found here on StackOverflow, I have it modified on my end but I'll post the original code here.
public List<Node> getDirections(Node start, Node finish){
List<Node> directions = new LinkedList<Node>();
Queue<Node> q = new LinkedList<Node>();
Node current = start;
q.add(current);
while(!q.isEmpty()){
current = q.remove();
directions.add(current);
if (current.equals(finish)){
break;
}else{
for(Node node : current.getOutNodes()){
if(!q.contains(node)){
q.add(node);
}
}
}
}
if (!current.equals(finish)){
System.out.println("can't reach destination");
}
return directions;
}
I'm aware of other depth first search algorithms out there, but I was also told its possible to convert breadth first search to depth first search easily, and I would understand it better if it was done to this code instead of 2 totally different codes.
How can I change this to be a Depth First Search?
The main difference between Depth first and Breadth fist is the order in which you explore the nodes in your "frontier" (the list of nodes you're yet to explore).
If you add the outgoing nodes from your current node to the end of that list, you'll be testing every possibility in a "level" (for simplification purposes, imagine this as a tree), before going to the next level, so you have a Breadth first search.
If, on the other hand, you explore the newly added nodes (the outgoing nodes from your current position), before the nodes you've added earlier (that belong in the "upper" levels of the tree), then you'll be exploring the depth of the tree first.
In terms of data structures, you want a Stack instead of a Queue, but I think the explanation may come in handy.
You'd have to replace q.add(node) (which adds at the end of a list) with q.add(0, node) (to add at the beginning). Basically, use a stack instead of a queue.
Obviously you'd have to use the List interface instead of the Queue one to access the LinkedList.
Deque<Node> q = new LinkedList<Node>();
and use pop and push instead of remove and add
basically remove from the same side you added (normal remove and add are LIFO queue base ops) depth first uses a FIFO stack
and the other search algorithms are essentially the same but use different types of queues (eager search uses a easiest next step for example)
Replace Queue and LinkedList with Stack, add with push, and remove with pop

Categories

Resources