List(链表)

list不是连续的线性空间,它的好处是每次插入或删除一个元素,就配置或释放一个元素空间。list的结点不保证在储存空间中连续存在,所以不能以普通指针作为迭代器。list迭代器必须有能力指向list的节点,并有能力进行正确的递增,递减,取值等操作。

list的节点结构

template<class T>
struct __list_node{
    typedef void *void_pointer;
    void_pointer prev;   //型别是void*,其实可设为__list_node<T>*
    void_pointer next;
    T data;
};    //双向链表

根据list的特性,即双向链表可以进行前后移动,那么迭代器的类型是Bidirectional Iterators.

迭代器的设计

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_iterators_tag iterator_category;
    typedef T value_type;
    typedef Ref reference;
    typedef Ptr pointer;
    typedef ptrdiff_t difference_type;

    typedef __list_node<T>* link_type;
    typedef size_t size_type;

    link_type node;      //迭代器的根,指向list的节点

    //构造函数
    __list_iterator(link_type x) : node(x) {}
    __list_iterator(const iterator& x) : node(x.node) {}
    __list_iterator() {}

    bool operator==(const self& x) const {
        return node == x.node;
    }
    bool operator!=(const self& x) const {
        return node != x.node;
    }
    reference operator*() const{
        return (*node).data;    //元素值
    }
    pointer operator->() const{
        return &(operator*());   //元素地址
    }


    self& operator++() {
        node = (link_type)((*node).next);      //移动内部的根,指向下一个节点
        return *this;
    }
    self operator++(int) {
        self tmp = *this;
        ++*this;     
        return *this;
    }
    self& operator--() {
        node = (link_type)((*node).prev);      //移动内部的根,指向上一个节点
        return *this;
    }
    self operator--(int) {
        self tmp = *this;
        --*this;     
        return *this;
    }
}    

List是一个环状双向链表。只需要一个指针,便可以完整表现整个链表。

template<class T, class Alloc = alloc>
class list{
protected:
    typedef __list_node<T> list_node;
    typedef simple_alloc<list_node, Alloc> list_node_allocator;
public:
    typedef list_node* link_type;

    //定义必须内嵌型别
    typedef T value_type;
    typedef value_type& reference;
    typedef const value_type&  const_reference;
    typedef value_type* pointer;
    typedef const value_type* const_pointer;
    typedef ptrdiff_t difference_type;
    typedef size_t size_type;

    //定义迭代器
    typedef list_iterator<value_type, reference, pointer> iterator;
    typedef list_iterator<value_type, const_reference, const_pointer> const_iterator;

protected:
    link_type node;
    //节点的创建和删除
    link_type get_node(){
        return list_node_allocator::allocate();
    }
    void put_node(link_type p){
        list_node_allocator::deallocate();
    }
    link_type create_node(const T &x){
        link_type p = get_node();
        construct(&p->data, x);   //取出节点中存放元素的地址
        return p;
    }
    void destory_node(link_type p){
        destroy(&p->data);
        put_node(p);
    }

    void empty_initialize(){    //初始化一个节点,不存放任何数值,充当尾节点
        node = get_node();
        node->next = node;
        node->prev = node;
    }

    //把[first, last)内的所有元素移到position之前
    void transfer(iterator position, iterator first, iterator last){
        if(position != last) {
            (*(link_type((*last.node).prev))).next = position.node;
            (*(link_type((*first.node).prev))).next = last.node;
            (*(link_type((*position.node).prev))).next = first.node;
            link_type tmp = link_type((*position.node).prev);
            (*position.node).prev = (*last.node).prev;
            (*last.node).prev = (*first.node).prev;
            (*first.node).prev = tmp;
        }
    }

public: 
    //容器基本操作
    inline iterator begin() {
        return (link_type)(*node).next;
    }
    inline const_iterator cbegin() const {
        return (link_type)(*node).next;
    }
    inline iterator end() {
        return node;   //头节点不存储任何数据,它就是end节点
    }
    inline const_iterator cend() const {
        return node;
    }
    inline bool empty() {
        return node->next == node;     //自己和自己连接,则list为空
    }
    inline size_type size() {
        return (size_type)distance(begin(), end());//计算首尾两个迭代器之间的距离
    }
    //引用方式返回
    inline reference front() {
        return *begin();   
    }
    inline reference back() {
        return *(--end());
    }

