zoukankan      html  css  js  c++  java
  • 数据结构:链表

    //
    // Created by DevilInChina on 2018/6/25.
    //
    
    #include <iostream>
    #include <algorithm>
    #include <functional>
    using namespace std;
    template <typename T>
    class List;
    template <typename T>
    class node{///双向链表节点,存储前指针后指针及元素本身。
        friend class List<T>;
        node *pre;
        node *next;
    public:
        T ele;
        node(T &A):ele(A){
            pre = nullptr;
            next= nullptr;
        }
        node(){
            pre = nullptr;
            next= nullptr;
        }
        T&operator*(){ return ele;}
        ~node(){
        }
    };
    template <typename T>
    class List{
    private:///pData为链表表头,en为链表表尾均不存放数据
        unsigned cnt;///元素个数计数
        node <T>*pData;
        node <T>*en;
        node <T>*last;///最后一个实际元素节点
    public:
        ///与iterator类混合使用,进行迭代访问。
        node<T> *begin(){ return pData->next;}
        node<T> *end(){ return en;}
        class iterator{
            node<T>*p;
            friend class List<T>;
        public:
            T&operator*(){
                return p->ele;
            }
            node<T>*operator++(){
                ///没有设计超限访问报错,因为笔者认为是用户的错
                p = p->next;
                return p;
            }
            bool operator!=(node<T>*t){ return p!=t;}
            bool operator==(node<T>*t){ return p==t;}
            void operator=(node<T>*t){p = t;}
        };
        ///构造之初均设计好首尾节点
        List(){
            cnt = 0;
            pData = new node<T>;
            en = new node<T>;
            last = pData;
            en->pre = pData;
            pData->next = en;
        }
        List(T*a,T*b){
            cnt = (unsigned int)(b - a);
            pData = new node<T>;
            last = pData;
            while (a!=b){
                last->next = new node<T>(*a);
                last ->next ->pre = last;
                last = last->next;
                a++;
            }
            en = new node<T>;
            en->pre = last;
            last->next = en;
        }
        List(T a, unsigned int n){
            cnt = 0;
            pData = new node<T>;
            last = pData;
            while (cnt!=n){
                last->next = new node<T>(a);
                last ->next ->pre = last;
                last = last->next;
                ++cnt;
            }
            en = new node<T>;
            en->pre = last;
            last->next = en;
        }
        ///可更改排序规则的排序,实现一劳永逸,默认情况需要元素重载小于号运算符
        void sort(std::function<bool(const T&,const T&)> cmp
        = [&](const T&a,const T&b)->bool{ return a < b;}){
            node<T>**dat;
            node<T>*it;
            dat = new node<T>* [cnt];
            it = pData->next;
            std::function<bool(const node<T>*,const node<T>*)> fun;
            fun = [&](const node<T>*a,const node<T>*b)->bool{
                return cmp(a->ele,b->ele);
            };
            for(int i = 0 ; i < cnt ; ++i){
                dat[i]=it;///为新生成的指针数组初始化
                it=it->next;
            }
            std::sort(dat,dat+cnt,fun);
            ///进行索引排序,避免大量复制
            for(int i = 0 ; i < cnt ; ++i){
                if(i!=cnt-1)dat[i]->next=dat[i+1];
                if(i)dat[i]->pre = dat[i-1];
            }
            pData->next=dat[0];
            dat[0]->pre=pData;
            dat[cnt-1]->next = en;
            en->pre = dat[cnt-1];
            last = dat[cnt-1];
            delete []dat;
        }
        T&front(){
            return pData->next->ele;
        }
        void push_back(T A){
            last -> next = new node<T>(A);
            last ->next ->pre = last;
            last = last->next;
            last->next = en;;
            en->pre = last;
            cnt++;
        }
        void push_front(T A){
            if(pData->next== nullptr){
                push_back(A);
                return;
            }
            node<T>*p = new node<T>(A);
            p->next = pData->next;
            pData->next->pre = p;
            pData->next = p;
            p->pre = pData;
            cnt++;
        }
        void pop_back(){
            last = last->pre;
            delete last->next;
            last->next = en;
            en->pre = last;
            --cnt;
        }
        void pop_front(){
            node<T>*tmp = pData->next;
            pData->next = tmp->next;
            tmp->next->pre = pData;
            delete tmp;
            --cnt;
        }
        ///三个insert实际上都依靠最后的insert完成,减少代码量,略微增加机器的负担
        ///且超出长度默认合并到最后一项,没有提示
        void insert(unsigned int pos,T*A,T*B){
            List <T> C(A,B);
            insert(pos,C);
        }
        void insert(unsigned int pos,T A){
            T pa[2];
            pa[0] = A;
            insert(pos,pa,pa+1);
        }
        void insert(unsigned int pos,List<T>&A){
            if(pos>=cnt){
                merge(A);
            }
            else {
                node<T> *it = pData;
                while (pos--) {
                    it = it->next;
                }
                A.last->next = it->next;
                it->next->pre=A.last;
                it->next = A.pData->next;
                A.pData->next->pre = it;
                A.pData->next = A.en;
                A.en->pre = A.pData;
                cnt+=A.cnt;
                A.cnt = 0;
            }
        }
        node<T>* erase(iterator i){///删除元素后返回上一个元素指针
            if(i.p== en)
                return en->pre;
            node<T>*tmp = i.p;
            i.p = i.p->pre;
            tmp->pre->next = tmp->next;
            tmp->next->pre = tmp->pre;
            delete tmp;
            return i.p;
        }
        node<T>*find(T a) {///只用定义了 < 运算符的元素可以进行查找
            node<T>*ipos = pData;
            while (ipos->next!=en){
                if(!(ipos->ele<a)&&!(a<ipos->ele))
                    return ipos;
                ipos = ipos->next;
            }
            return en;
        }
        void merge(List<T>&A){
            if(!A.size())///没有这一句会出问题导致链表自环
                return;
            last->next = A.pData->next;
            A.pData->next->pre = last;
            A.last->next = en;
            en->pre = A.last;
            last = A.last;
            A.last = A.pData;
            A.pData->next = A.en;
            A.en->pre = A.pData;
            cnt+=A.cnt;
            A.cnt = 0;
        }
        void clear(){
            while (pData->next!=en){
                pData = pData->next;
                delete pData->pre;
            }
            pData->next = en;
            en->pre = pData;
            cnt = 0;
        }
        T&operator[](unsigned int k){
            if(k>=cnt){
                cerr<<"seg fault"<<"
    ";
                return pData->ele;
            }
            node<T>* it = pData;
            while (k--){
                it = it->next;
            }
            return it->next->ele;
        }
        unsigned int size(){ return cnt;}
        unsigned int length(){ return cnt;}
        ~List(){
            while (pData->next){
                pData = pData->next;
                delete pData->pre;
            }
            delete pData;
            delete en;
        }
    };
    int main(){
        /// test
    }
  • 相关阅读:
    hdu4355(三分求极值)
    Codeforces Round #107 (Div. 1) (快速求质因子、vector)
    2012哈工程ACM暑期集训图论专场(练习赛第7场)题解
    2012 MultiUniversity Training Contest 6
    Codeforces Beta Round #97 (Div. 2)
    Codeforces Round #134 (Div. 2) 并查集
    C++ Boost foreach
    Design : 如何设计View
    15个最优秀的酒店网页免费模板
    在C++中使用tr1实现functor/函数指针/成员函数指针
  • 原文地址:https://www.cnblogs.com/DevilInChina/p/9375257.html
Copyright © 2011-2022 走看看