STL容器-list的使用&简单C++实现

1.容器是STL的重要组成部分之一,分为关联容器和顺序容器

c++中两种类型的容器:顺序容器和关联容器, 

  • 顺序容器主要有:vector、list、deque等。
      其中

    1.vector表示一段连续的内存地址,基于数组的实现
    2.list表示非连续的内存,基于链表实现。
    3.deque与vector类似,但是对于首元素提供删除和插入的双向支持。

  • 关联容器主要有map和set。

    1.map是key-value形式的,set是单值。map和set只能存放唯一的key值,multimap和multiset可以存放多个相同的key值。

容器类自动申请和释放内存,我们无需new和delete操作。

今天我们主要说说最常见的容器之一list,list是stl实现的双向链表,与向量vector想比,它允许快速的插入和删除,但是随机访问却是比较慢,需要添加头文件#include

主要的操作有

//1.定义和初始化
    list<int> lst1;          //创建空list
    list<int> lst2(3);       //创建含有三个元素的list
    list<int> lst3(3,2); //创建含有三个元素为2的list
    list<int> lst4(lst2);    //使用lst2初始化lst4
    list<int> lst5(lst2.begin(),lst2.end());  //同lst4

    //2.常用操作方法
    lst1.assign(lst2.begin(),lst2.end());  //分配值,3个值为0的元素
    lst1.push_back(10);                    //末尾添加值
    lst1.pop_back();                   //删除末尾值
    lst1.begin();                      //返回首值的迭代器
    lst1.end();                            //返回尾值的迭代器
    lst1.clear();                      //清空值
    bool isEmpty1 = lst1.empty();          //判断为空
    lst1.erase(lst1.begin(),lst1.end());                        //删除元素
    lst1.front();                      //返回第一个元素的引用
    lst1.back();                       //返回最后一个元素的引用
    lst1.insert(lst1.begin(),3,2);         //从指定位置插入个3个值为2的元素
    lst1.rbegin();                         //返回第一个元素的前向指针
    lst1.remove(2);                        //相同的元素全部删除
    lst1.reverse();                        //反转
    lst1.size();                       //含有元素个数
    lst1.sort();                       //排序
    lst1.unique();                         //删除相邻重复元素

    //3.遍历
    //迭代器法
    for(list<int>::const_iterator iter = lst1.begin();iter != lst1.end();iter++)
    {
       cout<<*iter;
    }

Tips:这里的push_back和vector的push_back不一样的地方在于,列表增加元素是不会全部重新分配内存的,所以列表list增加元素效率比向量vector的高


下面我们自己实现一把简易的List

MyList.h

#pragma once

#include<list>

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

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


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

    Ref operator*(){
        return _node->_data;
    }

    Ptr operator->() {
        // return &_node->_data;
        return &(operator*());
    }

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

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

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

    Self operator--() {
        _node = _node->_prev;
        return *tihs;
    }
    //后置--
    Self operator--(int) {
        Self tmp(*this);
        _node = _node->_prev;
        return tmp;
    }
};

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

    List(){
        _head = new Node(T());
        _head->_next = _head;
        _head->_prev = _head;
    }
    ~List(){
        Clear();
        delete _head;
        _head = NULL;
    }
    void Clear() {
        Iterator it = Begin();
        while (it != End()) {
        Node* del = it._node;
        ++it;
        delete del;
        }
        _head->_next = _head;
        _head->_prev = _head;
    }

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

    Iterator End() {
        return _head;
    }

    ConstIterator Begin() const {
        return _head->_next;
    }
    ConstIterator End() const {
        return _head;
    }

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

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

    void PopBack() {
        Erase(--End());
    }
    void PushFront() {
        Erase(Begin());
    }
    void Insert(Iterator pos, const T& x) {
        Node* cur = pos._node;
        Node* prev = cur->_prev;

        Node* tmp = new Node(x);

        prev->_next = tmp;
        tmp->_prev = prev;

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

    Iterator Erase(Iterator& pos) {
        assert(pos->_node != _head);

        Node* cur = pos->_node;
        Node*  prev = cur->_prev;
        Node* next = cur->_next;

        prev->_next = next;
        next->_prev = prev;
        delete cur;

        pos = prev;

        return next;
    }

    void Assign(size_t n, const T& val) {
        Clear();
        for (size_t i = 0;i<n;++i)
        {
            PushBack(val);
        }
    }

    template<class InputIterator>
    void Assign (InputIterator first,InputIterator last ){
        Clear();
        while (first != last) {
            PushBack(*first);
            ++first;
        }
    }

    protected:
    Node * _head;
};


struct AA {
    int _a1;
    int _a2;
};

void PrintList(const List<int>& l)
{
    List<int>::ConstIterator it = l.Begin();
    while (it != l.End())
    {
        cout << *it << " ";
        ++it;
    }
    cout << endl;
}

void print_list(const list<int>& l)
{
    list<int>::const_iterator it1 = l.begin();
    while (it1 != l.end())
    {
        cout << *it1 << " ";
        ++it1;
    }
    cout << endl;
}

void TestList() {
    List<int> l;
    l.PushBack(123);
    l.PushBack(456);
    l.PushBack(789);
    l.PushBack(10);

    PrintList(l);
}



//void Testlist2()
//{
//  list<int> l2;
//  l2.push_back(30);
//  l2.push_back(30);
//  l2.push_back(10);
//  l2.push_back(20);
//  l2.push_back(30);
//  l2.push_back(30);
//  l2.push_back(30);
//  l2.push_back(40);
//  l2.push_back(40);
//  l2.push_back(40);
//  print_list(l2);
//  list<int>::iterator pos = find(l2.begin(), l2.end(), 400);
//  if (pos != l2.end())
//  {
//      l2.erase(pos);
//  }
//
//  l2.remove(30);
//
//
//  l2.sort();
//  l2.unique();
//
//  print_list(l2);
//}
//  


    void Testlist3()
    {
        list<int> l2;
        l2.push_back(10);
        l2.push_back(20);
        l2.push_back(30);
        l2.push_back(40);
        print_list(l2);
        list<int> l1;
        l1.push_back(1);
        l1.push_back(2);
        l1.push_back(3);
        l1.push_back(4);

        print_list(l1);

        string s1("hello");
        l1.assign(10, 1);
        /*l1.assign(++l2.begin(), --l2.end());
        l1.assign(s1.begin(), s1.end());*/
        l1.resize(5);

        print_list(l1);
    }

test.cpp

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

#include"List.h"

int main() {
    //TestList();
    //Testlist2();
    Testlist3();

    system("pause");
    return 0;
}
  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值