#pragma once

#include<iostream>
using namespace std;
#include<assert.h>

template<class T>
struct __ListNode
{
    __ListNode<T>* _prev;
    __ListNode<T>* _next;
    T _data;

__ListNode(const T&x)
        :_data(x)
        , _prev(NULL)
        , _next(NULL)
    {}
};

template<class T,class Ref,class Ptr>
struct __ListIterator
{
    typedef __ListNode<T> Node;
    typedef __ListIterator<T, Ref, Ptr> Self;
    
    __ListIterator(Node* node)
        :_node(node)
    {}

__ListIterator()
    {}

Node* _node;

Ref operator*()
        {
            return _node->_data;
        }
        
        Ptr operator->()
        {
            return &_node->_data;
        }
        
        bool operator==(const Self&s)const
        {
            return _node == s._node;
        }

bool operator!=(const Self&s)const
        {
            return _node != s._node;
        }

Self& operator++()  //前置
        {
            _node = _node->_next;
            return *this;
        }

Self& operator++(int)
        {
            Self temp(_node);
            _node = _node->_next;
            return *this;
        }

Self& operator--()
        {
            _node = _node->_prev;
            return *this;
        }

Self& operator--(int)
        {
            Self tmp(_node);
            _node = _node->_prev;
            return *this;
        }
};

template<class T>
class List
{
    typedef __ListNode<T> Node;
public:
    typedef __ListIterator<T, T&, T*> Iterator;   //迭代器
    typedef __ListIterator<T, const T&, const T*> ConstIterator;   //const迭代器

Node* Buynode(const T&x)
    {
        Node* node = new Node(x);
        return node;
    }

List()
    {
        _head = Buynode(T());
        _head->_next = _head;
        _head->_prev = _head;
    }

//void PushBack(const T&x)
    //{
    //    Node* tail = _head->_prev;
    //    Node* tmp = Buynode(x);

//    tail->_next = tmp->_next;
    //    tmp->_prev = tail;

//    tmp->_prev = tail;
    //    tmp->_next = _head;
    //    //    //    tail->_next = tmp;
    //    //    //    tmp->_prev = tail;
    //    //
    //    //    //    tmp->_next = _head;
    //    //    //    _head->_prev = tmp;
    //}

void PushBack(const T&x)
    {
        Insert(End(),x);
    }

void PushFront(const T&x)
    {
        Insert(Begin(), x);
    }

void Pop()
    {
        Erase(--End());
    }

void PopFront()
    {
        Erase(Begin());
    }

void Insert(Iterator pos,const T&x)   //在pos前面插入
    {
        Node* cur = pos._node;
        Node* prev = cur->_prev;  //在prev后面插入

Node* tmp = Buynode(x);
        prev->_next = tmp->_next;
        tmp->_prev = prev;

prev->_next = tmp;
        tmp->_next = cur;
        //        tmp->_next = cur;
        //        cur->_prev = tmp;
        //
        //        prev->_next = tmp;
        //        tmp->_prev = prev;
    }

void Erase(Iterator pos)  //在pos前面删除
    {
        assert(pos != End());
        Node* cur = pos._node->_prev;  //要删除的元素
        Node* prev = cur->_prev;
        
        prev->_next = cur->_next;
        prev->_next = prev;
        delete cur;
    }

Iterator Begin()
    {
        return Iterator(_head->_next);
    }

Iterator End()
    {
        return Iterator(_head);
    }
private:
    Node* _head;
};

void main()
{
    //TestList();
    List<int> l;

l.PushBack(1);
    l.PushBack(2);
    l.PushBack(3);
    l.PushBack(4);

List<int>::Iterator it = l.Begin();
    while (it != l.End())
    {
        cout << *it << " ";
        ++it;
    }
    cout << endl;
}

