[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

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

用迭代器实现list的各种功能

#include #include #include #include using namespace std; template struct _ListNode { _ListNode* _p...
  • qingcunsuiyue
  • qingcunsuiyue
  • 2016年10月11日 15:46
  • 558

C++使用STL:慎重选择删除元素的方法

原文出自: C++使用STL:慎重选择删除元素的方法   关于要删除容器中元素要选用什么样的方法(因为不同的容器所支持或删除的方法效率不同),总结如下: 假设容器:Containerc; ...
  • iFuMI
  • iFuMI
  • 2016年05月03日 18:03
  • 1029

java List集合,迭代器iterator

一 .java的ArrayList类和Vector类 以及集合遍历 Iterator是一个迭代器接口,专门用来迭代各种Collection集合,包括Set集合和List集合。 Iterator...
  • StubbornAccepted
  • StubbornAccepted
  • 2017年01月15日 15:10
  • 1048

C++学习笔记-list遍历

// ConsoleApplication1.cpp : 定义控制台应用程序的入口点。 // #include "stdafx.h" #include #include #include #i...
  • yangwei19680827
  • yangwei19680827
  • 2014年06月07日 14:15
  • 11890

C++ List的用法(整理)

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

浅谈STL list<T>链表容器和迭代器的使用C++实现

一、今天简单的实现了STL容器里面的顺序容器list双链表里面的简单应用和迭代器的简单实现方法    包括迭代器的重载方法     二、双向链表的实现需要了解 堆得内存分配问题。堆内存是开发者使用ne...
  • whisperfor
  • whisperfor
  • 2017年05月26日 21:46
  • 319

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

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

List 和 Iterator

看别人写的源代码 把List对象 遍历出来 都是先转化成 Iterator 再来遍历,之前自己总是for遍历List 为了发现差别,上网搜索一下发现。 不管对于任何List的实现类都可以用Iterat...
  • silence1214
  • silence1214
  • 2008年12月08日 11:23
  • 6189

C++ STL学习 List iterator

环境: windows 7 x64, VC 6.0 STL List 中的 iterator存的是什么? 取元素使用 * 运算,比如 *iterSTList ,那么 iterSTList 是指针吗,...
  • ppdouble
  • ppdouble
  • 2016年02月19日 13:42
  • 3583

STL中迭代器的实现

 STL中迭代器的实现junguo           最近在看候捷先生的《STL源码剖析》,侯先生写的挺好的。但我读起来总感觉有些拗,理解起来有些费劲,可能他看问题的观点和我不一样造成的。开始的时候...
  • junguo
  • junguo
  • 2006年04月21日 01:11
  • 14860
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:[C++]List with iterator(链表的迭代器实现)
举报原因:
原因补充:

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