I want to create a program that creates a graph (to be specific a program graph), which stores values at nodes and also stores what other nodes each individual nodes are connected to.
I am thinking of doing this using linked list. Is this the right way to go about it? Any other advice would be greatly appreciated.
For the most part it's a good idea to model your graph with an adjacency list. There are probably existing frameworks to do this, but if you're interested in the representation as an exercise, you generally want two things. First, a HashMap containing all of your nodes, the node label for your node can be the key, the node itself is the value.
The Java API documents HashMaps here.
In each node object, you'll want a list of nodes that are adjacent to that node. This is best done with an ArrayList, which is documented here.
Here's how it might be organized.
import java.util.Hashmap;
import java.util.ArrayList;
class Node {
String label;
ArrayList<Node> adjacencyList;
}
HashMap<String, Node> graph = new HashMap<String, Node>();
Most algorithms you'd want to run on a graph will run well on this representation.
What you are looking for seems to be a TreeNode API.
Actually there is a nice one inside the swing package which is already present in Java SE the default implementation being: javax.swing.tree.DefaultMutableTreeNode.
It can be used outside of a Swing application and provide a very standard TreeNode model.
You will find every thing to fit your need: getChildren(), getParent(), setUserObject()... etc and every recursive method for crawling and searching over the nodes tree.
The good news is you will earn the ability to write a JTree UI in a few minutes!
You can write your own graph object or use something like Jung.
Related
I have a tree represented with the library jgrapht, there are variuous type of nodes I need to cut any subtree starting from a particulare node type.
As you can see in this example, this tree represent a source code of a Java class. I need to create multiple jgrapht objects by splitting the main tree starting for each "Entry" node type. In total I should get 7 tree from this big one. The structure I use is a DirectedPseudograph.
Although I'm not 100% clear about what you want, it seems there are various solution approaches.
Starting from every outgoing neighbor of the root node, you could run a depth first search and record the nodes returned. The nodes reachable by the DFS algorithm belong to the same subtree. For this you can use the DepthFirstIterator
You could create a subgraph without the root node, for instance by using the AsSubgraph class. You can then invoke the ConnectivityInspector on the resulting induced subgraph. Since every subtree is a disconnected graph component, the connectivity inspector will be able to find each of these components.
Btw, unless you need the capabilities of a Pseudograph, for performance it would be better to use the SimpleDirectedGraph. Obviously, the latter does not allow parallel edges or self-loops.
I'm having trouble figuring out what kind of data structure to use. I'm trying to represent classes that need to be taken to complete a major, complete with prereqs. Originally, I was thinking of using and adjacency matrix to represent the data. However, I'm currently using an arraylist to store each course. Then, in each course object, I have an arraylist containing the parents of each course and the children of each course. I'm planning on having a dummy course with the first courses in its children array. Then I plan on doing a BFS and adding classes so long as the parents have been taken and the current course hasn't. I can't help but feeling that this isn't the ideal solution. I tried looking at the difference between lists, sets, and maps, and I can't come to a clear reason why one is superior to the other. All of the courses are unique and sets don't contain duplicates, so that seems to make sense. On the other hand, the order of classes taken matters, so a list seems like a good idea. Then again, I could have the course number be the key and the course object be the value in a map.
I am trying to define adjacency multi-list in java. These type of lists are usually Edge based but I want to make it to be node/vertex based. Like list shows each vertex and edges associated with it.
I suggest you to watch the Coursera courses regarding algorithms, they are really well done and cover also these topics.
Here you can follow the Graph.java class for undirected graph with adjacency list
http://algs4.cs.princeton.edu/41undirected/Graph.java.html
Hi
I have a question that I have written a code such a merge sort that we can have a binary decision tree for that .but when i want to merge those elements I do not need those external nodes that has just one element in it! so what should I do with them? I should return them?
I'd say you remove the parent because your tree at that point degrades to a list. If the action at the leaf depends on data at the parent then there's not much you can do unless you can merge actions into one.
I'm writing a Java Tree in which tree nodes could have children that take a long time to compute (in this case, it's a file system, where there may be network timeouts that prevent getting a list of files from an attached drive).
The problem I'm finding is this:
getChildCount() is called before the user specifically requests opening a particular branch of the tree. I believe this is done so the JTree knows whether to show a + icon next to the node.
An accurate count of children from getChildCount() would need to perform the potentially expensive operation
If I fake the value of getChildCount(), the tree only allocates space for that many child nodes before asking for an enumeration of the children. (If I return '1', I'll only see 1 child listed, despite that there are more)
The enumeration of the children can be expensive and time-consuming, I'm okay with that. But I'm not okay with getChildCount() needing to know the exact number of children.
Any way I can work around this?
Added: The other problem is that if one of the nodes represents a floppy drive (how archaic!), the drive will be polled before the user asks for its files; if there's no disk in the drive, this results in a system error.
Update: Unfortunately, implementing the TreeWillExpand listener isn't the solution. That can allow you to veto an expansion, but the number of nodes shown is still restricted by the value returned by TreeNode.getChildCount().
http://java.sun.com/docs/books/tutorial/uiswing/components/tree.html#data
scroll a little down, there is the exact tutorial on how to create lazy loading nodes for the jtree, complete with examples and documentation
I'm not sure if it's entirely applicable, but I recently worked around problems with a slow tree by pre-computing the answers to methods that would normally require going through the list of children. I only recompute them when children are added or removed or updated. In my case, some of the methods would have had to go recursively down the tree to figure out things like 'how many bytes are stored' for each node.
If you need a lot of access to a particular feature of your data structure that is expensive to compute, it may make sense to pre-compute it.
In the case of TreeNodes, this means that your TreeNodes would have to store their Child count. To explain it a bit more in detail: when you create a node n0 this node has a childcount (cc) of 0. When you add a node n1 as a child of this one, you n1.cc + cc++.
The tricky bit is the remove operation. You have to keep backlinks to parents and go up the hierarchy to subtract the cc of your current node.
In case you just want to have the a hasChildren feature for your nodes or override getChildCount, a boolean might be enough and would not force you to go up the whole hierarchy in case of removal. Or you could remove the backlinks and just say that you lose precision on remove operations. The TreeNode interface actually doesn't force you to provide a remove operation, but you probably want one anyway.
Well, that's the deal. In order to come up with precomputed precise values, you will have to keep backlinks of some sorts. If you don't you'd better call your method hasHadChildren or the more amusing isVirgin.
There are a few parts to the solution:
Like Lorenzo Boccaccia said, use the TreeWillExpandListener
Also, need to call nodesWereInserted on the tree, so the proper number of nodes will be displayed. See this code
I have determined that if you don't know the child count, TreeNode.getChildCount() needs to return at least 1 (it can't return 0)