Arios
@Arios

Как работать с однонаправленными списками?

Есть структура.
struct listNode {
	int key;
	int data;
	listNode *next;
};
listNode *head;
listNode *tail;

Пока она пуста и нам нужно добавить в нее элементы.

void addItem() {
	listNode *currItem = new listNode;
	cout << "Enter key: "; cin >> currItem->key; cout << endl;
	cout << "Enter data: "; cin >> currItem->data; cout << endl;
	currItem->next = NULL;

	if (head != NULL) {
		tail->next = currItem;
		tail = currItem;
	}
	else head = tail = currItem;
}


И тут я начинаю не понимать.
У нас есть две вспомогательных структуры это структура хранящая первый элемент списка (для того, чтобы знать с чего начинать) и структура для хранения последнего элемента (не совсем понимаю для чего).
Допустим первый элемент мы добавили и т.к. это первый элемент то, ссылка на следующий элемент пуста, также мы присвоили вспомогательной структуре head (начало списка) новосозданный элемент, тоже и с tail (последний элемент).
Далее добавляем новый элемент. Т.к. начало списка уже имеется его трогаем. Только записываем указатель на следующий элемент. В общем я даже не могу объяснить чего не понимаю.
tail->next = currItem;
		tail = currItem;

Смысл записывать в переменную next указатель на следующий элемент, если потом мы полностью заменим последний элемент на новый? А если так то, первый элемент списка будет выводится как и положено, а вот последующие будут заменять друг друга. Чувствую, что вся "фишка" в указателях, но в университете нам о них будут говорить позже. А я хочу понять как это работает сейчас.
  • Вопрос задан
  • 2234 просмотра
Пригласить эксперта
Ответы на вопрос 2
ThePyzhov
@ThePyzhov
iOS Ninja
Здесь неплохо объясняются односвязные списки.
Ответ написан
@abcd0x00
У нас есть две вспомогательных структуры это структура хранящая первый элемент списка (для того, чтобы знать с чего начинать) и структура для хранения последнего элемента (не совсем понимаю для чего).

Голова нужна, чтобы получать доступ к элементам.
Хвост нужен, чтобы добавлять новые элементы.

Без хвоста, если у тебя, например, в списке есть миллион элементов, а тебе нужно добавить ещё три, ты будешь проходить миллион и добавлять первый, потом будешь проходить миллион один и добавлять второй, потом будешь проходить миллион два и добавлять третий.
Чтобы не проходить каждый раз, делается этот хвостовой указатель.

Функция addItem() у тебя плохо спроектирована. Правильнее будет передавать в неё добавляемое значение. Если ты вводишь внутри, то ты не можешь, например, взять элементы этого списка из файла или принять их по сети. Так тебе придётся писать много одинаковых списков с одинаковой функциональностью. Поэтому вводить надо снаружи, а потом введённое значение передавать на добавление.
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы