STL容器之List

目录

目录

list概述:

list节点的结构(单个list节点的结构)

list的数据结构(表示整个list的结构)

list的迭代器

如何判断list为空?

list的内存管理

list的元素操作

erase:移除迭代器所指节点

clear:清除整个list的所有节点

remove:将数值为value的节点全部移除

unique:唯一化链表中的节点,将连续相同的元素移除至只剩一个,不连续的相同元素不会被移除

splice:拼接,将某连续范围内的元素从一个list移动到另一个(或同一个)list的某个position

merge:有序合并,将升序排列的list1合并到升序排列的list2上,前提时list1和list2都必须升序有序,合并后的list也是升序

reverse:反转list, 如1->2->3->4反转后为4->3->2->1

sort:排序,list不能使用STL提供的sort算法,只能使用自己的sort()成员函数,因为STL中的sort只接受支持随机访问的iterator,而list当中的迭代器无法随机访问;


list概述:

        list的好处是每次插入或删除一个元素,只需配置或释放一个元素空间,所以list对于任意位置元素的插入或删除都是常数时间

list节点的结构(单个list节点的结构)

template <Class T>
struct _list_node {
    typedef void* void_pointer;
    void_pointer prev;
    void_pointer next;
    T data;
}

list的数据结构(表示整个list的结构)

templat <class T, class Alloc = alloc>
class list{
protected:
    typedef _list_node<T> list_node;
public:
    typedef list_node* link_type;
protected:
    link_type node; //只要一个指针,便可表示整个环状双向链表
...
    
}

显然,list是双向链表,并且是双向循环链表,只需刻意在尾端添加一个空白节点,指针node便可满足“前闭后开”的区间要求

list的迭代器

list的一个重要性质:insert和splice操作都不会导致原有list迭代器失效,erase操作也只是导致之前指向待删除节点的迭代器失效,其他迭代器不受影响。因为list插入和接合操作只需改变节点pre和next的指向,不会改变当前节点所处的内存位置;

list迭代器的设计:

template <class T, class Ref, class Ptr>
struct _list_iterator {
    
    //类型重命名
    typedef _list_iterator<T, T&, T*>  iterator;
    typedef _list_iterator<T, Ref, Ptr>  self;

    typedef  bidirectional_iterator_tag  itreator_category;
    typedef T value_type;
    typedef Ref pointer;
    typedef Ptr reference;
    typedef _list_node<T>* link_type;
    typedef size_t size_type;
    typedef ptrdiff_t difference_type;

    //迭代器中的成员
    link_type node;  //指向list节点的指针;
    
    //迭代器的构造函数
    _list_iterator() {}  //默认构造
    _list_iterator(link_type x) : node(x) {} //参数类型为link_type的构造
    _list_iterator(const iterator& x) : node(x.node) {} //参数类型为某list的迭代器
    

    //迭代器必备的重载函数
    bool operator==(const self& x) const {return node== x.node};
    bool operator!=(const self& x) const {renturn node!= x.node};
    
    reference operator*() const {return (*node).data;}
    pointer operator->() const {return &( operator*() );}
    


    //对迭代器累加1,即前进一个节点
    self& operator++() {
        node = (link_type) ((*node).next);
        return *this; //this代表指向当前对象的指针 return this 即为 返回当前对象的地址
                      //*this代表当前对象的拷贝或者本身, 若返回类型为A 则是返回拷贝, 若返回类型是A& 则是返回本身
    }
    
        //累加的重载版本,没看懂
    self operator++(int) {
        self tmp = *this; //tmp是iterator,*this是对象的拷贝
        ++*this; //什么意思?
        return tmp;}
    
    //对迭代器递减,即后退一个节点
     self& operator--() {
        node = (link_type) ((*node).next);
        return *this;}
    
      self operator--(int) {
        self tmp = *this; //tmp是iterator,*this是对象的拷贝
        --*this; //什么意思?
        return tmp;} 
            
    
}

如何判断list为空?

begin()->prev==bengin()&&begin()->next==begin()

即list节点node的prev和next都指向自身

list的内存管理

constructor、push_back、insert;

insert函数:

 iterator  insert(iterator position, const T& x)//在position位置插入 x

  当使用push_back()函数尾插新元素时,内部调用的就是insert(),其中position的位置可以通过find()来确定

find函数:

iterator find (begin,end,const T& x);//在begin至end范围内,查找value=x的节点,并返回其迭代器

注意:list中在position位置插入是指将某节点插入到position位置的前一个位置上;

list的元素操作

常用操作有:

push_front、push_back、pop_front、pop_back

erase:移除迭代器所指节点

  iterator erase(iterator position){...}

clear:清除整个list的所有节点

void clear() {...}

remove:将数值为value的节点全部移除

 void remove(const T& value){...}

unique:唯一化链表中的节点,将连续相同的元素移除至只剩一个,不连续的相同元素不会被移除

 void unique(){...}

splice:拼接,将某连续范围内的元素从一个list移动到另一个(或同一个)list的某个position

//1.将整个list1拼接到list2的position位置
void splice (iterator position, list1&,) {...}

//2.将list1中iterator i所指的节点拼接到list2的position位置
void splice (iterator position, list1&, iterator i) {...}

//3.将list1中某一连续范围[first,last)内的节点拼接到list2的position位置
void splice (iterator position, list1&, iterator first, iterator last)

merge:有序合并,将升序排列的list1合并到升序排列的list2上,前提时list1和list2都必须升序有序,合并后的list也是升序

void merge (list& list1){...}

transfer:为list内部提供的一个所谓的迁移操作,将某连续范围内元素迁移到某特定位置之前,主要是做一些节点指针移动的操作,splice和merge两个涉及迁移的函数内部都是transfer函数,但transfer不提供对外接口;程序员无法直接调用;

reverse:反转list, 如1->2->3->4反转后为4->3->2->1

       

void reverse() {...} //内部使用while循环,搭配快慢指针,将节点依次反转;

sort:排序,list不能使用STL提供的sort算法,只能使用自己的sort()成员函数,因为STL中的sort只接受支持随机访问的iterator,而list当中的迭代器无法随机访问;

void list<T>::sort() {...}//内部实现细节暂略

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值