gpt4 book ai didi

c++ - 链表迭代器实现 C++

转载 作者:行者123 更新时间:2023-11-30 04:49:25 25 4
gpt4 key购买 nike

我在 C++ 中创建了一个链表并想为它实现一个迭代器以便我可以进行范围循环:for (const int& i : list)其中 Linked_List<int> list; .

我的想法是创建 Iterator作为 Linked_List 的一部分像这样上课:

这是我到目前为止得到的:

template <typename T>
class Linked_List
{
public:
struct Iterator;
struct Node;
public:
Linked_List();
~Linked_List() noexcept(false);
Linked_List(const Linked_List&) = delete;
Linked_List(Linked_List&&) = delete;
Linked_List& operator=(const Linked_List&) = delete;
Linked_List& operator=(Linked_List&&) = delete;

void push_back(T);
void push_front(T);
void pop_back();
void pop_front();
bool empty() const;
T back() const;
T front() const;
//void swap(T, T);
//void insert(Iterator, T);
//void erase(Iterator);
//Iterator begin() const;
//Iterator end() const;
private:
Node* head;
Node* tail;
};

template<typename T>
struct Linked_List<T>::Node
{
Node() : prev(nullptr), next(nullptr) {}
Node(T t) : value(t), prev(nullptr), next(nullptr) {}
Node* prev;
Node* next;
T value;
};
  1. 这是一个好方法吗?
  2. 我是否应该在递增列表时进行错误检查以检查 current->next == tail 是否存在? ?如果是这样,我该怎么做?因为我的迭代器没有带尾部的列表对象。

编辑:我不确定如何实现 struct Iterator; ,我在弄清楚如何将它与列表连接时卡住了,以便我可以检查从迭代器返回的当前节点是否等于列表中的尾部,在 Linked_List Iterator end() const 中。方法。

假设我已经为这样的迭代器实现了所有必要的运算符:

struct Iterator
{
T& operator*() const { return current->value; }
bool operator!=(const Iterator& rhs) { return (*_current != rhs._current); }
Iterator& operator++()
{
current = current->next;
return *this;
}
};

我将如何实现 Iterator Linked_List<T>::begin() const;end()现在?

我想象一个假想的用户像这样创建一个迭代器对象: Linked_List<int>::Iterator it;

一个想法是有一个没有参数的公共(public)构造函数和一个将节点作为参数的私有(private)构造函数 _current将被设置为Linked_List作为 friend 上课。

最佳答案

一些注意事项。

声明Node 有两个选项和 Iterator .在列表类中为 List<T>::Node或外部为 Node<T> .这在一定程度上是品味问题。但是从工程角度来看,嵌套类的符号名称更长,因此您的调试信息更大。此外,当嵌套类也是模板时,如果/在必要时更难以专门化它们(因为这需要首先完全专门化封闭模板),但这里不是这种情况。

当一个列表节点被用作列表头和尾时,它会导致更优雅的代码。空列表是一个节点,其 nextprev指向自身。 push_front附加到 list.next它指向第一个节点或它自己。 push_back将节点附加到 list.prev它指向最后一个节点或它自己。插入/删除节点时,无需对第一个和最后一个节点进行特殊处理。例如。 :

struct Node {
Node *next_, *prev_;

Node()
: next_(this), prev_(this)
{}

~Node() {
unlink();
}

void push_back(Node* n) {
n->next_ = this;
n->prev_ = prev_;
prev_->next_ = n;
prev_ = n;
}

void unlink() {
Node *next = next_, *prev = prev_;
next->prev_ = prev;
prev->next_ = next;
next_ = this;
prev_ = this;
}
};

在上面,Node只需要两个操作就可以维护一个列表。不仅如此,Node本身是一个极简列表,可用于侵入式 列表(在析构函数中使用自动取消链接)。注意如何使用 this检查 nullptr不必要的 - Node始终是有效列表。

错误检查应该只在 Debug模式下进行(例如使用 assert )。否则,这些检查会通过不必要的运行时检查来惩罚正确的应用程序。


这是一个基于您的想法的最小工作示例:

template<class T>
class List;

class Iterator;

class Node {
friend class Iterator;
template<class T> friend class List;

protected:
Node *next_, *prev_;

void push_back(Node* n) {
n->next_ = this;
n->prev_ = prev_;
prev_->next_ = n;
prev_ = n;
}

void unlink() {
Node *next = next_, *prev = prev_;
next->prev_ = prev;
prev->next_ = next;
next_ = this;
prev_ = this;
}

public:
Node()
: next_(this), prev_(this)
{}

~Node() { unlink(); }
};

class Iterator {
protected:
Node* node_;

Iterator(Node* node)
: node_(node)
{}

public:
Iterator& operator++() {
node_ = node_->next_;
return *this;
}

bool operator==(Iterator b) const { return node_ == b.node_; }
bool operator!=(Iterator b) const { return node_ != b.node_; }

// Implement the rest of iterator interface.
};

template<class T>
class List {
class NodeT : public Node {
friend class List<T>;
T value_;
NodeT(T t) : value_(t) {}
};

template<class U>
class IteratorT : public Iterator {
friend class List<T>;
NodeT* node() const { return static_cast<NodeT*>(node_); }
public:
U& operator*() const { return node()->value_; }
U* operator->() const { return &node()->value_; }
operator IteratorT<U const>() const { return node_; } // iterator to const_iterator conversion
IteratorT(Node* node) : Iterator{node} {}
};

Node list_;

public:
using iterator = IteratorT<T>;
using const_iterator = IteratorT<T const>;

~List() { clear(); }

bool empty() const { return list_.next_ == &list_; }

iterator begin() { return list_.next_; }
iterator end() { return &list_; }

void push_back(T t) { list_.push_back(new NodeT(t)); }
void erase(const_iterator i) { delete i.node(); }

void clear() {
while(!empty())
erase(begin());
}

// Implement the rest of the functionality.
};

int main() {
List<int> l;
l.push_back(1);
l.push_back(2);
l.push_back(3);
for(auto elem : l)
std::cout << elem << ' ';
std::cout << '\n';
}

关于c++ - 链表迭代器实现 C++,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55402803/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com