(Извините, мой предыдущий ответ был неверным. Я пропустил, что вы используете q
непосредственно в своей вспомогательной функции.)
Ваша функция loop_delete
ищет соответствующий узел, но когда находитСоответствующий узел, кажется, делает необоснованные предположения.Если соответствующий узел n
находится в конце очереди (n.next = None
), он предполагает, что это был единственный элемент очереди (он устанавливает q.head
и q.tail
в None
).Если совпадающий узел не находится в конце очереди, кажется, предполагается, что совпадающий узел был в начале очереди (он устанавливает q.head
в n.next
).
В качестве отдельногопроблема, это не разумный тест:
n.next = Some n
Он проверяет, указывает ли указатель next
на n
на n
.Если вы просто хотите узнать, указывает ли n.next
на какой-либо узел, вы можете сказать n.next <> None
.
В качестве еще более общего комментария при удалении из односвязного списка вам, как правило, необходимо отслеживать два узла.интересующий вас узел и предыдущий узел в списке.Когда вы найдете узел, который хотите удалить, вам нужно изменить значение next
предыдущего узла.
Вам не нужно думать о указателях при кодировании в OCaml, но это не так уж и неправильно.воспринимать None
как нулевой указатель и Some n
как указатель на узел n
.Для первого вызова у вас нет предыдущего узла, поэтому вызов может выглядеть следующим образом:
loop_delete elt None q.head
Когда вы хотите перейти к следующему узлу внутри loop_delete
, вызов может выглядеть примерно так:this:
loop_delete elt no n.next
По сути вы передаете два значения типа 'a qnode option
.Они представляют предыдущий узел и текущий узел.Если предыдущего узла нет, то это потому, что вы находитесь в начале списка.Если текущего узла нет, то это потому, что вы находитесь в конце списка.
Извините за бесполезные комментарии ранее.Может быть, это немного лучше.