日本综合一区二区|亚洲中文天堂综合|日韩欧美自拍一区|男女精品天堂一区|欧美自拍第6页亚洲成人精品一区|亚洲黄色天堂一区二区成人|超碰91偷拍第一页|日韩av夜夜嗨中文字幕|久久蜜综合视频官网|精美人妻一区二区三区

RELATEED CONSULTING
相關咨詢
選擇下列產(chǎn)品馬上在線溝通
服務時間:8:30-17:00
你可能遇到了下面的問題
關閉右側工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營銷解決方案
樹的匯總用遞歸與和迭代來實現(xiàn)

繼上次淺談了樹的遍歷之后,這次再淺談一下樹的匯總。此處樹的匯總是指將樹中某節(jié)點的數(shù)據(jù)按指定的匯集到它的父節(jié)點中。例 如,可以將樹節(jié)點中的數(shù)值累加到它的父節(jié)點中。仍如樹的遍歷一文,我將使用兩種簡單的算法,遞歸與和迭代,來實現(xiàn)這一功能。

創(chuàng)新互聯(lián)建站專業(yè)為企業(yè)提供蓮花網(wǎng)站建設、蓮花做網(wǎng)站、蓮花網(wǎng)站設計、蓮花網(wǎng)站制作等企業(yè)網(wǎng)站建設、網(wǎng)頁設計與制作、蓮花企業(yè)網(wǎng)站模板建站服務,十多年蓮花做網(wǎng)站經(jīng)驗,不只是建網(wǎng)站,更提供有價值的思路和整體網(wǎng)絡服務。

1. 樹節(jié)點

仍然沿用樹的遍歷一文中的TreeNode/GenericTreeNode,為便于閱讀,將GenericTreeNode中的若干關鍵屬性展示如下,

 
 
 
  1. public class GenericTreeNode< T> implements TreeNode {  
  2.  
  3.     private T userObject = null;  
  4.  
  5.     private TreeNode parent = null;  
  6.  
  7.     private List< GenericTreeNode< T>> children = new ArrayList< GenericTreeNode< T>>();  
  8.  
  9.       
  10. }  

2. 遞歸法

仍然先從最簡單的遞歸法開始,

 
 
 
  1. public static Double recursiveGatherValue(GenericTreeNode< Double> node) {  
  2.     Double sumValue = null;  
  3.     if (node.isLeaf()) {  
  4.         return node.getUserObject();  
  5.     } else {  
  6.         sumValue = node.getUserObject();  
  7.         List< GenericTreeNode< Double>> children = node.getChildren();  
  8.         for (int i = 0, size = children.size(); i <  size; i++) {  
  9.             Double bufGatherValue = recursiveGatherValue(children.get(i));  
  10.             sumValue += bufGatherValue;  
  11.         }  
  12.     }  
  13.  
  14.     node.setUserObject(sumValue);  
  15.     return sumValue;  
  16. }  
  17.  

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

3. 迭代法

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

 
 
 
  1. public static void iterativeGatherValue(GenericTreeNode< Double> node) {  
  2.     Stack< NodeValueTuple< Double>> nodeValueStack = new Stack< NodeValueTuple< Double>>();  
  3.     Stack< GenericTreeNode< Double>> nodeStack = new Stack< GenericTreeNode< Double>>();  
  4.  
  5.     nodeStack.push(node);  
  6.     Double sumValue = new Double(0.0D);  
  7.     while (!nodeStack.isEmpty()) {  
  8.         GenericTreeNode< Double> bufNode = nodeStack.pop();  
  9.         if (bufNode == null) {  
  10.             NodeValueTuple< Double> bufNodeValueTuple = nodeValueStack.pop();  
  11.         bufNodeValueTuple.node.setUserObject(sumValue);  
  12.  
  13.         Double bufValue = bufNodeValueTuple.node.getUserObject();  
  14.             sumValue += bufValue;  
  15.         } else if (bufNode.isLeaf()) {  
  16.             sumValue += bufNode.getUserObject();  
  17.         } else {  
  18.             nodeValueStack.add(new NodeValueTuple< Double>(bufNode, sumValue));  
  19.  
  20.             sumValue = new Double(0.0D);  
  21.             nodeStack.push(null);  
  22.             nodeStack.addAll(bufNode.getChildren());  
  23.         }  
  24.     }  
  25. }  

在遍歷樹的過程中,會將某節(jié)點N與它的匯總值一同置入一個棧(nodeValueStack)中,當節(jié)點N有子節(jié)點時,則將它的子節(jié)點及其匯總值也置入棧 中,節(jié)點N與它的子節(jié)點之間使用一個NULL值進行分隔;如果節(jié)點N是葉節(jié)點則累加匯總值;如果節(jié)點N為NULL,則表示子節(jié)點們的匯總已結束,
NodeValueTuple是一個二元組,用于維護節(jié)點與它的匯總值之間的關系,代碼如下所示,

 
 
 
  1. public class NodeValueTuple< V> {  
  2.  
  3.     public final GenericTreeNode< V> node;  
  4.     public final V value;  
  5.  
  6.     public NodeValueTuple(GenericTreeNode< V> node, V value) {  
  7.         this.node = node;  
  8.         this.value = value;  
  9.     }  
  10. }  

在上述的匯總中,均只累加了葉節(jié)點中的數(shù)值,而不管分枝節(jié)點和根節(jié)點本身所擁有的數(shù)值。如果要累加這些節(jié)點本身的數(shù)值,應該如何做呢?大家自己做做看吧, 肯定非常簡單 ^_^

4. 小結

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


網(wǎng)頁題目:樹的匯總用遞歸與和迭代來實現(xiàn)
本文來源:http://www.dlmjj.cn/article/dppeoee.html