模拟实现STL中的list的更多相关文章

  1. 用数组模拟STL中的srack(栈)和queue(队列)

    我们在理解stack和queue的基础上可以用数组来代替这两个容器,因为STL中的stack和queue有可能会导致程序运行起来非常的慢,爆TLE,所以我们使用数组来模拟他们,不仅可以更快,还可以让代 ...

  2. 适配器模式—STL中的适配器模式分析

    适配器模式通常用于将一个类的接口转换为客户需要的另外一个接口,通过使用Adapter模式能够使得原本接口不兼容而不能一起工作的类可以一起工作. 这里将通过分析c++的标准模板库(STL)中的适配器来学 ...

  3. 模拟实现STL库

    最近在复习STL,感觉再看的时候比刚开始学的时候通透很多.以前模拟实现了一个STL库,最近复习完又重构了一遍.代码放出来以供后面学习.如果有写的不好的地方欢迎大家批评指正. STL_List.h #p ...

  4. C++STL中的vector的简单实用

    [原创] 使用C++STL中的vector, #include <stdio.h> #include<stdlib.h> #include<vector> usin ...

  5. C++ 队列!还是要从 STL 中的说起……

    1. 前言 队列和栈一样,都是受限的数据结构. 队列遵循先进先出的存储原则,类似于一根水管,水从一端进入,再从另一端出去.进入的一端称为队尾,出去的一端称为队头. 队列有 2 个常规操作: 入队:进入 ...

  6. STL中的set容器的一点总结

    1.关于set C++ STL 之所以得到广泛的赞誉,也被很多人使用,不只是提供了像vector, string, list等方便的容器,更重要的是STL封装了许多复杂的数据结构算法和大量常用数据结构 ...

  7. STL中的next_permutation

    给定一个数组a[N],求下一个数组. 2 1 3 4 2 1 4 3 2 3 1 4 2 3 4 1 ..... 在STL中就有这个函数: 1.参数是(数组的第一个元素,数组的末尾),注意这是前闭后开 ...

  8. 3.2 STL中的函数对象类模板

    *: STL中有一些函数对象类模板,如下所示: 1)例如要求两个double类型的x 和y 的积,可以: multiplies<double>()(x,y); 该表达式的值就是x*y的值. ...

  9. C++的模板特化 和 STL中iterator_traits模板的偏特化

    C++中有类模板和函数模板,它们的定义如下所示: 类模板: template<class T1,class T2> class C { //... }; 函数模板: template< ...

随机推荐

  1. Sqli-labs less 35

    Less-35 35关和33关是大致的一样的,唯一的区别在于sql语句的不同. $sql="SELECT * FROM users WHERE id=$id LIMIT 0,1"; ...

  2. 【基本算法】 KMP文本串模式串的字符串匹配算法

    看了两个晚上的KMP,加上基本的“暴力匹配” 今晚看懂next[j]递归求解时,突然觉得算法真的好美妙,虽然觉悟的晚但晚胜过没有是吧! 我的博客都是应试性的学习笔记,不具备指导性,还是大神们写的好,例 ...

  3. ASP.NET和JSP相似方法总结(持续中。。)

    一.HTTP请求处理 1.获取GET请求数据 ASP.NET:Request.QueryString[name] JSP:request.getParameter(String name); 2.解决 ...

  4. SQL 比较乱

    --DROP TABLE T_UserInfo---------------------------------------------------- --建测试表 CREATE TABLE T_Us ...

  5. 网络处理1-异步GET请求

    前言 云计算 近几年来,云计算是一个非常热门的技术名词,很多专家认为,云计算会改变互联网的技术基础,甚至会影响整个产业的格局.可能还很多人不了解什么是云计算,简单来说,就是把用户的数据(比如文档.照片 ...

  6. 540C: Ice Cave

    题目链接 题意: n*m的地图,'X'表示有裂痕的冰块,'.'表示完整的冰块,有裂痕的冰块再被踩一次就会碎掉,完整的冰块被踩一次会变成有裂痕的冰块, 现在告诉起点和终点,问从起点能否走到终点并且使终点 ...

  7. Eclipse中WEB项目自动部署到Tomcat

    原因 很长时间没用Eclipse了,近期由于又要用它做个简单的JSP项目,又要重新学习了,虽然熟悉的很快,但记忆总是很模糊,偶尔犯错,以前很少写博客,现在感觉还是很有必要的,编程中每个人对于犯过的错误 ...

  8. 查看程序是否启动或者关闭--比如查看Tomcat是否开启!直接用ps命令查看进程就行了啊

    1.查看程序是否启动或者关闭--比如查看Tomcat是否开启!直接用ps命令查看进程就行了啊 2.Tomcat服务器和虚拟机的关系,Tomcat启动运行过程要调用系统环境变量的java_home啊,J ...

  9. android-exploitme(八):内存保护

    如果一个手机被锁屏了,但是有个app还在后台运行,这个时候你想知道些app的信息,需要分析他的内存状态. 1. 首先运行模拟器,打开emm,使得模拟器返回锁屏状态 2. 打开ddms,下载内存文件

  10. PHP使用CURL详解

    CURL是一个非常强大的开源库,支持很多协议,包括HTTP.FTP.TELNET等,我们使用它来发送HTTP请求.它给我 们带来的好处是可以通过灵活的选项设置不同的HTTP协议参数,并且支持HTTPS ...