#linked-list
#связанный список
Вопрос:
Я пытался понять, как запретить пользователю вводить повторяющееся значение, и, честно говоря, я так сильно борюсь за ответ, который, вероятно, действительно прост, как только я его увижу, но я не могу. Функция приведена ниже вместе с узлом структуры. Я был бы очень признателен, если бы кто-нибудь мог мне здесь помочь.
struct node { int data = -1; node * current; node * next; }; node * start = NULL; ``` void addNode(struct node amp; n) { if (n.data == -1) { cout lt;lt; "List not created yet." lt;lt; endl; } else { node * temp; node * temp2; temp = new node; cout lt;lt; "What number would you like to enter:" lt;lt; endl; cin gt;gt; temp -gt; data; cout lt;lt; endl; int value; value = temp -gt; data; temp = start; while (temp != NULL) { if (temp -gt; data == value) { cout lt;lt; "Duplicate Number!" lt;lt; endl; } else { temp = temp -gt; next; } temp = temp -gt; next; } if (start == NULL) { start = temp; } else { temp2 = start; while (temp2 -gt; next != NULL) { temp2 = temp2 -gt; next; } temp2 -gt; next = temp; } } }
Комментарии:
1. Вам придется просмотреть список, чтобы проверить, но производительность быстро ухудшится.
2. Связанный список-это неправильная структура данных для этого. Вам, наверное, следовало бы использовать карту.
3. К сожалению, это для задания, и они хотели, чтобы я использовал связанный список
4. ОК. Затем каждый раз просматривайте список, чтобы увидеть, содержит ли он уже то, что вводит пользователь. Вы можете добавить набор для проверки на наличие ошибок вместо циклического перебора, если это не нарушает параметры задания.
Ответ №1:
Вот несколько замечаний по вашему коду:
- Не создавайте
start
глобальную переменную. Вместо этого сделайте его локальнымmain
и передайте его в качестве аргументаaddNode
функции - Используйте
nullptr
вместоNULL
- Не запрашивайте ввод данных пользователя внутри
addNode
функции. В соответствии с принципом разделения задач, держите аспекты ввода-вывода за пределами этой функции. - Вместо этого передайте значение в качестве аргумента
addNode
- Вы должны относиться к узлу по-другому, когда он имеет значение -1. Пустой список-это не список с одним узлом, имеющим значение -1. Пустой список-это нулевой указатель.
- Даже если список пуст, должна быть возможность добавить первый узел с помощью этой функции
- Используйте более описательные имена переменных.
n
дляnode
примера не очень понятно. Такжеtemp
иtemp2
не очень понятны. Один из двух-это вновь созданный узел, поэтому его можно назватьnewNode
. - После того как вы создали новый узел и присвоили ему ссылку
temp
, вы присваиваете новое значениеtemp
withtemp = start
, и таким образом вы потеряли (и допустили утечку) вновь созданный узел. - В вашем цикле вы будете выполняться
temp = temp-gt;next
дважды, если значение не совпадает. Это, конечно, следует делать только один раз за итерацию. - Даже когда ваш код находит дубликат и выводит сообщение, он все равно продолжает процесс. Вместо этого вы должны остановить процесс, а не создавать узел (или, если вы это уже сделали: утилизируйте его
delete
). - Жаль, что вам нужно снова просмотреть список с самого начала, чтобы найти последний узел и добавить туда новый узел. Вы должны быть в состоянии сделать это в первом цикле, где вы ищете дубликат.
Вот исправление:
bool addNode(node* amp;start, int value) { node * current = start; if (start != nullptr) { while (current-gt;data != value amp;amp; current-gt;next != nullptr) { current = current-gt;next; } if (current-gt;data == value) { return false; // duplicate! } } node* newNode = new node; newNode-gt;data = value; if (start != nullptr) { current-gt;next = newNode; } else { start = newNode; } return true; }
Обратите внимание, что эта функция возвращает логическое значение: если true
тогда узел был вставлен. Другой случай означает, что был дубликат.
Ваша основная функция может выглядеть следующим образом:
int main() { // define start as local variable node * start = nullptr; // Use nullptr instead of NULL while (true) { int value; // Don't do I/O together with list-logic cout lt;lt; "What number would you like to enter:" lt;lt; endl; cin gt;gt; value; cout lt;lt; endl; if (value == -1) break; if (!addNode(start, value)) { cout lt;lt; "Duplicate Number!" lt;lt; endl; } } }
Комментарии:
1. Это ответ на ваш вопрос?