Traversing directed graph breadth first with vertexes having longest paths first - jgrapht

Given a directed graph of dependencies, I want to traverse this graph from the root node level by level (that is breadth first) however taking the nodes on each level in a certain order. In my case, the order of nodes on each level must be sorted after their depth taking deepest nodes first.
Simple example:
A -> B
B -> C
A -> C
Starting at node A, I want the travseral to give me order A, B, C (and not A, C, B because B has C under it). No cycles.
Any hints much appreciated. I'm new to the excellent JGraphT library so may have overlooked some simple solution.
One way to solve this problem would be to:
Find all paths from root (A)
Sort the paths according to length (tallest first)
For each path travers the nodes and put node in right place in a list.
The right place is determined by a linear search of list at first position where new node is not found in the list
But maybe there is already some built in algorithm, so I don't have to encode the above? :-)

It sounds like you can simply use a topological sort of your graph. In jgrapht you can accomplish this with the TopologicalOrderIterator

Related

Binary trees and quicksort?

I have a homework assignment that reads as follows (don't flame/worry, I am not asking you to do my homework):
Write a program that sorts a set of numbers by using the Quick Sort method using a binary search
tree. The recommended implementation is to use a recursive algorithm.
What does this mean? Here are my interpretations thus far, and as I explain below, I think both are flawed:
A. Get an array of numbers (integers, or whatever) from the user. Quicksort them with the normal quicksort algorithm on arrays. Then put stuff into a binary search tree, make the middle element of the array the root, et cetera, done.
B. Get numbers from the user, put them directly one by one into the tree, using standard properties of binary search trees. Tree is 'sorted', all is well--done.
Here's why I'm confused. Option 'A' does everything the assignment asks for, except it doesn't really use the binary tree so much as it throws it last minute in the end since it's a homework assignment on binary trees. This makes me think the intended exercise couldn't have been 'A', since the main topic's not quicksort, but binary trees.
But option 'B' isn't much better--it doesn't use quicksort at all! So, I'm confused.
Here are my questions:
if the interpretation is option 'A', just say so, I have no questions, thank you for your time, goodbye.
if the interpretation is option 'B', why is the sorting method used for inserting values in binary trees the same as quicksort? they don't seem inherently similar other than the fact that they both (in the forms I've learned so far) use the recursion divide-and-conquer strategy and divide their input in two.
if the interpretation is something else...what am I supposed to do?
Here's a really cool observation. Suppose you insert a series of values into a binary search tree in some order of your choosing. Some values will end up in the left subtree, and some values will end in the right subtree. Specifically, the values in the left subtree are less than the root, and the values of the right subtree are greater than the root.
Now, imagine that you were quicksorting the same elements, except that you use the value that was in the root of the BST as the pivot. You'd then put a bunch of elements into the left subarray - the ones less than the pivot - and a bunch of elements into the right subarray - the ones greater than the pivot. Notice that the elements in the left subtree and the right subtree of the BST will correspond perfectly to the elements in the left subarray and the right subarray of the first quicksort step!
When you're putting things into a BST, after you've compared the element against the root, you'd then descend into either the left or right subtree and compare against the root there. In quicksort, after you've partitioned the array into a left and right subarray, you'll pick a pivot for the left and partition it, and pick a pivot to the right and partition it. Again, there's a beautiful correspondence here - each subtree in the the overall BST corresponds to doing a pivot step in quicksort using the root of the subtree, then recursively doing the same in the left and right subtrees.
Taking this a step further, we get the following claim:
Every run of quicksort corresponds to a BST, where the root is the initial pivot and each left and right subtree corresponds to the quicksort recursive call in the appropriate subarrays.
This connection is extremely strong: every comparison made in that run of quicksort will be made when inserting the elements into the BST and vice-versa. The comparisons aren't made in the same order, but they're still made nonetheless.
So I suspect that what your instructor is asking you to do is to implement quicksort in a different way: rather than doing manipulations on arrays and pivots, instead just toss everything into a BST in whatever order you'd like, then walk the tree with an inorder traversal to get back the elements in sorted order.
A really cool consequence of this is that you can think of quicksort as essentially a space-optimized implementation of binary tree sort. The partitioning and pivoting steps correspond to building left and right subtrees and no explicit pointers are needed.

How to store adjacent nodes for Dijkstra algorithm?

Most articles about Dijkstra algorithm only focus on which data structure should be used to perform the "relaxing" of nodes.
I'm going to use a min-heap which runs on O(m log(n)) I believe.
My real question is what data structure should I used to store the adjacent nodes of each node?
I'm thinking about using an adjacency list because I can find all adjacent nodes on u in O(deg(u)), is this the fastest method?
How will that change the running time of the algorithm?
For the algorithm itself, I think you should aim for compact representation of the graph. If it has a lot of links per node, a matrix may be best, but usually an adjacency list will take less space, and therefore less cache misses.
It may be worth looking at how you are building the graph, and any other operations you do on it.
With Dijkstra's algorithm you just loop through the list of neighbours of a node once, so a simple array or linked list storing the adjacent nodes (or simply their indices in a global list) at each node (as in an adjacency list) would be sufficient.
How will that change the running time of the algorithm? - in comparison to what? I'm pretty sure the algorithm complexity assumes an adjacency list implementation. The running time is O(edges + vertices * log(vertices)).

