How to sort glazed TreeList? - java

I have a pretty weird question - how to sort glazed TreeList? I am using it in SWT NatTable, and when my data provider is set to GlazedListsDataProvider with TreeList inside it, sorting works in a very strange way. It works fine, if I am using GlazedListsDataProvider with SortedList.
For instance, my tree looks like that:
Root
Node1
Child1
Child2
Node2
Child3
I need to sort only children INSIDE Node1 and Node2, separately one of another (so that only child1 and child2 will change their place). However, After sorting it looks like following:
Root
Node1
Node2
Child1
Child2
Child3
Reversed sorting:
Root
Node1
Node2
Child2
Child1
Child3
So basically, it kind of working (it does sort children in a correct way), but moreover it sorts elements, which it should not sort. What could be a reason of such behavior? My sorting algorithm is simple:
compare (element1, element2) {
if (both elements are under same parent and have same type)
compare
otherwise
return 0
}
I am doing sorting as proposed in following example http://kari.dy.fi/src/sample/foldertree.zip - meaning, that after comparator is build in SortState I am setting it into the TreeFormat, used by TreeList.
I assume, that returning 0 does not work in a correct way, however, I can not see other solution. Or may be it is a problem somewhere else, not in my comparator.
Thank you for your patience, I will be glad to get any hints.
Best regards, Alex G.

Your current code returns 0 when to nodes have different parents. That's like, 'if they have different parents, I don't care which one goes first'. But I think you want, 'if they have different parents, the first should be the one with the first parent'. If you want to do custom sorting inside the parents only, you should keep sorting outside the parents the way it was. Not sure about the exact code, but you could do something like:
compare (element1, element2) {
if (both elements are under same parent and have same type)
compare
otherwise
return original.compare(element1,element2)//delegate to the original sorting
}
Or
compare (element1, element2) {
if (both elements are under same parent and have same type)
compare
otherwise
compare(element1.parent,element2.parent) // sort on parent level
}

So, here is my solution for this problem: DZone Article. Once again, it is only one of the possible solutions, and it is not perfect, but it is working:)

Related

Cloning references?

This may be a too-specific question, but I'm hoping there's a more general solution to my problem.
I have a class. In this class is a tree-type structure with many parent/child nodes. Also in this class is an Array filled with references to each node in this tree-type structure.
The tree's purpose is for each node to know where to draw itself on screen (every node has relative positional information based on its parent's location).
The Array's purpose is the draw order, I simply draw whatever node is referenced at Array[0] first and so on. (So, the nodes aren't being drawn in the order they appear in the tree necessarily).
My problem is this. I want to clone this overall class that contains these two objects (tree with nodes and an Array that references said nodes). This seems simple.
I create a deep copy of the tree structure and the nodes it contains. Cool.
However, I don't know how to repopulate a new Array with references to these new nodes in this new tree. It seems like it would be simple but I can't figure out how to do it.
I tried to be specific enough to give enough information without being too confusing, hope you understand.
Thanks.
If you're able to change the node data structure, you could add a field for the node's array index. That way, once you've rebuilt your tree you can just walk through it and use the index field to repopulate the array. Not super elegant, but it gets the job done...
Or, to avoid adding a field to your node class, I suppose you could use a temporary hashtable that maps nodes to array indices. Walk through your source array to populate the hashtable, then once you've cloned the tree, walk through the tree, looking up the new nodes in the hashtable (which will work fine assuming you've implemented equals and hashCode properly) and populating the array from those.

How to create a simple unordered tree(not BST) in java with given node pairs(u,v)?

