List

来源:互联网 发布:apache cxf 2.7.6下载 编辑:程序博客网 时间:2024/06/04 19:04
List概述
对于任何位置的插入删除,时间复杂度为O(1)。
list类似于链表,双向链表,环状双向链表
template <class T>
struct _list_node{
    typedef void* pointer;
    pointer prev;  
    pointer next;
};
list的迭代器
重要性质:插入insert、接合操作splice不会造成原有迭代器失效(vector中不成立)
删除操作erase也只有指向被删除元素的那个迭代器失效

类的源码:
template<class T>
class List{
protected:    //typedef  重命名
    typedef _list_node<T> list_node;
public:
    typedef list_node* link_type;
protected:
    link_type node;       //只要一个指针,便可表示整个环状双向链表,该node节点为整个循环双向链表的头结点,即尾节点的next节点,所以求end也就是最后一个节点后的指针,也就是该node节点
    iterator end() { return node; }
    iteratot begin() { return (link_type)(node->next); }
};

List的构造及各种操作:
default constructors:
public:
    list() { empty_initialize(); }  //产生一个空链表
protected:
    void empty_initialize(){
        node=get_node();
        node->next=node;
        node->prev=node;
    }
insert:
iterator insert(iterator position, const T& val){
    link_type tmp=create_node(val);
    //调整双向链表
    tmp->next=position.node;
    tmp->prev=position.node->prev;
    (link_type (position.node->prev))->next=tmp;
    position.node->prev=tmp;
    return tmp;
}
push_back:
void push_back(const T& val) { insert(end(), val); }
push_front:
void push_front(const T& val) { insert(begin(), val); }
erase:
iterator erase(iterator position){
    link_type next_node=(link_type)(position.node->next);
    link_type prev_node=(link_type)(position.node->prev);
    prev_node.next=next_node;
    next_node.prev=prev_node;
    destory_node(position.node);
    return iterator(next_node);
}
pop_front:
void pop_front() { erase(begin()); }
pop_back:
void pop_back() { erase(--end()); }
remove:  删除所有值为val的元素
void remove(const T& val){
    iterator first=begin();
    iterator last=end();
    while(first!=last){
        iterator tmp=first;
        tmp++;
        if(*first==val)
            erase(first);
        first=tmp;
    }
}
unique: 删除数值相同的连续元素,注意:数值相同,且连续。
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;
    }
}
transfer:迁移操作,将某连续范围内的元素迁移到某个特定位置之前。
//将[first,last)内所有元素移动到position之前
void transfer(iterator position, iterator first, iterator last){
    if(position!=last){
        (*(link_type(last->node.prev))).next=position.node;   //last所指元素并不迁移
        (*(link_type(position->node.prev))).next=first.node;
        (*(link_type(first->node.prev))).next=last.node;
        iterator tmp=link_type(position->node.prev);
        position->node.prev=last->node.prev;
        first->node.prev=tmp;
        last->node.prev=first->node.prev;
    }
}

splice:接合
//将x结合于position所指元素之前,x须不同于*this
void splice(iterator position, list& x) { 
    if(!x.empty())
        transfer(position, x.begin(), x.end());
}
//将[first,last)内元素结合于position之前,position和[first,last)可能指向同一个list但position不能位于[first,last) 内
void splice(iterator position, list& , iterator first, iterator last){
    if (first!=last) transfer(position, first, last);
}
//将i所指元素结合于position之前,position和i可能指向同一个list
void splice(iterator position, list&, iterator i){
    iterator j=i;
    ++j;
    if(i==position||j==position) return ;
    transfer( position, i, j );
}
merge:将x合并到*this上,两个list是已经递增排序后的
void merge(const List& x){......}
reserve:将*this逆序操作
void reserve(){
    //首先判断是否是空表(begin()==end())或者只有一个元素(begin()->next==end()),如果是,则直接返回,代码略
    return;
    iterator first=begin();
    ++first;
    while(first!=end()){    //遍历链表,并将所有元素依次进行头插。
        iterator old=first;
        ++first;
        transfer(begin(), old, first);  
    }
}
sort:采用快速排序算法
void sort(){
    //首先判断是否是空表(begin()==end())或者只有一个元素(begin()->next==end()),如果是,则直接返回,代码略
    return;
    //采用快速排序算法
    //一些新的lists,作为中介数据存放区
    list carry;
    list counter[64];
    int fill=0;
    while(!empty()){
        carry.splice(carry.begin(), *this, begin());
        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] );
}

0 0
原创粉丝点击