C ++ Связанный список следующий указатель не движется - PullRequest
0 голосов
/ 04 мая 2020

Мой код для односвязного списка выглядит следующим образом: где Мой узел имеет эти getters и setters GetNext() и SetNext() GetData() и SetData()

template <class T>
void MyList<T>::Add(const T& data){

    Node<T> *t = new Node<T>(data); // create node with givin data and set the next to null
    Node<T> *tmp = head;
    if (head == nullptr)
    {
        head = t;
    }
    else
    {
        while (tmp != nullptr)
        {
            cout << tmp->GetData()<< "\n";

            tmp = tmp->GetNext(); // GetNext() returns Node<T>* next pointer
        }

        tmp = t;
    }
}

Я сделал не перегружайте никакие операторы равенства.

Почему присвоение tmp = tmp->GetNext(); никогда не перемещается к следующему указателю !!!!


Пример минимального завершения

Вот минимальный пример, который показывает (при запуске), что добавляется только «42», но не второй элемент («12»).

#include <iostream>

template <typename T> class Node {
public:
  Node<T>(const T &data) : data_(data) {}
  Node<T> *GetNext() const { return next_; }
  T GetData() const { return data_; }

private:
  Node<T> *next_{nullptr};
  T data_{};
};

template <class T> class MyList {
public:
  void Add(const T &data) {
    Node<T> *t = new Node<T>(
        data); // create node with givin data and set the next to null
    Node<T> *tmp = head;
    if (head == nullptr) {
      head = t;
    } else {
      while (tmp != nullptr) {
        std::cout << tmp->GetData() << "\n";
        tmp = tmp->GetNext(); // GetNext() returns Node<T>* next pointer
      }
      tmp = t;
    }
  }

private:
  Node<T> *head{nullptr};
};

int main() {
  MyList<int> list;
  list.Add(42);
  list.Add(12);
}

Вот ссылка для этого примера на Godbolt: https://godbolt.org/z/KTwwGT

Ответы [ 2 ]

0 голосов
/ 04 мая 2020

https://godbolt.org/z/CdD32y

#include <cassert>
#include <iostream>
#include <iterator>

template <typename T> struct Node {
public:
  Node<T>(const T &_data) : data(_data) {}

  Node<T> *next{nullptr};
  T data{};
};

template <class T> class MyList {

private:
  Node<T> *head{nullptr};

public:
  class iterator : public std::iterator<std::input_iterator_tag, T> {
    Node<T> *node_ptr_{nullptr};

  public:
    explicit iterator(Node<T> *node_ptr) : node_ptr_(node_ptr) {}
    iterator &operator++() {
      assert(node_ptr_);
      node_ptr_ = node_ptr_->next;
      return *this;
    }
    bool operator==(iterator other) const {
      return node_ptr_ == other.node_ptr_;
    }
    bool operator!=(iterator other) const { return !(*this == other); }
    T operator*() const { return node_ptr_->data; }
  };
  iterator begin() { return iterator(head); }
  iterator end() { return iterator(nullptr); }

  void Add(const T &data) {
    Node<T> *ptr = head;
    if (!ptr) {
      head = new Node<T>(data);
      return;
    }
    while (ptr->next) {
      ptr = ptr->next;
    }
    ptr->next = new Node<T>(data);
  }
};

int main() {
  MyList<int> list;
  list.Add(42);
  list.Add(12);

  // Let's check that the right values are in `list`.
  for (const auto &value : list) {
    std::cout << value << '\n';
  }
}
0 голосов
/ 04 мая 2020

Лог c вашего кода неверен. Посмотрите на Node. _next всегда имеет значение nullptr (в конструкторе) и никогда не устанавливается ни на что другое. Так как _next всегда равно nullptr GetNext всегда возвращает nullptr.

Сначала вам нужно добавить метод SetNext к Node.

template <typename T> class Node {
public:
  Node<T>(const T &data) : data_(data) {}
  Node<T> *GetNext() const { return next_; }
  void SetNext(Node<T> *next) { next_ = next; }
  T GetData() const { return data_; }

private:
  Node<T> *next_{nullptr};
  T data_{};
};

Затем вам нужно написать версию Add, которая использует SetNext для связывания нового узла в списке.

void Add(const T &data) {
    Node<T> *new_node = new Node<T>(data);
    if (head == nullptr) {
        // list is empty, set head to the new node
        head = new_node;
    } else {
        // find the last node, so we can add the new node to it
        Node<T> last = head;
        while (last->GetNext() != nullptr) {
            last = last->GetNext();
        }
        last->SetNext(new_node);
    }
}

Непроверенный код

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...