[C++]List with iterator(链表的迭代器实现)

原创 2016年05月30日 16:21:34

List with iterator(链表的迭代器实现)

我们都知道STL容器内部都有相应的迭代器,本文主要讨论的就是链表内部的迭代器实现。

测试代码

#include <iostream>
#include <string>
using namespace std;
int main() {
    list<int> li;
    cout << "test size" << endl;
    cout << li.size() << endl;
    cout << (li.empty() ? "empty" : "not empty") << endl;
    int n;  // n >= 3
    cout << "test push and pop" << endl;
    li.push_back(1);

    cout << li << endl;

    li.pop_back();
    cout << li << endl;
    li.push_front(1);
    cout << li << endl;
    li.pop_front();
    cout << li << endl;
    li.push_back(1);
    cout << li << endl;
    li.pop_front();
    cout << li << endl;
    li.push_front(1);
    cout << li << endl;
    li.pop_back();

    cin >> n;
    for (int i = 0; i < n; i++) {
        int tmp;
        cin >> tmp;
        li.push_back(tmp);
        li.push_front(tmp);
    }
    cout << li.size() << endl;
    cout << li << endl;
    li.pop_back();
    li.pop_front();
    li.pop_front();
    cout << li << endl;
    cout << "front : " << li.front() << endl;
    cout << "back : " << li.back() << endl;
    cout << (li.empty() ? "empty" : "not empty") << endl;

    cout << "test begin and end" << endl;
    list<int>::iterator it = li.begin();
    while (it != li.end()) {
        cout << it->data << " ";
        it++;
    }
    cout << endl;

    cout << "test insert and erase and ++ --" << endl;
    it = li.begin();
    cout << *(li.insert(it, 100)) << endl;
    it = li.end();
    cout << *(li.insert(it, 200)) << endl;
    cout << li << endl;
    it = li.begin();
    cout << *(li.erase(++it)) << endl;
    it = li.begin();
    it++;
    cout << *(li.erase(it)) << endl;
    cout << li << endl;
    it = li.begin();
    it++;
    it--;
    li.insert(it, 101);
    it = li.begin();
    ++it;
    --it;
    li.insert(it, 99);
    cout << li << endl;
    it = li.begin();
    *it = 90;

    cout << "test constructor" << endl;
    list<int> li2(5, 9);
    list<int> li3(li);
    it = li.begin();
    list<int>::iterator it2 = it;
    ++(++(++it2));
    list<int> li4(li.begin(), li.end());
    list<int> li5(it, it2);
    cout << li2 << endl;
    cout << li3 << endl;
    cout << li4 << endl;
    cout << li5 << endl;

    return 0;
}

实现:

template<class T>
class list {
public
:
    struct Node {      // list cell
        T data;
        Node *next, *prev;
        Node(T s = 0, Node* n = NULL,
             Node* p = NULL) : data(s), next(n), prev(p) {
        };  // suggest u to use the constructor
    };
    class iterator {
    public
    :
        friend class list;  // suggest u to use friend class
        explicit iterator(Node* p = 0) {
            current = p;
        }
        iterator(const iterator& other) {
            current = other.current;
        }
        iterator& operator++() {
            current = current->next;;
            return *this;
        }
        iterator& operator--() {
            current = current->prev;
            return *this;
        }
        iterator operator++(int) {
            iterator temp = *this;
            ++(*this);
            return temp;
        }
        iterator operator--(int) {
            iterator temp = *this;
            --(*this);
            return temp;
        }
        Node* operator->() {
            return current;
        }
        T& operator*() {
            return current->data;
        }
        bool operator==(const iterator & rhs) const
        { return current == rhs.current; }
        bool operator!=(const iterator & rhs) const
        { return !( *this == rhs ); }
        // u can use iterator as Node* sometimes
        operator Node * () {return current;}  // conversion;
    private
    :
        Node* current;  // current listelem or 0;
    };
private
:
    Node *head, *tail;  // head and tail
    int _size;
    void init() {
        _size = 0;
        head = new Node();
        tail = new Node();
        head->next = tail;
        tail->prev = head;
    }
public
:
    list() {
        init();
    }
    ~list() {
        clear();
        delete head;
        delete tail;
    }
    list(size_t n_elements, const T& c) {
        init();
        for (int i = 0; i != n_elements; i++) {
            push_back(c);
        }
    }
    list(const list& x) {
        init();
        for (iterator iter = x.begin(); iter != x.end(); iter++) {
            push_back(*iter);
        }
    }
    list(iterator b, iterator e) {
        init();
        for (iterator iter = b; iter != e; iter++) {
            push_back(*iter);
        }
    }
    iterator begin() const {
        return iterator(head->next);
    }
    iterator end() const {
        return iterator(tail);
    }
    size_t size() const {
        return _size;
    }
    void push_front(const T& c) {
        insert(begin(), c);
    }
    void push_back(const T& c) {
        insert(end(), c);
    }
    void pop_front() {
        erase(begin());
    }
    void pop_back() {
        erase(--end());
    }
    iterator insert(iterator position, const T& val) {
        Node* p = position.current;
        _size++;
        return iterator(p->prev = p->prev->next = new Node(val, p, p->prev));
    }
    iterator erase(iterator position) {
        Node* p = position.current;
        iterator retVal(p->next);
        p->prev->next = p->next;
        p->next->prev = p->prev;
        delete p;
        _size--;
        return retVal;
    }
    bool empty() const {
        return _size == 0;
    }
    T& front() {
        return *begin();
    }
    T& back() {
        return *(--end());
    }
    void clear() {
        while (!empty()) {
            pop_front();
        }
    }
    friend ostream& operator << (ostream& out, const list& x) {
        if (x.empty()) {
            out << "[ ]";
            return out;
        }
        out << "[ ";
        for (iterator iter =
             x.begin(); iter != (x.end())->prev; iter++) {
            out << *iter << " ";
        }
        out << (x.end())->prev->data;
        out << " ]";
        return out;
    }
};

