Back to project page Cafe.
The source code is released under:
Apache License
If you think the Android project Cafe listed in this page is inappropriate, such as containing malicious code/tools or violating the copyright, please email info at java2s dot com, thanks.
/* * Copyright (C) 2011 Baidu.com Inc/*from www . j av a 2 s. c om*/ * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.baidu.cafe.utils; import java.util.ArrayList; import java.util.LinkedList; import java.util.Queue; /* import org.dom4j.Document; import org.dom4j.DocumentException; import org.dom4j.Element; import org.dom4j.io.SAXReader; */ /** * a muti-node tree is not thread-safe * * @author luxiaoyu01@baidu.com * @date 2011-5-13 * @version * @todo */ public class TreeNode<T> { public static String vertical = null; public static String horizontal = null; public static String big_horizontal = null; public static String vertical_T = null; public static String horizontal_T = null; public static String left = null; private T data = null; private int index = -1; private TreeNode<T> parent = null; private ArrayList<TreeNode<T>> children = null; // load string to avoid to compile unicode static { // try { // Document doc = new SAXReader().read(new FileInputStream(new File("res/strings.xml"))); // Element rootElement = doc.getRootElement(); // List<Element> strings = rootElement.elements("string"); // vertical = strings.get(0).getStringValue(); // horizontal = strings.get(1).getStringValue(); // big_horizontal = strings.get(2).getStringValue(); // vertical_T = strings.get(3).getStringValue(); // horizontal_T = strings.get(4).getStringValue(); // left = strings.get(5).getStringValue(); // } catch (FileNotFoundException e) { vertical = "|"; horizontal = "-"; big_horizontal = "--"; vertical_T = "T"; horizontal_T = "|-"; left = "'-"; //e.printStackTrace(); // } catch (DocumentException e) { // e.printStackTrace(); // } } @Override public String toString() { return data.toString(); } public TreeNode(T data) { this.data = data; this.children = new ArrayList<TreeNode<T>>(); } public T getData() { return data; } public void setData(T data) { this.data = data; } public int getIndex() { return index; } public TreeNode<T> getParent() { return parent; } public ArrayList<TreeNode<T>> getBrothers() { ArrayList<TreeNode<T>> brothers = new ArrayList<TreeNode<T>>(); if (parent != null) { for (TreeNode<T> child : parent.getChildren()) { if (!child.equals(this)) { brothers.add(child); } } } return brothers; } public ArrayList<TreeNode<T>> getChildren() { return children; } public void addChild(TreeNode<T> child) { child.index = children.size(); children.add(child); child.parent = this; } public void addChildren(ArrayList<TreeNode<T>> children) { for (TreeNode<T> child : children) { addChild(child); } } public void removeChild(TreeNode<T> node) { int childrenSize = children.size(); for (int i = 0; i < childrenSize; i++) { if (children.get(i) == node) { children.remove(i); } } } private void insertFrontWhitespace(TreeNode<T> root, TreeNode<T> node, StringBuffer sb) { int number = 2 + node.parent.data.toString().length(); for (int i = 0; i < number; i++) { sb.append(" "); } if (node.parent == root) { return; } sb.append(vertical); insertFrontWhitespace(root, node.parent, sb); } private void drawFamily(StringBuffer sb, TreeNode<T> root) { int childrenSize = children.size(); // draw itself sb.append(horizontal + data); if (childrenSize == 0) { sb.append("\n"); return; } // draw the first child if (childrenSize == 1) { sb.append(big_horizontal); } else { sb.append(vertical_T); } children.get(0).drawFamily(sb, root); // draw middle children int i = 1; for (; i < childrenSize - 1; i++) { StringBuffer t = new StringBuffer(); insertFrontWhitespace(root, children.get(i), t); sb.append(t.reverse()); sb.append(horizontal_T); children.get(i).drawFamily(sb, root); } // draw the last child if (childrenSize > 1) { StringBuffer t = new StringBuffer(); insertFrontWhitespace(root, children.get(i), t); sb.append(t.reverse()); sb.append(left); children.get(i).drawFamily(sb, root); } } public String drawTree() { StringBuffer sb = new StringBuffer(1024 * 10); drawFamily(sb, this); return sb.toString(); } public interface NodeCallBack<T> { void doSomething(TreeNode<T> node, int depth); boolean shouldRepeat(TreeNode<T> node); void doWhenCompleted(TreeNode<T> node, int depth); boolean shouldStop(TreeNode<T> node); } /** * travel the tree with preorder and do something at every tree node * * @param callBack * @param maxDepth * the depth of root is 1 * @return should continue */ public boolean preorderTraversal(NodeCallBack<T> callBack, int maxDepth) { if (callBack.shouldStop(this)) { return false; } callBack.doSomething(this, maxDepth); if (maxDepth > 0) { for (int i = 0; i < children.size(); i++) { TreeNode<T> child = children.get(i); if (!child.preorderTraversal(callBack, maxDepth - 1)) { return false; } if (callBack.shouldRepeat(this)) { //Logger.println("Repeat: " + this.data.toString()); callBack.doSomething(this, maxDepth); } } } callBack.doWhenCompleted(this, maxDepth); return true; } public void breadthFirstTraversal(NodeCallBack<T> callBack, int maxDepth) { Queue<TreeNode<T>> queue = new LinkedList<TreeNode<T>>(); queue.offer(this); while (queue.size() != 0) { TreeNode<T> head = queue.poll(); if (countDistance(head, this) > maxDepth - 1) { break; } callBack.doSomething(head, maxDepth); for (int i = 0; i < head.children.size(); i++) { queue.offer(head.children.get(i)); } // printQueue(queue); } } private int countDistance(final TreeNode<T> child, TreeNode<T> ancestor) { int distance = 0; TreeNode<T> node = child; while (node != ancestor) { node = node.getParent(); distance++; } return distance; } private void printQueue(Queue<TreeNode<T>> queue) { // System.out.println("******************* print queue *********************"); for (TreeNode<T> node : queue) { System.out.println(node); } } public static void main(String[] args) { // Map map = new HashMap(); // Iterator iter = map.entrySet().iterator(); // while (iter.hasNext()) { // Entry entry = (Entry) iter.next(); // Object key = entry.getKey(); // Object val = entry.getValue(); // } TreeNode<String> root = new TreeNode<String>("0"); TreeNode<String> node1 = new TreeNode<String>("1"); TreeNode<String> node2 = new TreeNode<String>("22"); TreeNode<String> node3 = new TreeNode<String>("333"); TreeNode<String> node4 = new TreeNode<String>("4444"); TreeNode<String> node5 = new TreeNode<String>("55555"); TreeNode<String> node6 = new TreeNode<String>("666666"); TreeNode<String> node7 = new TreeNode<String>("7777777"); TreeNode<String> node8 = new TreeNode<String>("88888888"); TreeNode<String> node9 = new TreeNode<String>("999999999"); root.addChild(node1); root.addChild(node2); root.addChild(node7); node1.addChild(node3); node1.addChild(node4); node2.addChild(node5); node2.addChild(node6); node4.addChild(node8); // test draw tree System.out.println(root.drawTree()); System.out.println(node1.drawTree()); System.out.println(node4.drawTree()); System.out.println(node7.drawTree()); System.out.println("test remove child"); node1.removeChild(node4); System.out.println(root.drawTree()); System.out.println("test preorderTraversal"); node1.addChild(node4); node8.addChild(node9); System.out.println(root.drawTree()); root.preorderTraversal(new NodeCallBack<String>() { @Override public void doSomething(TreeNode<String> node, int maxDepth) { System.out.print(node.getData() + "(" + (3 - maxDepth) + "), "); } @Override public void doWhenCompleted(TreeNode<String> node, int maxDepth) { } @Override public boolean shouldRepeat(TreeNode<String> node) { return false; } @Override public boolean shouldStop(TreeNode<String> node) { return "55555".equals(node.getData()); } }, 3); System.out.println(""); System.out.println("test getBrothers"); ArrayList<TreeNode<String>> brothers = node1.getBrothers(); for (TreeNode<String> brother : brothers) { System.out.print(brother.getData() + ", "); } System.out.println(""); System.out.println("test breadthFirstTraversal"); System.out.println(root.drawTree()); root.breadthFirstTraversal(new NodeCallBack<String>() { @Override public boolean shouldRepeat(TreeNode<String> node) { return false; } @Override public void doSomething(TreeNode<String> node, int maxDepth) { System.out.print(node.getData() + ", "); } @Override public void doWhenCompleted(TreeNode<String> node, int depth) { } @Override public boolean shouldStop(TreeNode<String> node) { return false; } }, 2); System.out.println(""); } }