链接列表反向没有临时

时间:2012-01-11 22:20:30

标签: c data-structures linked-list

有没有办法在不使用C中的临时变量的情况下反转链表? 提前谢谢。

着名的方法:

Element *reverse(Element *head)
{
    Element *previous = NULL;

    while (head != NULL) {
        // Keep next node since we trash
        // the next pointer.
        Element *next = head->next;

        // Switch the next pointer
        // to point backwards.
        head->next = previous;

        // Move both pointers forward.
        previous = head;
        head = next;
    }

    return previous;
}

使用临时变量

SAURABH

4 个答案:

答案 0 :(得分:6)

请注意,temp用法实际上会产生两次swap()次来电,可以替换为:

swap(head->next,previous);
swap(previous,head);

您可以使用xor交换不带temps,它被称为xor swap

答案 1 :(得分:3)

在伪造XOR-swaps

的指针上使用XOR-linked-list.

实施留给读者作为练习。

答案 2 :(得分:1)

递归方法:

Element *reverse(Element *head, Element **first)
{
    if (head->next == NULL)
    {
        *first = head;
        return head;
    }


     Element* NextElement= reverse  (head->next, first);
     NextElement->next = head;
     head->next = null;

     return head;
}

调用递归函数:

   Element *revLinkListHead;
   reverse(head, &revLinkListHead);

答案 3 :(得分:0)

如果有人仍然感兴趣,这里的解决方案根本不使用任何新变量,除了那些在递归调用中传递的变量。

public static List invert(List l) {
    invert(l.next, l, l);
    l = l.next;
    breakCycle(l, l);
    return l;
}

private static void invert(List l, List toBeNext, List first) {
    if(l.next == null) {
        l.next = toBeNext;
        first.next = l;
    } else {
        invert(l.next, l, first);
        l.next = toBeNext;
    }
}

private static void breakCycle(List l, List first) {
    if(l.next == first) {
        l.next = null;
    } else {
        breakCycle(l.next, first);
    }
}

这个想法如下:首先我们递归地运行反函数,然后实现它,当它到达最后一个元素时,它将它指定为当前头的下一个元素(参数first)。在我们执行它之后,我们将有一个反向列表但循环,所以当前head.next将指向反向列表的头部。我们重新分配到下一个元素(反向列表的实际头部),我们要做的最后一件事就是打破循环。所以我们调用breakCycle来递归地完成工作!