成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

樹(shù)的匯總 用遞歸與和迭代來(lái)實(shí)現(xiàn)

開(kāi)發(fā) 后端
樹(shù)的匯總是指將樹(shù)中某節(jié)點(diǎn)的數(shù)據(jù)按指定的匯集到它的父節(jié)點(diǎn)中。例 如,可以將樹(shù)節(jié)點(diǎn)中的數(shù)值累加到它的父節(jié)點(diǎn)中。本文將使用兩種簡(jiǎn)單的算法,遞歸與和迭代,來(lái)實(shí)現(xiàn)這一功能。

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

1. 樹(shù)節(jié)點(diǎn)

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

  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. 遞歸法

仍然先從最簡(jiǎn)單的遞歸法開(kāi)始,

  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.  

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

3. 迭代法

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

  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. }  

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

  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é)點(diǎn)中的數(shù)值,而不管分枝節(jié)點(diǎn)和根節(jié)點(diǎn)本身所擁有的數(shù)值。如果要累加這些節(jié)點(diǎn)本身的數(shù)值,應(yīng)該如何做呢?大家自己做做看吧, 肯定非常簡(jiǎn)單 ^_^

4. 小結(jié)

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

【編輯推薦】

  1. 關(guān)于Java垃圾回收問(wèn)題
  2. Java連接MySQL中文亂碼處理
  3. 在Java應(yīng)用程序中使用Jfreechart配置
  4. 淺談Java線程的生命周期
  5. 關(guān)于Java繼承的一些復(fù)習(xí)
責(zé)任編輯:yangsai 來(lái)源: BlogJava
相關(guān)推薦

2011-06-28 15:47:13

Qt 信號(hào)

2021-09-15 07:40:50

二叉樹(shù)數(shù)據(jù)結(jié)構(gòu)算法

2020-05-27 11:10:54

KerasLSTM神經(jīng)網(wǎng)絡(luò)

2010-04-02 15:04:14

Oracle遞歸查詢(xún)

2009-09-03 10:52:41

C#遞歸樹(shù)

2022-01-26 07:25:09

PythonRSA加解密

2022-09-14 15:24:57

typescript快排

2024-04-19 13:55:36

python小迭代遞歸

2021-11-28 08:03:41

Python迭代器對(duì)象

2010-08-31 09:57:33

DHCP Relay

2010-08-09 13:37:09

FlexDjango

2016-03-28 10:39:05

Python迭代迭代器

2009-07-20 17:41:59

Java JDBC

2020-12-24 10:00:12

PythonPython基礎(chǔ)阿姆斯特朗數(shù)

2012-09-24 13:49:13

HTML5CanvasJS

2010-05-24 14:24:27

MySQL查詢(xún)

2020-08-25 07:00:00

容器微服務(wù)技術(shù)

2023-05-11 07:38:51

2017-08-02 07:36:06

大數(shù)據(jù)PythonOpenCV

2025-03-10 09:20:00

點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)

主站蜘蛛池模板: 亚洲午夜av久久乱码 | 日韩精品一区二区三区 | 日韩视频专区 | 在线观看国产 | 亚洲嫩草 | 涩涩导航 | 免费欧美 | 99精品热视频 | 成人精品一区 | 久久久资源| 国产最新网址 | 国产三级精品三级在线观看四季网 | 91免费版在线 | 久久精品视频网站 | 午夜视频在线 | 欧美日本亚洲 | 亚洲在线一区二区 | 久久综合狠狠综合久久综合88 | 一级毛片黄片 | 国产在线视频在线观看 | 国产精品久久国产精品 | 国产一区二区精品在线 | 99久久精品一区二区成人 | 欧美中文字幕一区二区三区亚洲 | 日本午夜精品一区二区三区 | 成人高清在线 | 亚洲成人精品视频 | 成人黄在线观看 | 国产在线观看免费 | 日韩精彩视频 | 欧美日韩免费一区二区三区 | 欧美成年人视频在线观看 | 欧美视频免费在线 | 中文字幕在线精品 | 欧美一区二区三区在线 | 午夜不卡福利视频 | 黄色免费网站在线看 | 国内精品久久久久久影视8 最新黄色在线观看 | 日韩免费视频一区二区 | 精品一区欧美 | 亚洲精品久久久久久宅男 |