这肯定是一个老掉牙的问题了,但我没找到满意的答案。假设一颗树,原来只有叶节点包含数值,如下面的节点N111,N112,N121和N21。
[code]ROOT
|-- N1
|-- N11
|-- N111(30)
|-- N112(10)
|-- N12
|-- N121(10)
|-- N2
|-- N21(30)[/code]
现在要逐级地把下级节点中的数值累加到它们父节点中,直至根节点,即最终的结果如下所示,
[code]ROOT(80)
|-- N1(50)
|-- N11(40)
|-- N111(30)
|-- N112(10)
|-- N12(10)
|-- N121(10)
|-- N2(30)
|-- N21(30)[/code]
目前我使用递归算法解决上述问题,但希望能够使用迭代算法,可不清楚如何进行转换:(
[code]ROOT
|-- N1
|-- N11
|-- N111(30)
|-- N112(10)
|-- N12
|-- N121(10)
|-- N2
|-- N21(30)[/code]
现在要逐级地把下级节点中的数值累加到它们父节点中,直至根节点,即最终的结果如下所示,
[code]ROOT(80)
|-- N1(50)
|-- N11(40)
|-- N111(30)
|-- N112(10)
|-- N12(10)
|-- N121(10)
|-- N2(30)
|-- N21(30)[/code]
目前我使用递归算法解决上述问题,但希望能够使用迭代算法,可不清楚如何进行转换:(
ROOT
|-- N1
|-- N11
|-- N111(30)
|-- N112(10)
|-- N12
|-- N121(10)
|-- N2
|-- N21(30)
现在要逐级地把下级节点中的数值累加到它们父节点中,直至根节点,即最终的结果如下所示,
ROOT(80)
|-- N1(50)
|-- N11(40)
|-- N111(30)
|-- N112(10)
|-- N12(10)
|-- N121(10)
|-- N2(30)
|-- N21(30)
目前我使用递归算法解决上述问题,但希望能够使用迭代算法,可不清楚如何进行转换:(
public class TreeNode {
public TreeNode(int value, TreeNode left, TreeNode right) {
this.value = value;
this.left = left;
this.right = right;
}
public int value;
public TreeNode left;
public TreeNode right;
}
//可以直接运行的例子
import java.util.Stack;public class Main { /**
* @param args
*/
public static void main(String[] args) {
new Main().go();
} public void go() {
TreeNode tree = initTree();
doLevelSum(tree);
System.out.println(tree.value);
}
//根据楼主的例子,初始化一棵树
public TreeNode initTree() {
TreeNode n111 = new TreeNode(30, null, null);
TreeNode n112 = new TreeNode(10, null, null);
TreeNode n11 = new TreeNode(0, n111, n112);
TreeNode n121 = new TreeNode(10, null, null);
TreeNode n12 = new TreeNode(0, n121, null);
TreeNode n1 = new TreeNode(0, n11, n12);
TreeNode n21 = new TreeNode(30, null, null);
TreeNode n2 = new TreeNode(0, n21, null);
TreeNode root = new TreeNode(0, n1, n2);
return root;
}
//逐级求和,用迭代
public void doLevelSum(TreeNode tree) {
Stack<TreeNode> stack = new Stack<TreeNode>();
stack.push(tree);
TreeNode node;
int a, b;
while(!stack.empty()) {
node = stack.peek();
if((node.left != null && node.left.value==0) || (node.right != null && node.right.value==0)) {
if(node.left != null && node.left.value==0)
stack.push(node.left);
if(node.right != null && node.right.value==0)
stack.push(node.right);
}else {
a = b = 0;
if(node.left != null)
a = node.left.value;
if(node.right != null)
b = node.right.value;
node.value = a + b;
stack.pop();
} }
}
}
我的树节点定义类似于
TreeNode {
private TreeNode parent = null;
private List<TreeNode> children = new ArrayList<TreeNode>(); // 可以有任意数量的子节点。 private Object value = null; ...
}
node--结点
lv--该结点左边的兄弟们结点值之和
flag: false--表示准备通过儿子们结点来求值
true--表示已经可以求出该结点值了
public void treeSum(TreeNode r)
{
int ss=0;//目前为止,儿子们结点值之和
if(r==null||r是叶子)return;
将树根r结点的三元组(r,0,true)进栈.[注意是:true]
将树根r的所有的儿子们结点从右向左依次进栈,三元组是(son,0,false)[注意是:false]
while(栈不空)
{
出栈=>三元组(node,lv,flag);
if(node是叶子){ss=ss+node.value;continue;}
//此时:node肯定不是叶子了
if(flag==false)//必须要通过儿子们来求值
{
将node再次进栈,三元组是(node,ss,true);
将node的所有的儿子们结点从右向左依次进栈,三元组是(son,0,false)[注意是:false]
ss=0;//开始计算node的儿子们值之和
}
else
{//表示儿子们之和已求出.放在ss中,可以对结点求值了
node.value=ss;
ss=ss+lv;//将node的儿子们之和 加上 node的兄弟们之和,作为新的node的父结点的目前的儿子们的和
}//if
}//while
}