Problem is I don't understand how to create a tree. I have gone through many code examples on trees but I don't even know how to work with/handle a node and hence I don't understand how the node class works(that was present in all the program examples ). When i try to use methods such as appendChild(as mentioned in java docs),I get an error,and I am asked to create one such appendChild method inside that node class within the main program. Couldn't understand why that happened.
I am given integer pairs((u,v) meaning there is an edge between u & v) of nodes and I also need to know if any Element-to-node conversion is required for using u and v(of type integer) as nodes.
Please bear with me since my basics are weak. Little explanation on how the entire thing works/functions would be very helpful.
Thank you.
EDIT 1: I went through the following links:(hardly found anything on just unordered trees) http://www.cs.cmu.edu/~adamchik/15-121/lectures/Trees/code/BST.java http://www.newthinktank.com/2013/03/binary-tree-in-java/ . Tried to modify these codes to meet my own purpose but failed.
I only got a blurry idea and that is not enough for implementation. I am trying to make a simple unordered tree,for which i am given u v pairs like:
(4,5) (5,7) (5,6). I just need to join (4<--5),(5<--7) and (5<--6). So how do I write a node class that only joins one node to the prev node? Besides,to do only this,do I need to bother myself with leftchild,rightchild? If not,how will I be able to traverse the tree and do similar operations such as height diameter calculation etc later?
Thank you for your patience.
Well Its not entirely clear whether you want an explanation on tree creation in general, on some tree implementation you have found, or you have a basic code already that you cannot get working. You might want to clarify that :).
Also tree creation in general:
Most explanation and implementation you will find might be "overly" elegant :). So try to imagine a simple linked list first. In that list you have nodes(the elements of the list). A node contains some valuable data and a reference to an other node object. A very simple tree is different only in that a node have more than one reference to other nodes. For example it has a Set of references, its "children".
Here is a VERY crude code only as an example for addChild() or appendChild in your case:
public class Node {
private String valueableData;
private Set<Node> children;
public Node(){
this.children=new HashSet<Node>();
}
public Node (String valueableData){
this.valueableData=valueableData;
this.children=new HashSet<Node>();
}
public void addChild(Node node){
children.add(node);
}
}
Now this implementation would be quite horrible (I even deleted the setter/getters), also it would be wise to keep the root nodes reference in some cases, and so on. But you might get the basic idea.
You might wanna create a cycle or recursion to go over the (u,v) integer pairs. You create the root node first then you just addChild() all the other nodes recursively, or create every node first then setChild() them according to your rules.

How to populate JTree dynamically?

I am working on a project that requires the use of a tree data structure. Having done some researches I found that Java JTree would be of great use to my project, however I stumbled upon a problem that I spent a week fixing but to no avail.
Here's the problem, in order to create a new node, a DefaultMutableTreeNode has to be instantiated and I'm not sure how that can be done in a loop. Normally when we want to create a new node in JTree, we would firstly declare the nodes in the following way:
DefaultMutableTreeNode parent = new DefaultMutableTreeNode("This is parent node.");
DefaultMutableTreeNode child = new DefaultMutableTreeNode("This is child node.");
Then, in order to add/link child node to parent node, we would do the following:
parent.add(child);
I have two arraylists containing the parent nodes and child nodes, they correspond to each other in a parent-child relationship, meaning that arraylistParent.get(x) will always be the parent of arraylistChild.get(x).
I was thinking that by using a for loop, I could do:
for (int x = 0; x < arraylistParent.size(); x++){
parent.add(new DefaultMutableTreeNode(arraylistChild.get(x)));
}
This could only work in a flat hierarchy tree, which obviously isn't the case for me. I will have different parent nodes in arrayListParent which I need to check before adding the child nodes, but once again not all child nodes have the same, single parent node. My arraylists probably contain something like this:
arraylistParent = [root, p1, p2, p2, p3, p1]
arraylistChild = [p1, p2, p5, p3, p4, p5]
and I want to generate the tree structure like this:
root
..p1
..p2
..p5
..p3
..p4
..p5
Obviously I can throw a few if loops inside to check whether parent.getUserObject() is the same as arraylistParent.get(x) but only those that match the string "This is parent node" will be checked and added.
If there's a different, non-existent parent found in the loop, a new parent needs to be created and this is the tricky part I don't know how to solve, as I have no idea how to have the loop automatically create a new instance of parent for the child node.
Let us assume your node-datums are Strings (that is, the contents of your ArrayLists are Strings). The explanation will work with any other Java object, though. We will call these contents 'nodes', as distinct from 'tree nodes'.
You can create a HashMap<String, DefautMutableTreeNode> m, so that m.get(node) will return the corresponding TreeNode.
Now, you have to iterate over the parents' arraylist. At each position, you will have a parent and a child. Look them up in the map. If the parent TreeNode does not exist, you will first have to create it. If the child TreeNode does not exist, the same will apply. You should make sure that the map is updated after creating any TreeNodes. Finally, you will mark the child as a child of the parent.
At the end of this algorithm, you should look through all the nodes in the child array. The one without any parents is the root. This is the root of your tree.

