将Zigzag顺序中的二叉树转换为双链表

时间:2011-03-12 10:50:16

标签: algorithm data-structures linked-list binary-tree

我有一个问题。我必须将其ZigZag格式的二叉树转换为双向链表     

 Given BT:
                 [1]
          [2]                  [3]
      [4]      [5]         [6]        [7]
    [8]  [9] [10] [11] [12] [13] [14] [15]

ZigZag order of BT in DLL: [1] [3] [2] [4] [5] [6] [7] [15] [14] [13] [12] [11] [10] [9] [8]

这是我的伪代码:

DLLNode* ConvertBTToZigZgDLL(Node* root)
{
  DLLNode* start=createDLLNode(root->data);
  DLLNode* tail=start;
  Stack<Node> stack1, stack2;
  stack1.push(root->left);
  stack1.push(root->right);
  while( !stack1.Empty() || !stack2.Empty() )
  {
     while(stack1.HasElement())
     {
       Node* temp=stack1.Pop();
       stack2.push(temp->right);
       stack2.push(temp->left);
       tail=Attach(tail,createDLLNode(temp->data));
       tail=tail->next;
     }
     while(stack2.HasElement())
     {
       Node* temp=stack2.Pop();
       stack1.push(temp->left);
       stack1.push(temp->right);
       tail=Attach(tail,createDLLNode(temp->data));
       tail=tail->next;
     }
  }
  return start;

}   这里是TimeComplexity O(N),其中N是给定二进制树中的节点数。

  

  DLLNode* Attach(DLLNode* source, DLLNode* dest)
  {
     source.Next=dest;
     dest.prev=source;
     return source;
  }

  DLLNode* CreateDLLNode(int data)
  {
    DLLNode* res=malloc(sizeof(struct DLLNode));
    res->data=data;
    res->prev=NULL;
    res->next=NULL;
    return res;
   }

我只想知道我的代码的逻辑有什么问题。

其中一位朋友说上面的代码不会工作而且错了。我无法找到我的逻辑失败的任何用例(排除空检查/空/空节点)

只需检查我的代码的逻辑并告诉我。

我的逻辑很简单:使用2个堆栈。在stack1中,我总是首先推动Left孩子,然后推动右孩子,在stack2中我总是先将正确的孩子推到第二位,然后将孩子推到第二位。最初加载stack1而stack1非空弹出并在stack2中推送相应的右/左子节点。对于上面的例子,我的堆栈状态应该像s1-B [2,3] T s2-B [7,6,5,4] T s1-B [8,9,10,11,12,13,14, 15] T B-stack底部T-Stack顶部。请再次检查。感谢。

2 个答案:

答案 0 :(得分:1)

另一个问题已经涵盖了这一点。

请参阅this stackoverview set of answers

答案 1 :(得分:1)

算法:

使用修改后的BFS算法,而不是单个fifo队列使用两个堆栈stack1用于包含从右到左访问的级别中的节点,而stack2包含要从左到右访问的节点。

列表使用根节点初始化,第一级(最接近根)存储在stack1中。因此,第一次通过stack1将以适当的顺序拉出第一级。

对于一般案例证明,假设stack1中的元素以正确的顺序存储,从stack1拉出N级节点可确保按从右到左的顺序处理它们。对于每个如此处理的节点,子树在第一个右侧存储在stack2中,然后在左侧存储。这保证了对于级别N + 1,从stack2 检索的节点列表具有从左到右的顺序。当级别N上没有更多节点时,while循环完成。此时从stack2中提取节点将从左到右依次从级别N + 1中检索所有节点。

相反,当从每个从左到右的级别从stack2拉出节点时,将子节点存储在stack1的第一个左侧,然后是右侧,确保在下一次迭代中将它们拉出时从右到左的顺序。

所以基本上算法证明是合理的。现在这不能确保实现。特别是你要将所有NULL指针添加到堆栈中,这意味着你将检索它们,然后尝试通读它们。