【问题标题】:Permuting a binary tree without the use of lists在不使用列表的情况下置换二叉树
【发布时间】:2009-03-26 12:24:24
【问题描述】:

我需要找到一种算法来生成二叉树的所有可能排列,并且需要在不使用列表的情况下这样做(这是因为树本身带有无法转换为列表的语义和约束)。我找到了一种适用于高度为 3 或以下的树的算法,但每当我达到更高的高度时,我就会丢失一组每个添加高度的可能排列。

每个节点都携带有关其原始状态的信息,以便一个节点可以确定是否已针对该节点尝试了所有可能的排列。此外,该节点携带有关天气的信息,它是否已被“交换”,即它是否已经看到它的子树的所有可能排列。树是左居中的,这意味着右节点应该总是(除了在某些情况下我不需要为这个算法介绍)是叶节点,而左节点总是叶节点或分支。

我现在使用的算法可以这样描述:

if the left child node has been swapped
      swap my right node with the left child nodes right node
      set the left child node as 'unswapped'
  if the current node is back to its original state
      swap my right node with the lowest left nodes' right node
      swap the lowest left nodes two childnodes
      set my left node as 'unswapped'
      set my left chilnode to use this as it's original state
      set this node as swapped
      return null
  return this; 
else if the left child has not been swapped
  if the result of trying to permute left child is null
     return the permutation of this node
  else 
     return the permutation of the left child node
if this node has a left node and a right node that are both leaves
   swap them
   set this node to be 'swapped'

算法的期望行为是这样的:

            branch
             /    |
       branch     3
         /   |
   branch    2
   /     |
  0      1


            branch
             /    |
       branch     3
         /   |
   branch    2        
   /     |
  1      0           <-- first swap



            branch
             /    |
       branch     3
         /   |
   branch    1         <-- second swap
   /     |
  2      0



            branch
             /    |
       branch     3
         /   |
   branch    1         
   /     |
  0      2   <-- third swap


            branch
             /    |
       branch     3
         /   |
   branch    0   <-- fourth swap        
   /     |
  1      2  

等等……

【问题讨论】:

  • 闻起来像家庭作业,但看起来你付出了真正的努力,所以这比通常的家庭作业式问题要好得多。尽管如此,即使是家庭作业,这种数据结构也很不适合置换。
  • 恐怕这不是家庭作业(我希望是),我有一份真正的工作来做这个……;)
  • 哇哦。这真的很糟糕,因为这似乎是一个疯狂的问题。我会看看我能想出什么。
  • 如果树是左居中的,这个问题和正常情况下的列表和交换操作有什么区别?
  • 非常感谢,我真的很感激!

标签: algorithm binary-tree permutation


【解决方案1】:

该结构完全不适合排列,但既然您知道它是左中心的,您也许可以做出一些假设来帮助您。

我尝试以与您类似的方式处理它,但我总是发现您只有一个二进制信息(交换或不交换)是不够的。对于四片叶子,你有四片! (24) 种可能的组合,但您实际上只有三个分支(3 位,8 种可能的组合)来存储交换的状态信息。您根本没有地方存储这些信息。

但也许您可以编写一个遍历树并使用叶子数来确定需要多少交换的遍历器,然后系统地遍历这些交换,而不是将其留给树本身。

类似

For each permutation
   Encode the permutation as a series of swaps from the original
   Run these swaps on the original tree
   Do whatever processing is needed on the swapped tree

这可能不适合您的应用程序,但您没有详细说明为什么需要按照您的方式进行操作。你现在这样做的方式根本行不通,因为阶乘(排列的数量)比指数(你拥有的“交换”位的数量)增长得更快。如果你有 8 片叶子,那么你将有 7 个分支和 8 片叶子,总共 15 位。 8个叶子有40320个排列,15位的可能组合只有32768个。在数学上,您根本无法表示排列。

【讨论】:

  • 啊,你说得对,我没想到。非常非常感谢您,我会尝试您建议的方法,看看是否有效。我没有足够的声誉分数来提高你的答案,但如果我有,我会从这个中提高 bajeebers。再次感谢!
  • 我不是为了积分,Banang。谢谢你的有趣问题。我希望我的解决方案适合你。如果没有,请在另一条评论中告诉我,我们会看看我们能想出什么。
【解决方案2】:

列出树中所有项目的列表,使用生成方法构建所有可能的顺序(参见 Knuth Vol 4),然后将它们重新映射到树结构有什么问题?

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-03-15
    • 2013-08-05
    • 1970-01-01
    • 1970-01-01
    • 2017-05-24
    • 2020-04-25
    相关资源
    最近更新 更多