压缩存储2个链表的数组

时间:2011-08-04 07:04:36

标签: algorithm data-structures linked-list complexity-theory

数组Arr(大小为n)可以表示双向链表。   [假设细胞有结构{int val,next,prev; }]

我有两个存储在数组中的列表A和B. A有m个节点,B有n个m节点。

这些节点被分散,我想重新排列它们,使得A的所有节点都来自Arr [0] .Arr [m-1]并且其余部分由B的节点填充,在O(m)时间内。 / p>

我遇到的解决方案是:

  • 迭代A直到出现超出Arr [m-1]
  • 的节点
  • 然后,迭代B直到出现在Arr [m]
  • 之前的节点
  • 交换两个(包括操纵他们和他们的邻居的下一个上一个链接)。

然而,在这种情况下,迭代总数为O(n + m)。因此应该有一个更好的答案。

P.S: 这个问题出现在Introduction to Algorithms, 2nd edition中。 问题10.3-5

2 个答案:

答案 0 :(得分:2)

如何迭代列表 A 并将每个元素放在Arr[0] ... Arr[m-1]中,显然用之前的任何内容交换位置并更新prev / next链接。会有很多交换但是它会是 O(m),因为一旦你完成迭代 A m 迭代),所有其元素的位置(按顺序顺序)位于Arr的第一个 m 个插槽中,因此 B 必须完全位于{的其余部分{1}}。

添加一些伪代码

Arr

答案 1 :(得分:0)

我认为“jw013”是对的,但这个想法需要一些改进:

通过交换你正在改变Arr数组中元素的地址。 所以你需要小心!

e.g。我们可以说Arr喜欢:

指数:0 1 2 3 4

        | 2 | empty | 3 | empty | 1 |   (assume the link list is like  1 -> 2 -> 3)

因此Arr[4].next为0而Arr[0].next为2。

但是当你交换Arr[4]Arr[0]时,Arr[0].next为0。 这不是我们想要发生的事情所以我们应该考虑在交换时调整指针。

所以它的代码就像:

 public static void compactify(int List_head , int Free , node [] array){
        int List_lenght ;
        
        List_lenght = find_listlenght(List_head , array);
        
        if(List_lenght != 0){ // if the list is not empty
            int a = List_head;
            for (int i = 0; i < List_lenght ; i++) {

                swap( array , a , i );
                a = array[i].next;
                
                print_mem(array);
            }
        }
         
       
    }

现在调用swap:

private static void swap(node[] array, int a, int i) {
        
        // adjust the next and prev of both array[a] and array[i]
        
        int next_a = array[a].next;
        int next_i = array[i].next;
        
        int prev_a = array[a].prev;
        int prev_i = array[i].prev;
        
        // if array[a] has a next adjust the array[next_a].prev to i
        if(next_a != -1)   
            array[next_a].prev = i;

        // if array[i] has a next adjust the array[next_i].prev to a
        if(next_i != -1)  
            array[next_i].prev = a;

        // like before adjust the pointers of array[prev_a] and array[prev_i] 

        if(prev_a != -1)
            array[prev_a].next = i;

        if(prev_i != -1)
            array[prev_i].next = a;
        
        node temp = array[a];
        array[a] = array[i];
        array[i] = temp;
        
    }