展平多级链表

时间:2014-06-30 20:00:47

标签: algorithm linked-list queue pseudocode

问题

  1. 给定一个链表,除了下一个指针之外,还有每个节点 有一个子指针,可能指向或不指向单独的列表。

  2. 鉴于第一个列表的头部扁平化列表以便所有 节点出现在单级链表中。

  3.   

    目标

         

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

    enter image description here

    以上列表应转换为

      

    10→5→12&将7-> 11-将4-> 20→; 13-> 17-> 6-> 2→16-&GT 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();
    

    这种做法是否正确?

2 个答案:

答案 0 :(得分:3)

这是一个简单的双指宽度优先(水平顺序)导线,它可以进行就地展平。 (效率怪胎可能想要重新安排循环,因为有些测试已完成两次,但它几乎没有什么区别。)基本思想是存在由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   

答案 1 :(得分:0)

基于简单堆栈的解决方案,遍历到下一个结束,然后将孩子从堆栈中附加。

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;
        }
    }
}