<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    John Jiang

    a cup of Java, cheers!
    https://github.com/johnshajiang/blog

       :: 首頁 ::  :: 聯系 :: 聚合  :: 管理 ::
      131 隨筆 :: 1 文章 :: 530 評論 :: 0 Trackbacks
    樹的匯總
    繼上次淺談了樹的遍歷之后,這次再淺談一下樹的匯總。此處的匯總是指將樹中某個節點的數據按指定的規則匯集到它的父節點中。例如,可以將樹節點中的數值累加到它的父節點中。仍如樹的遍歷一文,我將使用兩種簡單的算法,遞歸與和迭代,來實現這一功能。(2009.08.09最后更新)

    1. 樹節點
    仍然沿用樹的遍歷一文中的TreeNode/GenericTreeNode,為便于閱讀,將GenericTreeNode中的若干關鍵屬性展示如下,
    public class GenericTreeNode<T> implements TreeNode {

        
    private T userObject = null;

        
    private TreeNode parent = null;

        
    private List<GenericTreeNode<T>> children = new ArrayList<GenericTreeNode<T>>();

        
    }

    2. 遞歸法
    仍然先從最簡單的遞歸法開始,
    public static Double recursiveGatherValue(GenericTreeNode<Double> node) {
        Double sumValue 
    = null;
        
    if (node.isLeaf()) {
            
    return node.getUserObject();
        } 
    else {
            sumValue 
    = node.getUserObject();
            List
    <GenericTreeNode<Double>> children = node.getChildren();
            
    for (int i = 0, size = children.size(); i < size; i++) {
                Double bufGatherValue 
    = recursiveGatherValue(children.get(i));
                sumValue 
    += bufGatherValue;
            }
        }

        node.setUserObject(sumValue);
        
    return sumValue;
    }
    遞歸法還是一如既往的簡單易懂。與遞歸遍歷樹相比,遞歸匯總樹的程序基本上沒大的變化,我就不贅述了...

    3. 迭代法
    與迭代遍歷樹相比,迭代匯總樹的程序有一些明顯的變化。當初在思考迭代法時,有個問題一直困繞著我:如何將下級節點的值賦給它的父節點,并且父節點的值要不斷的進行累加。在JavaWorld@TW中提出這個問題之后,很快就得到了清晰的解答(真的很感謝社區里的大大們)。毫無疑問,用迭代法遍歷一棵樹時需要使用一個棧,但同時,為了維護節點與匯總值之間的關系,還需要另一個棧進行輔助。具體程序如下所示,
    public static void iterativeGatherValue(GenericTreeNode<Double> node) {
        Stack
    <NodeValueTuple<Double>> nodeValueStack = new Stack<NodeValueTuple<Double>>();
        Stack
    <GenericTreeNode<Double>> nodeStack = new Stack<GenericTreeNode<Double>>();

        nodeStack.push(node);
        Double sumValue 
    = new Double(0.0D);
        
    while (!nodeStack.isEmpty()) {
            GenericTreeNode
    <Double> bufNode = nodeStack.pop();
            
    if (bufNode == null) {
                NodeValueTuple
    <Double> bufNodeValueTuple = nodeValueStack.pop();
            bufNodeValueTuple.node.setUserObject(sumValue);

            sumValue += bufNodeValueTuple.value;
            } 
    else if (bufNode.isLeaf()) {
                sumValue 
    += bufNode.getUserObject();
            } 
    else {
                nodeValueStack.add(
    new NodeValueTuple<Double>(bufNode, sumValue));

                sumValue 
    = new Double(0.0D);
                nodeStack.push(
    null);
                nodeStack.addAll(bufNode.getChildren());
            }
        }
    }
    在遍歷樹的過程中,會將某節點N與它的匯總值一同置入一個棧(nodeValueStack)中,當節點N有子節點時,則將它的子節點及其匯總值也置入棧中,節點N與它的子節點之間使用一個NULL值進行分隔;如果節點N是葉節點則累加匯總值;如果節點N為NULL,則表示子節點們的匯總已結束。
    NodeValueTuple是一個二元組,用于維護節點與它的匯總值之間的關系,代碼如下所示,
    public class NodeValueTuple<V> {

        
    public final GenericTreeNode<V> node;
        
    public final V value;

        
    public NodeValueTuple(GenericTreeNode<V> node, V value) {
            
    this.node = node;
            
    this.value = value;
        }
    }
    在上述的匯總中,均只累加了葉節點中的數值,而不管分枝節點和根節點本身所擁有的數值。如果要累加這些節點本身的數值,應該如何做呢?大家自己做做看吧,肯定非常簡單 ^_^

    4. 小結
    樹的匯總肯定是一個十分常見的應用,除了匯總數據之外,我們還可以匯集節點中的對象,如匯總掛載在節點上的集合對象中的元素,使得父節點能夠擁有所有子節點所擁有的元素。上述方法的效率應該不算低,主要是因為所有的樹節點只需要訪問一次。

    posted on 2009-06-26 07:11 John Jiang 閱讀(1884) 評論(0)  編輯  收藏 所屬分類: JavaAlgorithm原創
    主站蜘蛛池模板: 在线亚洲97se亚洲综合在线| 99久久免费精品视频| 亚洲色大成网站www永久网站| 亚洲国产精品日韩在线| 亚洲精品乱码久久久久久下载 | 香蕉免费一级视频在线观看| 三上悠亚在线观看免费| 最近免费中文在线视频| 日本免费一区二区三区最新| 免费一级一片一毛片| 久久精品国产亚洲AV麻豆王友容 | 免费人成大片在线观看播放| 成人一级免费视频| 国产成人免费网站| 亚洲精品国产美女久久久| 中文无码亚洲精品字幕| 国产啪精品视频网站免费尤物 | 日韩一级在线播放免费观看| 亚洲综合成人婷婷五月网址| 韩国日本好看电影免费看| 亚洲动漫精品无码av天堂| 国产综合成人亚洲区| 8x网站免费入口在线观看| 最好免费观看韩国+日本| 久久无码av亚洲精品色午夜| 污污网站18禁在线永久免费观看| 免费在线一级毛片| 在线免费观看h片| 婷婷亚洲天堂影院| 亚洲an日韩专区在线| 久久国产乱子伦精品免费强| 又色又污又黄无遮挡的免费视| 一区二区三区视频免费观看| 国产一精品一AV一免费孕妇| 亚洲美女aⅴ久久久91| 久久国产一片免费观看| 亚洲欧洲日产国码二区首页| 日本免费福利视频| 182tv免费视频在线观看| 亚洲综合激情五月丁香六月| 亚洲人成精品久久久久|