【问题标题】:Flattening a multilevel linked list展平多级链表
【发布时间】:2014-08-21 07:01:49
【问题描述】:

问题

  1. 给定一个链表,其中除了 next 指针之外,每个节点 有一个子指针,它可能指向也可能不指向单独的列表。

  2. 给定第一个列表的头部,将列表展平,以便所有 节点出现在单级链表中。

目标

我们需要以这样一种方式展平列表,以使第一级的所有节点 应该先来,然后 二级节点,以此类推。

上面的列表应该转换成

10->5->12->7->11->4->20->13->17->6->2->16->9->8->3->19- >15

我的方法:

1) Create an empty queue
2) while(Queue is not empty AND head.next!=null AND head.child!=null)
     2a) while(head!=null)
           if(head.child!=null)
               Enqueue(head.child)
           newList = head;
           head = head.next;
           newList = newList.next;
     2b)head = deQ();

这种方法正确吗?

【问题讨论】:

  • 它是伪代码,但仍然不是Queue is not empty 等价于head.next!=null AND head.child!=null。除此之外,您的方法对我来说似乎是正确的。
  • 有一个两指解决方案,无需额外的数据结构即可工作。 (好吧,它需要两个手指,但它们只是节点指针。)我认为这是家庭作业,你更愿意自己解决,对吧?
  • @rici 这不是家庭作业。您或@aa333 能否指出while 的第2 行)中的终止条件?
  • @Dubby:好的,添加了解决方案。我确定我已经在 SO 的其他地方为 BFS 提供了相同的算法。还有一个双指深度优先版本,其中子链接用于维护递归堆栈;你可能会喜欢弄清楚。

标签: algorithm linked-list queue pseudocode


【解决方案1】:

简单的基于栈的解决方案,遍历到下一个端点,然后从栈中附加子节点。

node *flatten(node *head) {
    stack<node *> s;
    node *curr = root;
    while (1) {
        if (curr->next) { // keep moving in current streak
            if (curr->child)
                s.push(curr);
            curr = curr->next;
        }
        else { // attach child branch and continue from there
            if (s.empty())
                return head;
            curr->next = s.top()->next;
            s.top()->next = NULL;
            s.pop();
            curr = curr->next;
        }
    }
}

【讨论】:

  • 您的解决方案在给定的测试用例上失败。另外,如果 head 为 NULL,它会崩溃。
【解决方案2】:

这是一个简单的两指宽度优先(级别顺序)遍历,它执行就地展平。 (效率狂人可能想要重新排列循环,因为有些测试会进行两次,但这几乎没有什么区别。)基本思想是有一个隐式队列,由finger2finger1 之间的节点组成。 finger1 向前穿过关卡,每次到达没有右兄弟节点的节点时,“队列”通过向右移动 finger2 前进,直到找到一个子节点,然后将其附加到 finger1 以便finger1 可以继续向右移动。

finger1 = finger2 = head;
while finger2 is not Null:
  while finger1.next is not Null: finger1 = finger1.next
  while finger2 is not Null and finger2.child is Null: finger2 = finger2.next
  if finger2 is not Null:
    finger1.next = finger2.child
    finger2.child = Null   

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-10-27
    • 2017-03-06
    • 1970-01-01
    • 2018-12-23
    • 1970-01-01
    • 1970-01-01
    • 2015-04-08
    • 2017-12-12
    相关资源
    最近更新 更多