Мне трудно понять, как работает этот рекурсивный код, я сделал чертежи и прогонил код через gdb
.
void RecursiveReverse(struct node** headRef)
{
struct node* first;
struct node* rest;
if (*headRef == NULL) return; // empty list base case
first = *headRef; // suppose first = {1, 2, 3}
rest = first->next; // rest = {2, 3}
if (rest == NULL) return; // empty rest base case
RecursiveReverse(&rest); // Recursively reverse the smaller {2, 3} case
// after: rest = {3, 2}
first->next->next = first; // put the first element on the end of the list
first->next = NULL;
*headRef = rest; // fix the head pointer
}
Я понимаю, что при создании стека рекурсивных вызовов и после того, как список содержит только {3}, пустой базовый регистр остатка if (rest == NULL)
в первый раз равен true
.
После этого стек рекурсивных вызовов начинает разрываться и впервые набирает first->next->next = first;
, {2, 3},
Перед выполнением этой строки выведите в gdb
:
(gdb)p *first
{data = 2, next = 0x1003001f0}
(gdb) p *rest
{data = 3, next = 0x0}
После выполнения этой строки,
(gdb) p *rest
{data = 3, next = 0x1003000a0}
Продолжаем выполнение кода, нажимая first->next->next = first;
, во второй раз:
(gdb) p **head_ref
{data = 1, next = 0x1003000a0}
(gdb) p *rest
{data = 3, next = 0x1003000a0} // expected p *rest to be 2
Здесь я ожидал, что локальный указатель rest
должен указывать на узел 2, поскольку при построении стека рекурсивных вызовов **headRef
указывает на узел 1, а после строки rest = first->next;
выполняется rest
указывает на узел 2 .
После выполнения *headRef = rest;
разве headRef
не должно указывать на узел 2?
Почему локальное состояние потеряно, а остальное указывает на узел 3?