有序遍历的非递归算法

时间:2011-09-01 20:04:58

标签: algorithm language-agnostic computer-science

有一系列组合算法,基于以下技术 - 我们观察结构的一些属性,并使用该属性遍历所有可能/可访问的线性变体(或关闭,无论如何,并不重要)时间,没有递归。

实施例

词典排列a 1 .. a [n]

  • 找到最后一个[k],使得a [k]< a [k + 1]> ...
  • 在[k + 1] ... a [n]中找到最小a [m],使得a [k] < a [m]
  • 交换a [m]和[k]
  • 还原[k + 1] .. a [n]

n的k-subsets

  • 从最后迭代,找到第一个零,前面加1(第一个[k] == 0使a [k + 1] == 1)
  • 指定[k] = 1
  • 在[k] .. a [n]
  • 中计算1
  • 重新平衡 - 尽可能在最后分配1,其余设置为零

n的分区(按降序排列)

  • 找到第一个k,使得a [k]> a [k + 1](k = 1也没关系)
  • 增加a [k] = a [k] + 1
  • 找到从k到最后一个元素的总和
  • 只要总和允许,
  • 将左邻居增加1。

我想,这足以说明这种算法的本质。这些以及其他一些例子可以在优秀,精湛的书籍“Algorithms and Programming: Problems and Solutions”中找到。

我的问题如下。请你在这个算法的任何领域向我描述更多的例子。如果你也提供算法本身(用上面的话,更可取),这将是很好的。也欢迎参考书籍,文章。也欢迎参考相关的理论问题(例如,我只是感觉不能建立这样的算法,何时 - 不是)。

提前致谢。

2 个答案:

答案 0 :(得分:2)

考虑一系列算法中的算法A.要么A已经是迭代的,要么它是递归的,它可以通过显式数据结构模拟调用堆栈而转换为等效的迭代算法。参见例如Wikipedia

答案 1 :(得分:1)

这和Jiri的答案一样,但也许更直接:任何可解决的计算问题都可以通过图灵机解决,我认为没有人会把图灵机的功能描述为“递归” ,但作为国家。换句话说,给定足够的辅助磁带存储,while循环和select-case(或等效分支,例如if / else,构造),您可以使用基于状态机的方法解决任何问题 - 包括这些枚举问题

例如,定义一个基于状态的算法来进行二叉搜索树的有序遍历是相当简单的。

  1. 从状态DL开始(左下)。如果您在DL中并且节点有一个左子节点,则向下移动到该节点并保持DL状态;否则,打印节点的内容,如果节点有正确的子节点,则更改为状态DR并移动到正确的子节点;如果节点没有正确的子节点,则更改为状态UR并移至父节点。

  2. 如果处于状态DR,并且您有一个左孩子,请移至左侧孩子并更改为状态DL。否则,如果您有正确的孩子,请打印节点的内容并移至孩子并留在DR中。否则,移至父节点并切换到UL状态。

  3. 如果处于UR状态,则打印节点信息,如果有正确的子节点,则移动到该状态并将状态更改为DR;否则,转移到父母并留在UR。

  4. 如果处于UL状态,如果当前节点是其父节点的正确子节点,则保留在UL中并移至父节点;否则,如果当前节点不是父节点的右子节点,并且它是左子节点,则更改为状态UR并移动到父节点。如果此节点没有父节点,则终止算法。

  5. 无论如何,你明白了。有序的树遍历就像你得到的本质上递归一样;许多(所有?)其他遍历问题可以通过遍历某些树来实现,这里是一种使用状态机在线性时间内进行顺序遍历的方法。你相信这种方法是O(n)吗?提示:它访问每个节点不超过三次。