2016-08-19 85 views
1

美好的一天,是否可以使用有限状态机遍历二叉树?

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

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

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

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

我已经尝试了很长一段时间,怀疑这是不可能的,但我不是当然。问题在于需要跟踪最近的决定,因此在重新访问通过父节点的节点时,可以在左侧处理完毕后右转。

想法?

在此先感谢! 香草

+0

你看过Morris Inorder Traversal吗? https://en.wikipedia.org/wiki/Tree_traversal#Morris_in-order_traversal_using_threading – msandiford

+0

谢谢@msandiford。一个线程化的二叉树([link](https://en.wikipedia.org/wiki/Threaded_binary_tree))在按顺序访问树时将会很棒。不幸的是,改变树布局是没有问题的。由于树是一个前缀树(aka Patricia trie),访问它的最明智的方式是预定。出于纯粹的好奇心(因为我无法改变树布局):没有线程二叉树用于预先遍历,或者是否存在? – Herb

回答

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”应该是相互排斥的。但我正在用这种方式写出来,以节省一点时间。如果你不明白我的意思,请问。

+0

谢谢杰拉尔多。事实上,正如同时在类似的解决方案中工作,并在我看到您的工作时回来发布它。谢谢你的时间! – Herb

0

这是我拿出来的许多纸张,价值半棵树后,主要是绘制许多二叉树(尤其是退化的树),以验证FSM正常工作。

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

可访问所有的时间要求的唯一的变量是开始节点。这可以是树中的任何节点:FSM仅遍历此子树。

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

单独行动的意思是:

  • 向左走 - 使当前节点的左子当前节点,如果有的话。如果成功,答案是肯定的;如果没有这样的节点,答案是否定。
  • 正确 - 使当前节点的右侧子节点成为当前节点(如果有)。如果成功,答案是肯定的;如果没有这样的节点,答案是否定。
  • GO UP - 使当前节点的父节点成为当前节点。只有一个结果状态。对于根目录,父目录不存在,但FSM永远不会尝试访问根目录的父目录。
  • 我左边 - 测试当前节点是否是其父亲的左孩子。答案是真或假。
  • 我是正确的 - 测试当前节点是否是其父亲的右孩子。答案是真或假。
  • I AM START - 测试当前节点是否为开始节点。答案是真或假。
+0

您的图表对输入/条件评估和状态使用相同的符号。这使得它有点令人困惑,如果你改变它看起来像我的答案......它看起来像它工作正常 –

+1

所以哪些是状态机的状态?向左/向右/向上是输出。我是左/右/开始是输入。哪些是州?即使有解释,你仍然在绘制流程图,而不是状态机。 –

+0

对不起,很难过。如果这是家庭作业,那是一位老师会问的。 –