| 註冊 | 登入 | 全文檢索 | 排行榜 |
|
» JavaWorld@TW
» Java 新手區
» 演算法
|
![]() ![]() ![]()
|
| 本主題所含的標籤 |
| 作者 | Re:树的逐级求和? [Re:jiangshachina] | ||
jiangshachina
Hi, Java! ![]() ![]() ![]() ![]()
發文: 527 積分: 1 |
此处树的构造是基于一种常用的结构:
对于我的问题,我有另一种思路: 因为在初始时,只有leaf上才有数值,那么root或branch的数值,就是root或branch下属所有leaf的数值之和。 如,ROOT=N111+N112+N121+N21=80;N1=N111+N112+N121=50;N12=N121=10;... 所以,如果知道了所有的leaf,则可以从leaf出发,由下向上遍历,将该leaf的数值依次赋给(加法)它的parent,grandparent,...,直至root。这可由一个两层嵌套循环实现。 但如何得到所有的leaf呢?这恐怕要先遍历一次树 ![]() 所以,我的这一思路最终需要遍历树两次,显然也不太好。 a cup of Java, cheers! 同是Java爱好者,相逢何必曾相识! |
| 作者 | Re:树的逐级求和? [Re:jiangshachina] | ||||
Duncan
街友 JaJa 版主
發文: 7594 積分: 39 |
jiangshachina wrote: 為何考慮將 recursion 作法改成 iteration 呢? 這個問題還得考量你對 iteration 作法的定義為何。 假如你一開始只獲得 tree 的 root node,那麼你要從 root node 取得所有的 tree nodes,這個過程本身可以說是 recursion 的作法,即使你之後求和是 iteration 過程,這樣子整體來說就不算是 iteration 的演算法。 給我 貓咪 其餘免談 我要效法葛屁老師,我承認了,我是蘿莉控。 |
| 作者 | Re:树的逐级求和? [Re:jiangshachina] |
jiangshachina
Hi, Java! ![]() ![]() ![]() ![]()
發文: 527 積分: 1 |
假如你一開始只獲得 tree 的 root node,那麼你要從 root node 取得所有的 tree nodes,這個過程本身可以說是 recursion 的作法我一开始确实只有root。 但仅就遍历树而言,也是可以分递归和非递归算法吧。 即使你之後求和是 iteration 過程,這樣子整體來說就不算是 iteration 的演算法求和本身是很简单的,关键是如何找到各个node(包含branch和leaf),然后将leaf中的值依次传给branch和root。 一般地,递归算法不是都可以转化为迭代算法吗? a cup of Java, cheers! 同是Java爱好者,相逢何必曾相识! |
| 作者 | Re:树的逐级求和? [Re:jiangshachina] |
jiangshachina
Hi, Java! ![]() ![]() ![]() ![]()
發文: 527 積分: 1 |
其实我只是想显示地使用runtime stack来执行recursion罢了。 a cup of Java, cheers! 同是Java爱好者,相逢何必曾相识! |
| 作者 | Re:树的逐级求和? [Re:jiangshachina] | ||
Duncan
街友 JaJa 版主
發文: 7594 積分: 39 |
jiangshachina wrote: 如果你要的是這種以 stack 來模仿 recursion 的作法,這有標準的作法。 1. 把每次 recursive method 內的所有操作,扣除掉 recursive method call 的部分改成 iteration 去完成。 2. 分析一下,recursive method call 回返時,需要哪些數據用已繼續完成 calling method 未完成的操作。 可以使用兩個 stack 來分別用以紀錄 recursive call 時的狀態,以及待完成的操作。 以你提到的這個例子來說,遞迴的作法是在求和時,如果遇到 non-leaf node 則進行 recursive method call,當 method return subtree 的和後,把此和存入 non-leaf node 裡,並繼續與之前位於同一深度的其他 nodes 的累積值作累加。這樣子在使用 stack 模擬 recursive method call 時所要保存的只有兩個:一是累積值,二是下一深度的總和要存到哪個 node。 概略地說,把原本 recursive 方式求和作法可以改成以下幾個流程: 1. 求一個 non-leaf node 的值就是先放一個結束標記到 node stack 裡,再把此 node 的所有 child nodes 一一放入 2. 將 node stack 裡的 node 一一取出來累加 2a. 累加時如果遇到 non-leaf node,就先把已累加的值與此 non-leaf node 存入 state stack,累加值歸零,再進行步驟 1 2b. 累加時如果遇到空 node(null),則把新累加值存進 state stack 最頂端所記錄的 node,把新累加值類加進 state stack 最頂端所記錄的累加值 3. node stack 為空時,則累加完畢。 底下是簡單的 demo code:
TreeNode.java (0.89k)
給我 貓咪 其餘免談 我要效法葛屁老師,我承認了,我是蘿莉控。 |
| 作者 | Re:树的逐级求和? [Re:jiangshachina] |
jiangshachina
Hi, Java! ![]() ![]() ![]() ![]()
發文: 527 積分: 1 |
非常感谢 ![]() 一定仔细研究... 再提个问题: 既然系统在执行recursion时,会隐式地使用stack,那么是否可以认为,我们自己显示地使用stack去执行recursion并不会改善程序的性能? a cup of Java, cheers! 同是Java爱好者,相逢何必曾相识! |
| 作者 | Re:树的逐级求和? [Re:jiangshachina] |
Duncan
街友 JaJa 版主
發文: 7594 積分: 39 |
jiangshachina wrote: 改成這種方式的確是不會改善效率,通常還會變差,特別是越高階的程式語言,在操作 stack 時的 overhead 會比 recursive method call + 傳遞 argument 的 overhead 還來得大。 通常會想把 recursive 演算改成這種以 stack 為主的 iteration 演算,主要會是在於避開 runtime 所提供的 stack size 在 recursive method call 深度太深時不夠用的情況。 給我 貓咪 其餘免談 我要效法葛屁老師,我承認了,我是蘿莉控。 |
| » JavaWorld@TW » Java 新手區 » 演算法 |
![]() ![]() ![]()
|
已讀文章 新的文章 被刪除的文章 |