2017-01-23 5 views
2

Меня спросил один из моих старших руководителей: можно ли перевернуть односвязный список без использования цикла? Если да, то как? Его улыбка, казалось, говорила мне, что это возможно, но я ничего не мог придумать. Кто-нибудь думал об этом раньше?Связанный список обратный без использования цикла?

+2

вы имеете в виду, что мы можем сделать это быстрее, чем O (п)? или вы хотите сказать, что мы можем сделать это с рекурсией? –

+0

или вы также можете сделать это с помощью goto –

+0

@PetarPetrovic, Goto кажется интересным. Расскажи мне больше. –

ответ

4

Можно отменить двойной связанный список в O (1) путем замены его head и tail указатели, и (в зависимости от реализации) установление своего рода флаг, который скажет, что список должен быть теперь повторяется назад (т. е. следуя указателям back для повторения итерации вперед и следуя указателям next, чтобы итератировать назад).

Что касается односвязного списка, я считаю, что его невозможно отменить быстрее, чем O (n).

1

В STL есть итераторы rbegin() и rend() для обхода коллекций в обратном порядке. Но он не будет работать для одного связанного списка.

2

подход в рекурсии

struct node { 
    int value; 
    struct node* next; 
}; 

struct node** _reverse(struct node* n) 
{ 
    if (NULL != n->next) 
     *_reverse(n->next) = n; 
    return &(n->next); 
} 

// this is the entry 
void reverse(struct node* head) 
{ 
    *_reverse(head) = NULL; 
} 
+0

Вы уверены, что этот код будет работать? Мысленно пробуем его с тремя списками элементов A, B, C и get * (& nullptr) = B. – AMA

+0

@AMA Просто потому, что 'c-> next == nullptr' не означает, что' * (& c-> next) 'является то же, что и '* (& nullptr)'. 'c-> next' имеет свой адрес. – neuront

+0

ага! Это элегантно. Спасибо, что объяснили. – AMA

Смежные вопросы