是否可以使用有限状态机遍历二叉树?

时间:2016-08-19 03:19:14

标签: tree-traversal state-machine

美好的一天,

为了清楚起见:我不是在寻找递归或迭代解决方案,维基百科有足够的伪代码来实现任何树的前,中,后顺序遍历。

我有兴趣构建一个有限状态机来遍历二叉树。

树由节点组成。节点有LeftChild,RightChild和Parent属性。

FSM在任何给定时间在节点处停止,并且可以具有所需数量的状态,但是没有任何类型的动态堆栈(这使其与图灵机区别开来)。在输入“GiveNext”时,机器应该在下一个节点上停止(比如遍历树预订。)

我已经尝试了很长一段时间,并怀疑,这是不可能的,但我不确定。问题是需要跟踪最近的决定,以便在通过Parent重新访问节点时,可以在处理完左侧时向右转。

思想?

提前致谢! 草本植物

2 个答案:

答案 0 :(得分:0)

我可能会缺少这种练习的限制。我希望这至少有点有用。

我认为FSM是“站着”是可以接受的。在当前节点的任何给定时间'因此,它有可用的输入返回正确的0/1值,并提供有关此当前节点的信息。

输入:

  • AmIALeftChild(如果当前节点挂在其父节点的左侧,则等于1,否则为0)
  • AmIARightChild(如果我挂在父节点的左边,则为1,否则为0)
  • HaveLeftChild? (如果我有一个左孩子,则为1,否则为0)
  • HaveRightChild? (1如果我有一个合适的孩子,否则为0)

是否可以“遍历”'按照这3个输出中的说明进行操作?

输出:

  • GoToLeftChild
  • GoToRightChild
  • GOUP

(3个输出中只有1个在任何给定时间都可以为真)

如果允许两个约束,那么你可以像这样构建一个FSM:

  • 启动
  • NormalTraverse
  • GoBackFromLeft
  • GoBackFromRight
  • 完成

这是状态机:

Start -> just go to NormalTraverse state (assuming we are on the root, right)

NormalTraverse -> 
    If HaveLeftChild=1 Then
        Set GoToLeftChild=1  (and others outputs to 0)
        Go to NormalTraverse
    ElseIf HaveRightChild Then
        Set GoToRightChild=1 
        Go to NormalTraverse
    ElseIf AmIALeftChild Then
        Set GoUp=1
        Go to GoBackFromLeft
    ElseIf AmIARightChild Then
        Set GoUp=1
        Go to GoBackFromRight
    Else 
        Go to Finished.

GoBackFromLeft ->
    If HaveRightChild Then
        Set GoToRightChild=1 
        Go to NormalTraverse.   
    ElseIf AmIALeftChild Then
        Set GoUp=1
        Go to GoBackFromLeft
    ElseIf AmIARightChild Then
        Set GoUp=1
        Go to GoBackFromRight
    Else 
        Go to Finished.

GoBackFromRight
    If AmIALeftChild Then
        Set GoUp=1
        Go to GoBackFromLeft
    ElseIf AmIARightChild Then
        Set GoUp=1
        Go to GoBackFromRight
    Else 
        Go to Finished.

请原谅我的英语,请注意代码不是程序性的,而且" IF""在正确地扩大'之后应该互相排斥。他们' bit-wisely'。但我这样写它是为了节省一点时间。如果您不明白我的意思,请询问。

答案 1 :(得分:0)

这是我提出的,经过多张纸的半张树后,主要是为了验证FSM能正常工作的许多二叉树(特别是退化的树)。

A finite-state machine traversing a binary tree pre-order

始终可访问的唯一变量是start节点。这可以是树中的任何节点:FSM仅遍历此子树。

假设已经处理了起始节点(或者不需要处理)。但是如果您的应用程序不是这样的话,它将很容易集成:在GO LEFT步骤之前,只需为起始节点添加一个测试:I AM START。如果为TRUE,则报告,否则如图所示继续。

个人行为意味着:

  • GO LEFT - 将当前节点的左子节点设为当前节点(如果有)。如果成功,答案是OK,如果没有这样的节点,则为No Left。
  • GO RIGHT - 将当前节点的右子节点设为当前节点(如果有)。如果成功,答案是OK,如果没有这样的节点,则为No Right。
  • GO UP - 使当前节点的父节点成为当前节点。只有一个结果状态。对于root,父节点不存在,但FSM永远不会尝试访问根节点的父节点。
  • 我向左 - 测试当前节点是否为其父左子节点。答案是正确还是错误。
  • 我是正确的 - 测试当前节点是否是其父权限子节点。答案是正确还是错误。
  • 我开始 - 测试当前节点是否为起始节点。答案是正确还是错误。