convert a binary search tree to doubly linklist using recursion

As mentioned in the Title , I have a Binary search tree. I want to convert it to sorted doubly linklist using recursion.
My code
for each node in tree
find max of left sub-tree and assign its right to present node ,present node left to max
find min of right sub-tree and assign its left to present node ,present node right to max
and now recursively do same thing to other nodes in BST .
but this solution is not efficient as it reaches each node more than one time .In my quest of optimized code i got a link from google greatTreeList sollution . I have searched the same in SO both sollutions are same and worked for me. I didnt understand the append function of the sollution as it contains code
join(alast,b)
join(blast,a)
For tree whose nodes are inserted in following order 10,5,9,6,8,7,12,11,13,14
can anyone please explain how
join(alast,b)
join(blast,a)
are linking node in each recursion call.
I think you are over thinking this actually quite easy task - extracting the data from a binary tree in order is as simple as doing a depth first traversal - this is the point of a binary tree that it very efficiently gives you the elements in the sorted order.
So what you need to do is a standard depth first walk of the tree and each time you find a node add it to you linked list.
This in order depth first recursion is fairly straight forward is pseudocode:
Traverse(Node N)
Traverse(N.left);
Add N to the linked list
Traverse(N.right);
I suggest you try this manually on you example so you see how it works.
In order to convert a binary search tree to a sorted doubly linked list, one typically performs an inorder depth-first traversal, building the list along the traversal.
Try to come up with code that performs an inorder depth-first traversal and prints the items of the binary tree in sorted order. From there, it should be easy to complete your task.
Expanding on Elemental's answer
Traverse(Node N)
Traverse(N.left);
Add N to the linked list
Traverse(N.right);
To add N to the linked list,
your linked list class or data structure should have an append() method or similar.
Use your imagination, but something like this:
def append(N):
new_tail = node(val=N, prev=self.tail, next=None)
self.tail.next = new_tail
self.tail = new_tail
of course you also need to add self.head = self.tail the first time you append.

C Creating an Ordered Priority Queue

I am trying to implement dijkstra's algorithm for path finding and need some sort of priority queue to store the information.
In the past, for example a fifo or filo PQ i've simply used an array and then two pointers to the current insert and the current "look" position and then to "remove" and item shifted the look position up once.
However for dijkstra's I need a PQ that is ordered by weight (or current distance) and then look at the one that is at the top of the PQ, how would I go about implementing this in C?
Thanks for your time!
Edit: People have mentioned binary heap, do you mind giving a slight hint as to how to get started?
The easiest option is to implement a binary heap based on C arrays.

How to search a specific node in a graph structure in C?

Not that I have time to discuss this properly to reach a conclusion and adapt my code because the phase one (of three) of a school project is in 24hrs, but at least I need to know if I did the correct decision.
I'm using linked lists and here's my structures:
typedef struct sCity {
int cityID;
char *cityName;
struct sCityLink *links;
struct sCity *next;
} nCity, *City;
typedef struct sCityLink {
City cityLinkParent;
City cityLinkTo;
struct sCityLink *next;
} nCityLink, *CityLink;
Basically, I have lots of cities and those cities are linked all together, like a graph. For instance, A, B, C, D and E they are inserted in this order into the structure City. Then, I connect A to B, C and D, B to C, D, E, C to D and E and D to E.
Now, let's say I need to go to city E. This is the last one in the linked list and it takes time to traverse the linked list all the way. Maybe not on this example with 5 cities but in the real app I'm supposed to support like 10,000 cities at least. But the shortest route is from A (which is the starting point) from C to E (or it could be A-D-E or A-B-E, doesn't matter).
Do my structures allow me to find the shortest route from A to E without traversing the whole linked list one by one? If not, what I'm doing wrong?
If yes, how can I do that? I don't have a clue how can I find such a path...
There are two separate issues - one, you probably want to find a City pointer for a city ID (eg. "E"). You cannot do that in less than linear time with your structures; if you need it faster, use a hashtable or binary search tree.
Two, you want to find a path between two given cities. For this you'd probably use the BFS algorithm, for which your data structure is just fine. Note that BFS takes O(V+E) time where V and E are the vertex and edge count of the induced subgraph whose vertices' distance from the start vertex is not greater than the distance from start to end vertex. Which means in the worst case, it takes more time than traversing the list of cities.
You can use an algorithm called Breadth-First Search (BFS). You need to implement a "color" flag on each node to use it. Note that this algorithm only works if your edges are unweighted -- if 2 cities are connected, then they are of equal distance.
If the edges have weight (which it does not look like they do), you need something like Dijkstra's Algorithm or A*.

Resources