DoubleLinkedTree.java
Go to the documentation of this file.
00001 /*
00002  * (c) copyright 2008, Technische Universitaet Graz and Technische Universitaet Wien
00003  *
00004  * This file is part of jdiagengine.
00005  *
00006  * jdiagengine is free software: you can redistribute it and/or modify
00007  * it under the terms of the GNU General Public License as published by
00008  * the Free Software Foundation, either version 3 of the License, or
00009  * (at your option) any later version.
00010  *
00011  * jdiagengine is distributed in the hope that it will be useful,
00012  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014  * GNU General Public License for more details.
00015  * You should have received a copy of the GNU General Public License
00016  * along with jdiagengine. If not, see <http://www.gnu.org/licenses/>.
00017  *
00018  * Authors: Joerg Weber, Franz Wotawa
00019  * Contact: jweber@ist.tugraz.at (preferred), or fwotawa@ist.tugraz.at
00020  *
00021  */
00022 
00023 
00024 package utils;
00025 
00026 import java.util.*;
00027 
00028 
00029 public class DoubleLinkedTree {
00030  
00031     protected long lastId = -1;
00032 
00033     protected DoubleLinkedTreeNode root;
00034 
00035     protected int size = 0;
00036 
00037 
00038 
00039     public DoubleLinkedTree(int initialCapacity) {
00040     }
00041 
00042     public void addNode(DoubleLinkedTreeNode newNode, DoubleLinkedTreeNode parent) {
00043         assert((root == null) || (parent != null));
00044 
00045         ++lastId;
00046         newNode.setId(lastId);
00047 
00048         if (root == null) {
00049             root = newNode;
00050         }
00051         if (parent != null) {
00052             newNode.setParent(parent);
00053             parent.addChild(newNode);
00054         }
00055 
00056         ++size;        
00057         //nodes.put(newNode.id, newNode);
00058     }
00059 
00060     public int size() {
00061         return size;
00062     }
00063 
00064     /*
00065      * Returns an iterator for the entire tree.
00066      *
00067      * Pre-order iteration: the nodes are returned in the same order as they are visited by visitChildrenPreOrder().
00068      */
00069     public Iterator iterator() {
00070         return new DoubleLinkedTreeIterator(root);
00071     }
00072 
00073     /*
00074      * Like iterator(), but only startNode and its descendants are iterated.
00075      */
00076     public Iterator iterator(DoubleLinkedTreeNode startNode) {
00077         return new DoubleLinkedTreeIterator(startNode);
00078     }
00079 
00080     public void visitChildrenPreOrder(DoubleLinkedTreeNode node,
00081                                       DoubleLinkedTreeVisitor visitor) {
00082 
00083         visitChildrenPreOrder_Recursive(node, visitor);
00084     }
00085 
00086     public void visitChildrenPreOrder_Recursive(DoubleLinkedTreeNode node,
00087                                                 DoubleLinkedTreeVisitor visitor) {
00088 
00089         visitor.visit(node);
00090         boolean moreNodes = visitor.wantMoreNodes();
00091         if (moreNodes) {                
00092             Iterator itChildren = node.getChildrenIterator();
00093             while (moreNodes && itChildren.hasNext()) {
00094                 DoubleLinkedTreeNode child = (DoubleLinkedTreeNode)itChildren.next();
00095                 visitChildrenPreOrder_Recursive(child, visitor);
00096                 moreNodes = visitor.wantMoreNodes();
00097             }
00098         }
00099     }
00100 
00101     /*
00102      * Remove leafNode which MUST really be a leaf.
00103      */
00104     public void removeLeafNode(DoubleLinkedTreeNode leafNode) {
00105         assert(leafNode.isLeafNode());
00106         //assert(nodes.containsKey(leafNode.id));
00107 
00108         DoubleLinkedTreeNode parent = leafNode.getParent();
00109         if (parent != null) parent.removeChild(leafNode);
00110         else {
00111             assert(leafNode == root);
00112             root = null;
00113         }
00114         //nodes.remove(leafNode.id);
00115     }
00116 
00117     /*
00118      * Removes node and all of its descendants from this tree.
00119      */
00120     public void removeNodeAndDescendants(DoubleLinkedTreeNode node) {
00121         DoubleLinkedTreeNode parent = node.getParent();
00122         if (parent != null) parent.removeChild(node);
00123         else {
00124             assert(node == root);
00125             root = null;
00126         }
00127         //removeRecursive(node);
00128     }
00129 
00130     /*
00131      * Creates a list containing all nodes of this tree.
00132      *
00133      * The order of the resulting list is not guaranteed.
00134      * Note that this method is computationally expensive, as the list must be created from scratch. 
00135      */
00136     public List composeNodeList() {
00137         ArrayList result = new ArrayList(size());
00138 
00139         DoubleLinkedTreeIterator itNodes = new DoubleLinkedTreeIterator(root);
00140         while (itNodes.hasNext()) {
00141             Object node = itNodes.next();
00142             result.add(node);
00143         }
00144 
00145         return result;
00146     }
00147 
00148     /*
00149     protected removeRecursive(DoubleLinkedTreeNode node) {
00150         
00151         Iterator itChildren = node.getChildrenIterator();
00152         while (itChildren.hasNext()) {
00153             DoubleLinkedTreeNode child = (DoubleLinkedTreeNode)itChildren.next();
00154             removeRecursive(child);
00155         }
00156 
00157         nodes.remove(node.id);
00158         }*/
00159 }
00160 
00161 /*
00162  * For pre-order iteration of a tree.
00163  */
00164 class DoubleLinkedTreeIterator implements Iterator {
00165     
00166     protected Stack nodesOnRight;
00167 
00168     protected DoubleLinkedTreeNode nextNode;
00169 
00170     
00171     public DoubleLinkedTreeIterator(DoubleLinkedTreeNode startNode) {
00172         nextNode = startNode;
00173         nodesOnRight = new Stack();
00174     }
00175 
00176     public boolean hasNext() {
00177         return (nextNode != null);
00178     }
00179 
00180     public Object next() {
00181         assert(hasNext());
00182         
00183         Object result = nextNode;
00184 
00185         List children = nextNode.getChildren();
00186         if (children.size() == 0) {  // no children? Take node on top of stack, if stack not empty
00187             if (nodesOnRight.empty()) nextNode = null;
00188             else nextNode = (DoubleLinkedTreeNode)nodesOnRight.pop();
00189         
00190         } else {  // there are children: the next node is the topleft child, the children on right are pushed on stack
00191             DoubleLinkedTreeNode firstChild = (DoubleLinkedTreeNode)children.get(0);
00192             nextNode = firstChild;
00193 
00194             for (int iChildren = 1; iChildren < children.size(); ++iChildren) {
00195                 Object childOnRight = children.get(iChildren);
00196                 nodesOnRight.push(childOnRight);
00197             }
00198         }
00199 
00200         return result;
00201     }
00202     
00203     public void remove() {
00204         throw new UnsupportedOperationException("DoubleLinkedTreeIterator does not provide a \"remove()\" method.");
00205     }
00206     
00207 }


tug_ist_diagnosis_engine
Author(s): Safdar Zaman, Gerald Steinbauer
autogenerated on Mon Jan 6 2014 11:51:16