c++之stl_list

本文详细介绍了C++中的STL List,包括其内存结构、双向链表特性、节点设计、迭代器、常用方法及测试。List在C++中提供高效插入删除,但不支持随机访问。文章还给出了具体的实现代码和测试案例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

c++之stl_list

一、list的内存结构

在cpp中,list容器是双向链表,对应c#中的LinkedList。链表的内存是不连续的,通过节点(node)串起来。

  1. 优点:
    • 高效插入删除。只需对指针进行操作,不需要拷贝元素。
    • 不需要连续内存,就可以完成动态操作。增加元素,即增加节点。
  2. 缺点:
    • 不支持随机访问,即索引器,[]操作符。
    • 需要额外内存来维护node节点。

接下来看看list是怎样设计的。

在这里插入图片描述

从图中可以看出,list不仅是双向的,还是环状的。整个list是由node串起来的,node里有两根指针,prev、next,以及一个data。prev指向前一个node,next指向后一个node。end()里没有data,这是为了遵循前闭后开原则,stl里其他容器也是一样。

二、具体实现

1. list的node

    template <typename T>
    struct list_node
    {
   
   
        typedef list_node<T> *node_ptr;
        typedef T value_type;

        value_type data;
        node_ptr prev;
        node_ptr next;

        list_node(const value_type &val) : data(val), prev(NULL), next(NULL) {
   
   }
    };

2. list的迭代器

    template <typename T>
    struct list_iterator {
   
   
        list_node<T> node;
        //......
        ref operator*() const {
   
   return node->data;}
        ptr operator->() const {
   
   return &(operator*());}
        self &operator++(){
   
   node = node->next; return *this;}
        self &operator--(){
   
   node = node->prev; return *this}
        bool &operator==(cosnt self &ths){
   
   return node == ths.node};
        //......
    };
    struct reverse_list_iterator {
   
   /* ..... */};
由于list的内存空间不连续,无法直接使用指针操作,所以必须重载++、--操作符,且不提供[]操作符。++操作其实就是将迭代器中的node指向下一个node,很容易理解。为了让迭代器能像指针一样使用,需要对*、->操作符进行重载,使其能够轻松获取到node中的data。操作符重载是cpp重要的一部分,虽然设计起来比较麻烦,但是能够让使用者用得很舒服。

3. list的常用方法

    void push_back(const value_type &val);//后端插入
    void push_front(const value_type &val);//前端插入
    void insert(iterator positon, const value_type &val);//任意一个位置插入
    void pop_front();//前端删除
    void pop_back();//后端删除
    void remove(const value_type &val);//删除所有指定元素
    iterator earse(iterator position);//删除任意一个节点
    void clear();//清空容器
list只需要一根node指针,一般称作为head(里面不装data,仅作为标记使用,为了遵循前闭后开区间的原则),配合iterator,就可以管理整个链表。操作list、iterator中的node指针,可以很快、很轻松的完成插入删除、操作。

在这里插入图片描述

4. 完整代码

为了保证简洁,可以忽略reverse iterator部分,本文reverse iterator的实现不妥,应采用迭代器适配器(iterator adaptor)来实现。

    #if !defined(_M_LIST_)
    #define _M_LIST_

    #include <memory>

    namespace learnCpp
    {
   
   
    template <typename T>
    struct list_node
    {
   
   
        typedef list_node<T> *node_ptr;
        typedef T value_type;

    public:
        value_type data;
        node_ptr prev;
        node_ptr next;

        list_node() : prev(NULL), next(NULL) {
   
   }
        list_node(const value_type &val) : data(val), prev(NULL), next(NULL) {
   
   }
    };

    template <typename T>
    struct list_iterator
    {
   
   
    protected:
        typedef T value_type;
        typedef T *ptr;
        typedef T &ref;
        typedef list_iterator<T> self;
        typedef list_node<T> *link_type;

    public:
        link_type node;

        list_iterator(link_type node = nullptr) : node(node
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值