Здравствуйте. Столкнулся с такой задачей. Нужно инициализировать односвязный список, ввести его с клавиатуры и вывести. Перепробовал все способы. Но почему-то при выводе списка выводится только первый элемент. Может кто знает как исправить?
Заранее благодарю
P.S. Данные в списке представлены в виде структуры. И заранее не известно сколько пользователь введет элементов списка
#include <iostream>
#include <Windows.h>
using namespace std;
//List #1
struct A
{
int cyfra;
char symbol;
};
struct List
{
A a;
List* next;
};
void Init(List** b)
{
(*b) = new List;
List *end = NULL;
for (int i = 0; ; i++) {
if (i == 0)
{
cin >> (*b)->a.cyfra >> (*b)->a.symbol;
(*b)->next = NULL;
end = (*b);
}
else {
end->next = new List;
cin >> end->a.cyfra >> end->a.symbol;
end = end->next;
end->next = NULL;
}
if (GetAsyncKeyState(VK_RETURN))break;
}
}
void Print(List *b)
{
List *print = b;
cout << endl;
while (print != NULL)
{
cout << print->a.cyfra << print->a.symbol << " ";
print = print->next;
}
}
void main()
{
//Initial L prim
List* begin = NULL;
Init(&begin);
cout << "List: ";
Print(begin);
system("pause");
}
Односвязные списки это очень простая штука. Главное, чтобы код, работающий с ними, был структурирован в соответствии с шагами алгоритма (КО -)).
Вашу задачу совершенно логично решает вот такой main
:
int main () {
// Получить заполненный список
List *list = get_list();
// поэлементно распечатать его
cout << "List:\n";
for (List *p = list; p; p = p->next)
cout << p->a.cyfra << p->a.symbol << ' ';
}
Вы совершенно правильно решили, что при последовательном построении списка в порядке поступления его элементов, нужно запомнить адрес первого элемента списка и иметь указатель на его последний элемент.
Вот так может выглядеть функция, которая последовательно строит список:
List *get_list () {
List *head = get_AList_item(), // взять первый элемент списка
*tail = head; // сейчас он же и последний в списке
if (head)
while ((tail->next = get_AList_item())) // обратите внимание, здесь мы автоматически получаем обнуленный указатель на следующий у последнего элемента списка
tail = tail->next;
return head; // тут накопили весь список
}
Думаю, что функцию (get_AList_item()
), реализующую ввод данных и выделяющую память под каждый элемент вы сами легко напишете.
В качестве простого ее примера:
List * get_AList_item () {
List *elem = new List;
if (cin >> elem->a.cyfra >> elem->a.symbol)
return elem;
delete elem;
return 0;
}
Как видите, вся прелесть простых задач, реализуемых с односвязными списками в том, что на каждом шаге декомпозиции программы, благодаря тривиальности односвязных списков, мы имеем функции с минимумом строк кода, оперирующих списком. Но есть и оборотная сторона медали -- далеко не все операции с такими списками имеют эффективные алгоритмы.
else {
end->next = new List;
end = end->next; //
cin >> end->a.cyfra >> end->a.symbol; // тут
end->next = NULL;
такой вариант пробуйте.
И еще, в любом случаи правильнее будет в конструкторе класса list
сразу инициализировать next
нулем, чтоб в коде каждый раз не делать это в ручную...
struct A
{
int cyfra;
char symbol;
};
struct List
{
A a;
List* next;
List() : next(0) {a.cyfra = 0; a.symbol = '8';}
~List() {delete next;}
};
void Init(List*& b)
{
b = new List;
List *end = b;
while (cin >> end->a.cyfra >> end->a.symbol) {
end->next = new List;
end = end->next;
}
}
void Print(List *b)
{
List *print = b;
cout << endl;
while (print->next)
{
cout << print->a.cyfra << " " << print->a.symbol << " ";
print = print->next;
}
}
int main()
{
List* begin = NULL;
Init(begin);
cout << "List: ";
Print(begin);
return 0;
}
Этот код работает как надо...
end->next = new List;
cin >> end->next->a.cyfra >> end->next->a.symbol;
Айфон мало держит заряд, разбираемся с проблемой вместе с AppLab
Перевод документов на английский язык: Важность и ключевые аспекты
Какие существуют виды рекламных бордов и как выбрать подходящий?
Суть: при нажатии одной кнопки на форме динамически создаются лейблы с уникальными именами При нажатии второй кнопки, должен выделять определенный...
Добрый день! Излагаю суть дела: есть проверка, согласно которой пользователь не должен ввести символы или ещё какую-то ерунду вместо обычного...
В учебниках по C++ пишут, что динамические массивы нужны, когда заранее неизвестны размеры этих массивовПотом идет объяснение, как выделять...
1-2 дня назад я задал вопрос, но не совсем корректный, поэтому сейчас я постараюсь поставить его более правильноДопустим, есть игра, в которой...