#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. JobClient学习------作业提交与初始化

    public static void main(String[] args) throws Exception { Configuration conf = new Configuration(); ...

  2. Altium Designer Summer 09创建半圆焊盘方法

    关于异形焊盘的创建,可参看下面的半圆PAD的制作:1.新建一个PCB文件,然后在里面画一个半圆的Arc,即Place放置(P)>Arc,并且要将其开口处 封闭,即可用Place   放置(P)& ...

  3. linux权威指南 简记

    /proc 目录,linxu系统以文件形式存放进程信息,这是一个虚拟的文件系统,不占有任何磁盘空间,当读取该文件系统时,系统内核会拦截动作,并动态产生文件与目录的内容 查看该文件夹,会发现很多已数字命 ...

  4. iOS KVC,KVO

    链接(写得不错,着重kvc):http://www.cocoachina.com/industry/20140224/7866.html 链接:http://www.cnblogs.com/kensh ...

  5. POJ 2105

    #include <iostream> #include <cmath> #include <string> using namespace std; int ma ...

  6. lightoj 1397 - Sudoku Solver

    思路:每次找出可能情况最少的位置枚举可能情况!!! poj2676和这题一样不过poj数据比较水,很容易过. 代码如下: #include<iostream> #include<cs ...

  7. WCF分布式开发步步为赢(5)服务契约与操作重载

    继上一节WCF分布式开发步步为赢系列的(4):WCF服务可靠性传输配置与编程开发,本节我们继续学习WCF分布式开发步步为赢的第(5)节:服务契约与操作重载.这里我们首先讲解OOP面向对象的编程中方法重 ...

  8. Android Non-UI to UI Thread Communications(Part 1 of 5)

    original:http://www.intertech.com/Blog/android-non-ui-to-ui-thread-communications-part-1-of-5/ ANDRO ...

  9. iOS开发--git

    http://blog.chinaunix.net/uid-26495963-id-3474178.html 相关知识 gnu interactive tools 一句话概括git: Git is a ...

  10. 【原创】【ViewPager+Fragment】ViewPager中切换界面Fragment被销毁的问题分析

    ViewPager中切换界面Fragment被销毁的问题分析   1.使用场景 ViewPager+Fragment实现界面切换,界面数量>=3   2.Fragment生命周期以及与Activ ...