Tree data structure implementation [duplicate] - java

This question already has answers here:
How to implement a tree data-structure in Java?
(27 answers)
Closed 1 year ago.
I recently started college with no previous coding experience. I began to study a tree data structure and its Java implementation. The question is quite basic but I have not found an answer to it.
As in a list you'd start by typing import java.util.List what do you need to do in order to start with a tree implementation?

There is no need to import a Java package for implementing Trees. Tree structure is a collection of nodes/instance of a class referencing to the address of the child nodes. Although, there are different types of trees like Binary Search Tree or AVL Trees, however each tree has separate property.
Sample Implementation of Binary Search Tree in Java is as follows:
/* Node Class containing left and right child of current
node and key value*/
class Node
{
int key;
Node left, right;
public Node(int item)
{
key = item;
left = right = null;
}
}
class Tree
{
Node root;
Tree()
{
root = null;
}
public static void main(String[] args)
{
Tree tree = new Tree();
tree.root = new Node(1);
tree.root.left = new Node(2);
tree.root.right = new Node(3);
tree.root.left.left = new Node(4);
}
}

The easiest answer is the DefaultTreeModel class. Basically, you create TreeNode objects and add them to the Model or Parent node as needed. DefaultMutableTreeNode should be good enough to meet your needs as a beginner.
You can navigate the model using recursion easily enough.

For a regular binary tree you could implement your own:
class Node {
int value;
Node left;
Node right;
public Node(int value) {
this.value = value;
}
}
Then create a BinaryTree class that contains a root Node instance.

a tree structure is a bit different from the list implementation...
i recommend you to see this topic if you just want the code, if your focus question isn't how to do if but how does they work, i recommend this.
and if you have found the problem by using this data structure, you need to learn this

Related

Dynamically add nodes in a JTree

I have data like this (has other data like percentage, but is not important now) in a List that can vary:
1
1.1
1.1.1
1.1.2
1.2
2
2.1
2.2
How i easily work with the levels to build a proper JTree for any given levels?
Can be done with recursion?
What the best way?
Thank you so much.
Yes, it can easily be done using recursion. The idea is to check if there is already a node in the tree under which the new node can be fallen. For example, if the new node is "1.1.2", then we have to check if the node "1.1" exists in the tree. I wrote a very simple code and it is working, I am going yo cope here. If you don't understand something then just let me know, I will explain you. The function to check if the tree has the node of a particular string is given below.
public DefaultMutableTreeNode findparentnode(String s,DefaultMutableTreeNode root){
DefaultMutableTreeNode parent=null;
for (int i=0;i<root.getChildCount();i++) {
if(s.equalsIgnoreCase(((DefaultMutableTreeNode)root.getChildAt(i)).toString())){
parent = (DefaultMutableTreeNode)root.getChildAt(i);
break;
}
else
parent=findparentnode(s, (DefaultMutableTreeNode)root.getChildAt(i));
}
return parent;
}
Now, we will check every string in the list. We will skip the last part of the string, and will pass the remaining value to the function. To check the string, the code is given below
for(String s:list){
String[] substr=s.split("\\.");
String parent=substr[0];
for(int i=1;i<substr.length-1;i++){
parent=parent+ "." + substr[i];
}
DefaultMutableTreeNode node=null;
node=findparentnode(parent,root);
if(node==null)
root.add(new DefaultMutableTreeNode(s));
else
node.add(new DefaultMutableTreeNode(s));
}

Implementing the List<Node>

I decided to implement the Abstract List<Node> . here is a piece of it:
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
public class myNodeList implements NodeList{
Node root = null;
int length = 0;
public myNodeList() {}
public void addNode(Node node) {
if(root == null)
{
root = node;
}
else
root.appendChild(node);
length++;
System.out.println("this is the added node " +node);
}
}
but when I try to add a node, it gives me the following exception:
Exception in thread "main" org.w3c.dom.DOMException: HIERARCHY_REQUEST_ERR: An attempt was made to insert a node where it is not permitted.
at com.sun.org.apache.xerces.internal.dom.NodeImpl.insertBefore(NodeImpl.java:478)
at com.sun.org.apache.xerces.internal.dom.NodeImpl.appendChild(NodeImpl.java:235)
at pageparsertest.myNodeList.addNode(myNodeList.java:27)
is this because of the Node root = null; which makes to add a node to a null node?
then how can be fixed
You can't append to a com.sun.org.apache.xerces.internal.dom.NodeImpl, you'll need to use com.sun.org.apache.xerces.internal.dom.ParentNode.
appendChild will call insertBefore which only throws an Exception for NodeImpl
Source code
Move one or more node(s) to our list of children. Note that this
implicitly removes them from their previous parent.
By default we do not accept any children, ParentNode overrides this.
Take a look how Axis implemented their : http://grepcode.com/file/repo1.maven.org/maven2/com.ning/metrics.collector/1.0.2/org/apache/axis/message/NodeListImpl.java
It seems you're trying to build a Node tree using the first Node as the Root, not a node list. Which is not possible has your nodes are NodeImpl not ParentNode.
If you want a tree, you'll have to create (or import) somehow a parent node.
If you just need a list, then use a List.
You may need to create a fake custom parent to insert your nodes.
Take a look here : HIERARCHY_REQUEST_ERR while trying to add elements to xml file in a for loop
well this is embarressing but I changed my idea to implement that and instead usedstatic List<Node> listOfNodes = new ArrayList<Node>();
which worked well for me!