Are there any performance differences between singly- and doubly-linked lists?

Our homework assignment asks us to prove that the Java LinkedList implementation is doubly-linked and not singly-linked. However, list operations such as adding elements, removing elements, and looking elements up seem to have the same complexity for both implementations, so there doesn't seem to be a way to use a performance argument to demonstrate the doubly-linked nature of Java's LinkedList. Anyone know of a better way to illustrate the difference between the two?
Look at iterating in forward or backward direction, removing the "before-last" element, and such.
It's quite an easy proof -- you look at the source code and see that each node has a .previous pointer :)
http://www.docjar.com/html/api/java/util/LinkedList.java.html
Consider the following nodes, single and double.
class SingleLinkedNode {
E data;
SingleLinkedNode next;
}
class DoubleLinkedNode {
E data;
DoubleLinkedNode prev;
DoubleLinkedNode next;
}
If we want to remove from a DoubleLinkedList (assuming we have already FOUND the node, which is very different) what do we need to do?
Make the node before the deleted
one point to the one after.
Make the node after the deleted one point to the one before.
If we want to remove from a SingleLinkedList (assuming we have already FOUND the node, which is very different) what do we need to do?
Make the node before the deleted one point to the one after.
You'd think that means it's even faster in a single linked list than a double.
But, how are we doing to delete the node if we don't have a reference to the one before it? We only have a reference to the next. Wouldn't we have to do a whole other search on the list just to find prev? :-O
The Java List interface doesn't have a method which allows you to remove an item without searching through a linked list. It has remove(int index), which would have to scan the list to find the indexed entry, and it also has remove(Object o), which has to scan the list as well. Since a linked list implementation can save the necessary previous-item entry context while scanning, remove has equivalent complexity for singly- and doubly-linked lists. This state can be saved in an iterator, as well, so Iterator.remove() doesn't change this. So I don't think you can tell from remove performance.
My guess is that the "right" answer to this is to create several lists of different sizes and time the performance of .indexOf() and .lastIndexOf() when searching for the first or last object. Presuming that the implementation is doubly-linked and searches from the beginning of the list for .indexOf() and searches from the end for .lastIndexOf(), the performance will be length-dependent or length-independent.

Efficient way to walk through an object tree?

I've got a set of TreeNodes, each of which has an id, a Collection of parent nodes, and a collection of child nodes.
For a given node Id, I'm looking for an efficient way to generate all the links that pass through that node. So in short, start at the node, and iterate through all its children. If a node has more than one child, create a link for each child. The traverse the children etc..
I'd also like to be able to do this in an 'upward' direction, through the parent nodes.
Is there a simple algorithm to do this?
EDIT: Oh, and I'd like to be able to output the id's of all the nodes in a given chain...
You are looking for a Breadth First or Depth First Search. At first it is not more than the following (this is depth first search).
Visit(Node node)
{
foreach (Node childNode in node.Children)
{
Visit(childNode);
}
DoStuff(node);
}
The problem is that the graph may contain cycles, hence the algorithm will enter infinite loops. To get around this you must remember visited nodes by flaging them or storing them in a collection. If the graph has no cycles - for example if it is a tree - this short algorithm will already work.
And by the way, if a TreeNode has multiple parents, it's not a tree but a graph node.
Well, if the nodes have a reference to the parent, it's simple as getting the parent recursively (once in a tree, each node has only one (or none at all, if it is a root) parent.
If there's no such reference, than you could use a breadth-first search, for instance, having as initial set your collection of parent nodes.
-- EDIT --
Once a node may have more than one parent, then you're dealing with a graph. There are also graph traversal algorithms (see table at the side).
Make sure that, if your graph has a cycle, you won't end up having a infinite loop
You might want to check out depthFirstEnumeration() and breadthFirstEnumeration() on DefaultMutableTreeNode. However, this doesn't solve your problem of wanting to navigate the tree in a bottom-up fashion.

Categories