Algorithm 用迭代法计算最大相互独立节点集
我们从一棵n元树开始。每个分支表示“依赖性”(即父级依赖于子级)。我需要找到相互独立的节点的最大和 递归解决方案相当简单:Algorithm 用迭代法计算最大相互独立节点集,algorithm,graph-algorithm,Algorithm,Graph Algorithm,我们从一棵n元树开始。每个分支表示“依赖性”(即父级依赖于子级)。我需要找到相互独立的节点的最大和 递归解决方案相当简单: int calc_max() { int child_max = 0; foreach (var n in nodes) { child_max += n.calc_max(); } return Math.Max(this.value, child_max); } 现在我很难为这个问题提供非递归的解决方案。这将需
int calc_max()
{
int child_max = 0;
foreach (var n in nodes)
{
child_max += n.calc_max();
}
return Math.Max(this.value, child_max);
}
现在我很难为这个问题提供非递归的解决方案。这将需要后序遍历。二叉树的迭代后序已经得到了回答。但即使有了这个解决方案,我也无法从这个解决方案中移除递归 我有一些答案,说明如何将算法的任何递归表达式转换为非递归表达式 让我们再来一次 我将使用C,因为它更清晰:
int calc_max(NODE *node) {
int child_sum = 0;
for (int i = 0; i < node->n_children; ++i)
child_sum += calc_max(node->children[i]);
return MAX(node->value, child_sum);
}
需要保存的参数和局部变量是节点
、i
和子项和
。所以我们可以填写伪代码
typedef struct node {
struct node *children[8];
int n_children, value;
} NODE;
#define MAX(A, B) ((A) > (B) ? A : B)
int calc_max(NODE *node) {
int i, child_sum, rtn_val, sp = 0;
struct stack_frame {
NODE *node;
int i, child_sum;
} stk[1000];
start:
child_sum = 0;
for (i = 0; i < node->n_children; ++i) {
stk[sp++] = (struct stack_frame){.node = node, .i = i, .child_sum = child_sum};
node = node->children[i];
goto start;
rtn:
child_sum += rtn_val;
}
rtn_val = MAX(node->value, child_sum);
if (sp > 0) {
--sp;
node = stk[sp].node;
i = stk[sp].i;
child_sum = stk[sp].child_sum;
goto rtn;
}
return rtn_val;
}
现在,通过复制i=child\u sum=0
我们可以将goto start
的目标移动到rtn
int calc_max(NODE *node) {
int i, child_sum, rtn_val, sp = 0;
struct stack_frame {
NODE *node;
int i, child_sum;
} stk[1000];
i = child_sum = 0;
rtn:
while (i < node->n_children) {
stk[sp++] = (struct stack_frame){.node = node, .i = i, .child_sum = child_sum};
node = node->children[i];
i = child_sum = 0;
goto rtn;
}
rtn_val = MAX(node->value, child_sum);
if (sp > 0) {
--sp;
node = stk[sp].node;
i = stk[sp].i;
child_sum = stk[sp].child_sum;
child_sum += rtn_val;
++i;
goto rtn;
}
return rtn_val;
}
最后,我们可以将最后一个goto rtn
替换为一个无止境的循环,其中我们从函数返回(打破循环),除非goto rtn
会循环:
int calc_max(NODE *node) {
int i, child_sum, rtn_val, sp;
struct stack_frame {
NODE *node;
int i, child_sum;
} stk[1000];
sp = i = child_sum = 0;
while (1) {
while (i < node->n_children) {
stk[sp++] = (struct stack_frame){.node = node, .i = i, .child_sum = child_sum};
node = node->children[i];
i = child_sum = 0;
}
rtn_val = MAX(node->value, child_sum);
if (sp <= 0) return rtn_val;
node = stk[--sp].node;
i = stk[sp].i + 1;
child_sum = stk[sp].child_sum + rtn_val;
}
}
int calc_max(节点*NODE){
整数i,子和,rtn值,sp;
结构栈框架{
节点*节点;
int i,child_sum;
}stk[1000];
sp=i=child\u sum=0;
而(1){
而(in_子节点){
stk[sp++]=(结构堆栈_帧){.node=node、.i=i、.child_sum=child_sum};
节点=节点->子节点[i];
i=子项_和=0;
}
rtn_val=MAX(节点->值,子项和);
如果(sp
int calc_max(NODE *node) {
int i, child_sum, rtn_val, sp = 0;
struct stack_frame {
NODE *node;
int i, child_sum;
} stk[1000];
i = child_sum = 0;
rtn:
while (i < node->n_children) {
stk[sp++] = (struct stack_frame){.node = node, .i = i, .child_sum = child_sum};
node = node->children[i];
i = child_sum = 0;
goto rtn;
}
rtn_val = MAX(node->value, child_sum);
if (sp > 0) {
--sp;
node = stk[sp].node;
i = stk[sp].i;
child_sum = stk[sp].child_sum;
child_sum += rtn_val;
++i;
goto rtn;
}
return rtn_val;
}
int calc_max(NODE *node) {
int i, child_sum, rtn_val, sp = 0;
struct stack_frame {
NODE *node;
int i, child_sum;
} stk[1000];
i = child_sum = 0;
rtn:
while (i < node->n_children) {
stk[sp++] = (struct stack_frame){.node = node, .i = i, .child_sum = child_sum};
node = node->children[i];
i = child_sum = 0;
}
rtn_val = MAX(node->value, child_sum);
if (sp > 0) {
--sp;
node = stk[sp].node;
i = stk[sp].i;
child_sum = stk[sp].child_sum;
child_sum += rtn_val;
++i;
goto rtn;
}
return rtn_val;
}
int calc_max(NODE *node) {
int i, child_sum, rtn_val, sp;
struct stack_frame {
NODE *node;
int i, child_sum;
} stk[1000];
sp = i = child_sum = 0;
while (1) {
while (i < node->n_children) {
stk[sp++] = (struct stack_frame){.node = node, .i = i, .child_sum = child_sum};
node = node->children[i];
i = child_sum = 0;
}
rtn_val = MAX(node->value, child_sum);
if (sp <= 0) return rtn_val;
node = stk[--sp].node;
i = stk[sp].i + 1;
child_sum = stk[sp].child_sum + rtn_val;
}
}