Связанные структуры, такие как deques, легко поддаются рекурсии, поэтому я склоняюсь к рекурсивному стилю при работе со связанными структурами.Это также позволяет нам писать это постепенно, чтобы мы могли легко проверить каждую функцию.Циклы, выполняемые вашей функцией, имеют много недостатков: вы можете легко ввести ошибки забора , и это приводит к большим сбивающим с толку функциям.
Сначала вы решили сделать это, поменяв указатели, право?Итак, напишите функцию для замены указателей:
void swapCirListDequePointers(
struct cirListDeque** left,
struct cirListDeque** right)
{
struct cirListDeque* temp = *left;
*left = *right;
*right = temp;
}
Теперь напишите функцию, которая инвертирует указатели в одном узле:
void swapPointersInCirListDeque(struct cirListDeque* q)
{
swapCirListDequePointers(&(q->prev),&(q->next));
}
Теперь, рекурсивно сложите это вместе:
void reverseCirListDeque(struct cirListDeque* q)
{
if(q == q->backSentinel)
return;
swapPointersInCirListDeque(q);
// Leave this call in tail position so that compiler can optimize it
reverseCirListDeque(q->prev); // Tricky; this used to be q->next
}
Я не уверен точно, как устроена ваша структура;моя функция предполагает, что ваша очередь круговая, и вы будете вызывать ее на страже.
РЕДАКТИРОВАТЬ: Если ваша очередь не круглая, вы также захотите позвонить swapPointersInCirListDeque(q)
на страже, поэтому переместите swapPointersInCirListDeque(q)
перед оператором if
.
Если после этого вы планируете использовать backSentinel, вы должны также изменить это, поскольку теперь он находится в начале списка.Если у вас есть frontSentinel, вы можете просто добавить swapCirListDequePointers(&(q->frontSentinel),&(q->backSentinel));
к swapPointersInCirListDeque
.В противном случае вам придется передать первый узел вместе с q
и установить для него q->backSentinel
.