这个实现版本中最特别的地方就在于:

    void init() {
        _size = 0;
        head = new Node();
        tail = new Node();
        head->next = tail;
        tail->prev = head;
    }

给首尾节点都分配的内存。这样做的好处就是可以避开每一次增加元素时都要考虑head有没有空间。最重要的是,可以实现end()和rbegin()提供的作为哨兵的地址。但需要注意的是,在析构函数中还需要释放掉这两个内存,不然会出现内存泄露。

其次,这个代码看起来非常的简洁,原因就在于,所有关于增加的函数全部都有insert来完成,这符合编写代码中的2-8原则(80%时间完成20%的代码),但同样也会出现因为调用函数而造成的额外开销。

最后代码实现结果

List

版权声明:本文为博主原创文章,未经博主允许不得转载。 举报

相关文章推荐

C++ List的用法(整理)

Lists将元素按顺序储存在链表中. 与 向量(vectors)相比, 它允许快速的插入和删除,但是随机访问却比较慢. assign() 给list赋值  back() 返回最后一个元素 ...
  • lskyne
  • lskyne
  • 2013-08-27 23:04
  • 131062

C++ STL学习 List iterator

环境: windows 7 x64, VC 6.0 STL List 中的 iterator存的是什么? 取元素使用 * 运算,比如 *iterSTList ,那么 iterSTList 是指针吗,...

精选:深入理解 Docker 内部原理及网络配置

网络绝对是任何系统的核心,对于容器而言也是如此。Docker 作为目前最火的轻量级容器技术,有很多令人称道的功能,如 Docker 的镜像管理。然而,Docker的网络一直以来都比较薄弱,所以我们有必要深入了解Docker的网络知识,以满足更高的网络需求。

STL之list函数详解

本文主要介绍了list的内部结构,list特殊的能力,以及list所支持操作函数,并在最终给出list应用实例。

C++中STL迭代器的种类和简介

C++中STL迭代器的种类和简介 标签: c++vectoroutput算法listinput 2012-03-21 06:37 1494人阅读 评论(0) 收藏 举报  分类:...

c++迭代器介绍

迭代器的简介 (1):迭代器类似于指针类型,它也提供了对对象的间接访问。 (2):指针是c语言中就有的东西,迭代器是c++中才有的,指针用起来灵活高效,迭代器功能更丰富些。 (3):迭代器提供一...

C++中防止STL中迭代器失效——map/set等关联容器——vector/list/deque等序列容器—如何防止迭代器失效—即erase()的使用

序列性容器::(vector和list和deque)   erase迭代器不仅使所有指向被删元素的迭代器失效,而且使被   删元素之后的所有迭代器失效,所以不能使用erase(...

STL中list的容器使用介绍

STL中list的使用:   STL中的list就是一双向链表,可高效地进行插入删除元素。现总结一下它的操作。   文中所用到两个list对象c1,c2分别有元素c1(10,20,30)  c2(40...

JAVA链表中迭代器的实现

来自java数据结构与算法一书 如果插入节点的话current指向插入的元素,如果删除掉当前节点的话,那么current=current.next; 下面是完整代码: {CS...

(数据结构与算法分析 二)------单链表的实现,使用链表迭代器

Java实现链表能够很好的封装对指针的实现,让用户使用的时候不会感受到指针的繁琐,但是可能会带来效率的降低。        这个链表是一个单链表的实现,使用了链表迭代器,刚开始看的时候感觉有些很不舒...

vector,list,map,迭代器iterator

//////////////////////////////////////////////////////////////////////////vector #include     #in...
返回顶部
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

(最多只允许输入30个字)