адрес узла стека
#include <iostream>
using namespace std;
class List
{
public:
List();
class Node {
public:
Node* pNext;
int data;
Node(int data, Node* pNext = nullptr) {
this->data = data;
this->pNext = pNext;
}
};
int Size;
Node *Top;
void push_back(int data);
void lout(List&lst);
void lin(List &lst);
void firstTask(List& lst1, List& lst2);
};
List::List() {
Size = 0;
Top = nullptr;
}
void List::push_back(int data) {
if (Top == nullptr) {
Top = new Node(data);
}
else {
Node* current = this->Top;
while (current->pNext != nullptr) {
current = current->pNext;
}
current->pNext = new Node(data);
}
Size++;
}
void List::lout(List&lst) {
cout << "Your list:" << endl;
Node* current = Top;
for (int i=0;i<Size;i++) {
cout << current->data << " ";
current = current->pNext;
}
cout << endl;
}
void List::lin(List&lst) {
cout << "How many time you want to fill in elements of list? Do not enter not integer data type!" << endl;
int answer;
cin >> answer;
for (int i = 0; i < answer; i++) {
int input;
cin >> input;
lst.push_back(input);
}
}
void List::firstTask(List&lst1,List&lst2) {
List tmp;
}
int main() {
List lst1;
lst1.lin(lst1);
lst1.lout(lst1);
List lst2;
lst2.lin(lst2);
lst2.lout(lst2);
lst2.firstTask(lst1,lst2);
}
Как мне сделать так, чтобы Тор в методе firstTask указывал на крайний элемент списка, а не на первый?
Ответы (1 шт):
Не говоря о других недостатках:
Плохо, что каждый раз, добавляя в конец, объект начинает искать этот конец, перебирая свои элементы от начала до конца. А значит для n элементов, количество перебора этих элементов будет считаться математической прогрессией. Лучше, когда класс просто знает место своего последнего элемента. Поэтому, помимо Node* Top храните и Node* end. Тогда будете иметь:
class List
{
public:
//...
int Size;
Node* Top;
Node* end;
//...
};
List::List() {
Size = 0;
Top = end = nullptr;
}
void List::push_back(int data) {
if (Top == nullptr) {
Top = new Node(data);
end = Top;
}
else {
Node* current = end;
end = new Node(data);
current->pNext = end;
}
Size++;
}
Но еще нужно написать как добавить в начало, чтобы могли реализовать написание не только описанной вами функции, но и для многих других задач:
void List::push_front(const int data)
{
if (Top == nullptr) {
Top = new Node(data);
end = Top;
}
else {
Node* curr = Top;
Top = new Node(data);
Top->pNext = curr;
}
}
Теперь можете написать вашу функцию:
void firstTask(List& lst1, List& lst2) {
List tmp;
List::Node* curr = lst1.Top;
while (curr) {
tmp.push_front(curr->data);
curr = curr->pNext;
}
//теперь записать из lst2 в lst1 и из tmp в lst2
//это лучше сделать в конструкторе копирования и в операторе присваивания
}
Но это все не будет ничего стоить, если вы не написали деструктор класса, и каждый раз будет иметь место утечка памяти. А еще нужно написать конструктор копирования и оператор присваивания. Тогда вы можете просто присвоить один список другому или инициализировать список другим списком, и пользоваться классом станет легче и безопасней с точки зрения не допущения логических ошибок.