    //默认构造函数
    list() { empty_initialize(); }


    //在相应的位置插入元素
    iterator insert(iterator position, const T &x){
        link_type tmp = create_node(x);
        tmp->next = position.node;
        tmp->prev = position.node->prev;
        (link_type(position.node->prev))->next = tmp;
        position.node -> prev = tmp;
        return tmp;
    }
    void push_front(const T &x){
        insetr(begin(), x);
    }
    void push_back(const T &x){
        insetr(end(), x);
    }
    iterator erase(iterator position){
        link_type next_node = link_type(position.node->next);
        link_type prev_node = link_type(position.node->prev);
        next_node->prev = prev_node;
        prev_node->next = next_node;
        destory(position.node);
        return iterator(next_node);
    }
    void pop_front(){
        erase(begin());
    }
    void pop_back(){
        erase(--end());
    }
    void clear(){
        link_type cur = (link_type)node->next;
        while(cur != node){   //最后一个节点
            link_type tmp = cur;
            cur = (link_type) cur->next;
            destory(tmp);
        }
        node->next = node;    //空链表
        node->prev = node;
    }
    void remove(const T &value){
        iterator first = begin();
        iterator last  = end();
        while(first != last){
            iterator next = first;
            ++next;
            if(*first == value){
                erase(first);
            }
            first = next;
        }
    }
    void unique(){   //删除连续且相同的元素
        iterator first = begin();
        iterator last  = end();
        if(first == last) { return; }
        iterator next = first;
        while(++next != last){
            if(*first == *next){
                erase(next);
            }else{
                first = next;
            }
            next = first;
        }
    }


    void splice(iterator position, list &x){  //连接两个链表
        if(!x.empty()){
            transfer(position, x.begin(), x.end());
        }
    }
    void splice(iterator position, list&, iterator i){
        iterator j = i;
        ++j;
        if(position == i || position == j) {
            return;
        }
        transfer(position, i, j);
    }
    void splice(iterator position, list&, iterator first, iterator last){
        if(first !=  last){
            transfer(position, first, last);
        }
    }

    //merge()将x合并到*this身上。两个list的内容都必须经过递增排序
    void merge(list<T, Alloc>& x){
        iterator first1 = begin();
        iterator last1 = end();
        iterator first2 = x.begin();
        iterator last2 = x.end();

        while(first1 != last1 && first2 != last2){
            if(*first2 < *first1){
                iterator next = first2;
                transfer(first1, first2, ++next);
                first2 = next;
            }else{
                ++first1;
            }
            if(first2 != last2){
                transfer(last1, first2, last2);
            }
        }
    }

    //将*this的内容重载
    void reverse(){
        if(node->next == node || link_type(node->next)->next == node) { return; }
        iterator first = begin();
        ++first;
        while(first != end()){
            iterator old = first;
            ++first;
            transfer(begin(), old, first);
        }
    }

    //list不能使用STL算法sort(),因为STL算法只接受RandomAccessIterator
    void sort(){     //非递归的归并排序
        if(node->next == node || link_type(node->next)->next == node) { return; }

        List<T, Alloc> carry;
        List<T, Alloc> counter[64];
        int fill = 0;
        while(!empty()){
            carry.splice(carr.begin(), *this, end());
            int i = 0;

            while(i < fill && !counter[i].empty()){
                counter[i].merge(carry);
                carry.swap(counter[i++]);
            }
            carry.swap(counter[i]);
            if(i == fill){
                ++fill;
            }
        }
        for(int i = 1; i < fill; ++i){
            counter[i].merge(counter[i - 1]);
        }
        swap(counter[fill - 1]);
    }
}; 

image-20231130180241964

Leave a Comment

Your email address will not be published. Required fields are marked *

Scroll to Top