Categories - sub categories traversal algorithm

I am looking for good way to traverse a list of categories to create an hierarchy. The present algorithm I am using will not be able to take deep nesting into consideration.
I have a list of all categories (including parent and their all sub-categories), category class is like below:
class Category{
private int id;
private int parentCategoryId;
private String name;
/*Getter Setters*/
}
Here the parentCategoryId stores the id of its parent, root categories will be having parentCategoryId = 0 and their could be many root categories. Current condition requires me to extend the nesting to atleast 5-6 levels deep, and my current algo fails over that.
What could be a good way to arrange them in such an order that I can easily iterate over them in my view to build something like this:
-Root1
--Root1Sub1
--Root1Sub2
---Root1Sub2SubSub1
---Root1Sub2SubSub2
-Root2
--Root2Sub1
The algorithm you are looking for is called Depth-first search, or DFS (you can also compare it to Breadth-first search, BFS).
As written in Wikipedia:
Depth-first search (DFS) is an algorithm for traversing or searching tree or graph data structures. One starts at the root (selecting some arbitrary node as the root in the case of a graph) and explores as far as possible along each branch before backtracking.
In order to use it efficiently, your class needs to have a list of references to child categories (parent IDs is not important, but you should have actual references, not IDs, of the child categories).
The algorithm (using an explicit stack) is then something like:
static void dfs(Category root) {
Stack stack = new Stack();
// start by pushing the root node to the stack
stack.push(root);
while (!stack.isEmpty()) {
Category node = (Category)stack.pop();
// do something with this node
// e.g. System.out.print(node.name);
// push children to the stack
stack.addAll(node.children);
}
}
Recursive solution is even simpler:
static void recursiveDfs(Category node) {
// do something with this node
// e.g. System.out.print(node.name);
// recursively process all children
Iterator children = node.children.iterator();
while (children.hasNext())
recursiveDfs((Category)children.next());
}

How do I enumerate an object based on nodes in Java?

Say I constructed an Integer Node like so:
Node<Integer> node = new Node<Integer>(0, new Node<Integer>(1, new Node<Integer>(2, null)));
And get a node that looks like "0 ---> 1 ---> 2".
My objective is that when I run a command like node = node * 4 + 28; , node will look like "28 ---> 32 ---> 36", WITHOUT using functions such as multiply(...).
That is, node = node * 4 + 28 and not node.multiply(4); node.add(28); (unless it's used as a private function in a larger parsing function - a function I'd like to avoid if possible.)
Is there a way to enumerate nodes and other data structures (like Queue and Stack) like that in Java?
(Small note: Node itself is generic. It doesn't have to work with Strings, though. It'd be really nice if it did, though.)
Thanks in advance!
For those interested, Node looks like this:
public class Node<T> {
private T info;
private Node<T> next;
...
}
public class Node {
private int value = 0;
private Node next = null;
...
public void multiply(int num) {
value *= num;
if (next != null)
next.multiply(num);
}
}
If I get the question right, the function you're looking for is usually called map and it's not present in Java itself.
However, it's a paradigm commonly used in functional programming, so you might want to check e.g. Guava which offers a bunch of functional features to Java users.

Flex - How to display Tree like view of file system?

I need a view of file system like this.
folder_name
|_sub_folder1
| |_file1
| |_file2
|_sub_folder2
|_file1
please give your comments.
First off, Flex in a browser will not give you access to any file system information, only AIR projects will allow you to access files and directories.
Now, if you're just trying to create a tree, I've found the easiest is to make your own object, with an array property "children" that will automatically be used by the flex tree control to display subnodes.
so:
<mx:Tree id="treeProducts" labelField="productName"
dataProvider="{_productList}">
</mx:Tree>
where:
[Bindable]
var _productList:ArrayCollection;
and for each object you put into _productList, it needs:
tmpObject.children = new ArrayCollection();
What does Flex have to do with your question?
You already asked this question and got your answer: use a tree. Furthermore, you don't say whether you want to process the structure (run through it), store it in memory, or whether you want to visually display the tree.
If you're putting it into memory, create a node-based tree where each Node has a List of Nodes. Each node's value is a String containing the file name. Below is an example. I suggest coming up with something a little more usable. You could use the JTree API or the DOM API, but I recommend creating a tree from scratch because it has a much smaller memory footprint.
import java.util.ArrayList;
import java.util.List;
public class TreeTest {
public static void main(String[] args) {
Tree<String> t = new Tree<>();
Tree.Node<String> usr = new Tree.Node<>("/usr");
Tree.Node<String> home = new Tree.Node<>("/home");
Tree.Node<String> share = new Tree.Node<>("/share");
Tree.Node<String> docs = new Tree.Node<>("/documents");
t.root = new Tree.Node<>("/");
t.root.children.add(usr);
t.root.children.add(home);
usr.children.add(share);
home.children.add(docs);
}
}
class Tree<T> {
Node<T> root;
static class Node<T> {
T file;
List<Node<T>> children = new ArrayList<>();
Node(T file) {
this.file = file;
}
}
}

Categories

Resources