Операции над разными типами данных элемента линейного односвязного списка

166
16 августа 2021, 15:30

К примеру у меня описан элемент линейного списка:

struct Node{
  string Adres;
  double square;
  Node *next;
};

Описан класс,производящий операции над элементами линейного списка

class Actions{
private:
    Node *start;//Указатель на начало списка
public:
    Actions();
    ~Actions();
    void insBack();//Добавление в элемента в конец 
    void inFront();//Добавление элемента в начало       
};

У меня возникли трудности с составлением алгоритма(то есть с написанием функций insBack() и insFront()) добавления элемента в конец и в начало в котором подчёркиваю - несколько типов данных то есть string и int.

Answer 1

Что содержит структура узла, не имеет значения. Важно, чтобы обьекты этой структуры инициализировались в class Actions нужным образом, а обьекты содержащийся в структуре узла инициализировались конструкторами этой структуры. Опишем структуру так:

struct Node {
    std::string Adres;
    double square;
    Node* next;
    Node(const std::string& s, const double d)
        : Adres(s), square(d), next(nullptr) {}
    Node() : Node("", 0) {}
};

Класс Actions(не понятно с каких соображений вы так назвали) должен обеспечить доступ к началу списка, иначе сможем только добавлять, а нужно еще использовать(например выводить) эти обьекты. Опять же: конструктор должен инициализировать свои члены(в данном случаи один указатель), а деструктор освобождать всю память. Как добавлять в начало и в конец?.. Попробуйте все нарисовать на бумаге(обьекты в виде кружочков, указатели в виде стрелочек), и все получится. Для начала помогу реализацией класса. Вот ваш класс(хоть я и написал бы совсем по другому).

class Actions {   
    Node* start;//Указатель на начало списка
public: 
    Actions() : start(nullptr) {}
    ~Actions() {
        Node* cur = start;
        while (cur) {
            cur = start->next;
            delete start;
            start = cur;
        }
    }       
    void insBack(const string& s, const double d) {     
        if (!start) {
            start = new Node(s, d);
            return;
        }
        Node* cur = start;
        while (cur->next) 
            cur = cur->next;
        cur->next = new Node(s, d);
    }
    void inFront(const string& s, const double d) {
        Node* new_node = new Node(s, d);
        if (!start)
            start = new_node;
        else
            new_node->next = start;
    }
    //обеспечим доступ к началу списка
    Node* begin() const { return start; }
};

Т.е. чтобы добавить обьекты, нужно знать какие обьекты добавлять, т.е. нужно передать в функцию или сам обьект или обьекты, которые могут служить для создания (конструирования) такого обьекта.

Ну а простая программа может выглядеть так:

Actions list;
list.inFront("first", 0.1);
list.insBack("last", 1.0);
list.insBack("end", 10.01);
for (Node* p = list.begin(); p; p = p->next) {
    cout << p->Adres << ' '
        << p->square << std::endl;      
}
Answer 2

Структуру данных нужно отделить от указателя на следующий Node. Тогда структуру данных передаём в функцию добавления узла. А сам класс списка будет сам делать узлы на своё усмотрение. Делаем вспомогательные функции , возвращающие на первый и на последний узел списка. (Всегда нужны.) После этого делать функцию станет проще.

// g++ -Wall -Wextra -std=c++11 actions.cpp -o actions
# include <string>
using std::wstring;
# include <iostream>
using std::wcout;
struct  Data {
  wstring Adres;
  double square;
};
class Actions{
public:
    Actions(void){}
    ~Actions(void);
    void insBack(Data);//Добавление в элемента в конец 
    void inFront(Data d){start = new Node{d,start};}//Добавление элемента в начало       
  struct Node{
    Data  d ;
    Node *  next;
  };
  Node * first(void){return start;}    
  Node * last(void);    
private:
  Node *start{nullptr};//Указатель на начало списка
};
Actions::Node * Actions::last(void){
  Node * i = start ;
  Node * r = nullptr ;
  while(i){
    r = i ;
    i=i->next;  }
  return r ; }  
Actions::~Actions(void){
  while(start){
    Node * next = start->next;
    delete  start ;
    start = next ; } }
void Actions::insBack(Data d){
  Node * l =last();
  Node **ps;
  if(l)  ps = &(l->next);
  else  ps = & start;
  (*ps)= new Node{d,nullptr};}    
int main(void){
  setlocale(LC_ALL,"");
  Actions a ;
  a.inFront(Data{L"Фрунзе",12});
  a.insBack(Data{L"Ленина",7});
  for(Actions::Node * i = a.first();i;i=i->next)
    wcout<<L"адрес = "<<i->d.Adres<<L" , квартал = "<<i->d.square<<std::endl;  }
READ ALSO
winapi c++ получить из списка(combobox) текс и поместить в edit

winapi c++ получить из списка(combobox) текс и поместить в edit

идея такая нужно при нажатии кнопки взять текст из combobox и поместить в edit и вывести сообщение в виде модального окна, компилится без ошибок...

359
Несколько таблиц с общим хедером

Несколько таблиц с общим хедером

Имеется следующий макет

155
Error: Stray end tag

Error: Stray end tag

Что нужно исправить в данном коде чтобы он стал валидным и бузе ошибок?

264