2017-02-15 16 views
1

Мне нужно написать функцию, чтобы перевернуть двойной связанный список, чтобы хвост стал головой.Обратный двойной связанный список

Например, элементы перед: {(1,1), (1,2), (2,2), (2,3)}

после: {(2,3) , (2,2), (1,2), (1,1)}

Вот структура:

struct snake { 
    unsigned int i; 
    unsigned int j; 
    struct snake *next; 
    struct snake *prev; 
    }; 

Это функция prototipe я должен использовать:

void snake_reverse(struct snake **s); 

я пытался что-то вроде этого и несколько других попыток

void snake_reverse(struct snake **s) { 
struct snake *last, *tmp = NULL; 

last = *s; 

while (last != NULL) 
{ 
    tmp = last->prev; 
    last->prev = last->next; 
    last->next = tmp; 
    last = last->prev; 
} 

if(tmp != NULL) 
    *s = tmp->prev; 
} 

попытался Также это:

while (last != NULL) 
{ 
    tmp = last->next; 
    last->next = last->prev; 
    last->prev = tmp; 
    last = tmp; 
} 

if(tmp != NULL) 
    *s = tmp; 

, но он не работает. Я почти уверен, что не ошибаюсь. Первый -> prev из списка NULL, последний -> следующий из списка - NULL.

У меня нет ошибок или сбоев, но задача функции состоит в том, чтобы инвертировать направление змеи путем изменения всех элементов и изменения главы списка. Можете ли вы сказать, что здесь не так?

EDIT: Проблема была в другом модуле программы, которую я не сделал.

В любом случае лучшим решением является решение kmkaplan. Спасибо всем

+0

Когда вы описываете проблему, вы не можете просто сказать «она не работает»; лучше, если вы более точны: вот что я сделал, ожидаемый результат - X, но у меня есть Y (альтернативно: есть сбой с сообщением об ошибке Z). Возможно, настоящая ошибка заключается в том, как вы проверяете свою функцию. – coredump

+0

См. Также 'last = last-> prev': было бы целесообразно иметь' last = tmp' вместо этого? – coredump

+0

@coredump извините, если я не могу быть более конкретным, но эта функция используется как модуль в программе, и я не могу контролировать остальную часть программы. Во всяком случае, я не получаю ошибок или сбоев, но задача функций состоит в том, чтобы инвертировать направление змеи, изменяя все элементы и меняя головку списка. last-> prev имеет адрес последней и следующей причины, по которым мы их переключили. tmp имеет последний-> пред.Так что они разные – RUsl

ответ

1

Вы должны установить *s к новой главе списка. Это старый хвост списка, последний элемент, который вы обрабатываете.

void snake_reverse(struct snake **s) { 
    struct snake *last, *tmp = NULL; 
    last = *s; 
    while (last != NULL) { 
     *s = last 
     tmp = last->prev; 
     last->prev = last->next; 
     last->next = tmp; 
     last = last->prev; 
    } 
} 
+0

Спасибо, это действительно поменять местами элементы (я проверил адрес элементов, и они поменялись местами), но змея в игра по-прежнему застревает, когда она вызывает эту функцию. Так что я думаю, что это не моя ошибка, и проблема в другой функции. – RUsl

+0

Проблема была в другом модуле программы, а не сделанном мной. В любом случае это кажется лучшим решением и сработало – RUsl

0

Я не уверен, но я думаю, что последняя строка кода в вашем цикле while неверна. Насколько я понимаю, последняя переменная - это хвост змеи. Это означает, что last-> next = null. Во второй строке кода в то время как вы делаете предыдущий последний нуль и в последней строке кода в то время как последнее становится 0. Я думаю, что изменение вашей последней строки кода в цикле while изменит это.

last = last->next 
+0

Я пробовал, но он не работает. Теоретически в последней строке цикла while-> prev имеет адрес last-> next, поэтому правильно использовать last-> prev для перехода к следующему элементу списка – RUsl

0

Вы никогда не устанавливаете новую головку списка, поскольку tmp всегда имеет значение NULL после цикла while. Попробуй это;

void snake_reverse(struct snake **s) { 
    struct snake *last, *newHead, *tmp = NULL; 

    last = *s; 

    while (last != NULL) 
    { 
    tmp = last->prev; 
    if (tmp!=NULL) 
     newHead = tmp; 
    last->prev = last->next; 
    last->next = tmp; 
    last = last->prev; 
    } 

    *s = newHead; 
} 
+0

Спасибо за ответ, но ничего не делать , змея все еще застревает в игре, когда я вызываю эту функцию. Тогда я думаю, что что-то не так. Для немного отладки эти адрес элементов: перед циклом * s = 16595408 * втор-> следующая = 16595360 * втор-> пред = 0 После того, как * s = newHead * s = 16595408 * s-> следующая = 0 * s-> пред = 1659536 – RUsl