list类的C++模板实现

来源:互联网 发布:棋盘覆盖算法 编辑:程序博客网 时间:2024/06/06 03:12

list类的实现 list.h

/*2017/07/20Liu YK*/#pragma once#include <iostream>#include <ctime>#include <cassert>#include <cstdlib>namespace MYSTL{#define ListNodePosi(T) ListNode<T>*    typedef int Rank;    template<typename T>    class ListNode    {    public:        ListNode(const T &e = T(), ListNodePosi(T) prev = nullptr, ListNodePosi(T) next = nullptr)            : m_data(e), m_prev(prev), m_next(next) {}        ~ListNode() {}        ListNodePosi(T) insertAsPrev(const T &e)        {            ListNodePosi(T) p = new ListNode<T>(e, m_prev, this);            m_prev->m_next = p;            m_prev = p;            return p;        }        ListNodePosi(T) insertAsNext(const T &e)        {            ListNodePosi(T) p = new ListNode<T>(e, this, m_next);            m_next->m_prev = p;            m_next = p;            return p;        }    public:        T m_data;        ListNodePosi(T) m_prev;        ListNodePosi(T) m_next;    };    template<typename T>    class List    {    public:        /*template<typename T>        friend std::ostream& operator<< (std::ostream &os, List<T> &l)        {            if (l.m_size)            {                ListNodePosi(T) p = l.first();                while (p != l.m_trailer)                {                    os << p->m_data << " ";                    p = p->m_next;                }            }            return os;        }*/    public:        List() { init(); }        List(const List<T> &l) { copyNodes(l.first(), l.size()); }        List(const List<T> &l, Rank r, int n);        List(ListNodePosi(T) p, int n);        ~List() { clearAllNode(); };        //只读接口        int size() const { return m_size; }        bool empty() const { return 0 == m_size; }        T& operator[](Rank r) const;        ListNodePosi(T) first() const;        ListNodePosi(T) last() const;        void print() const;        ListNodePosi(T) find(const T &e);        ListNodePosi(T) find(const T &e, int n, ListNodePosi(T) p);        ListNodePosi(T) search(const T &e, int n, ListNodePosi(T) p);        ListNodePosi(T) search(const T &e);        //可写访问接口        ListNodePosi(T) insertAsFirst(const T &e);        ListNodePosi(T) insertAsLast(const T &e);        ListNodePosi(T) insertAfter(ListNodePosi(T) p, const T &e);        ListNodePosi(T) insertBefore(ListNodePosi(T) p, const T &e);        const T remove(ListNodePosi(T) p);        int deduplicate();        int uniqify();        void sort();        void sort(ListNodePosi(T) p, int n);    private:        void init();        void clearAllNode();        void copyNodes(ListNodePosi(T) p, int n);//拷贝p之后的n个元素        void insertSort(ListNodePosi(T) p, int n);        void selectSort(ListNodePosi(T) p, int n);        void mergeSort(ListNodePosi(T) p, int n);        void merge(ListNodePosi(T) p, int n, ListNodePosi(T) q, int m, List<T> &l);        ListNodePosi(T) findMax(ListNodePosi(T) p, int n);    private:        int m_size;        ListNodePosi(T) m_header;        ListNodePosi(T) m_trailer;    };    template<typename T>    inline List<T>::        List(const List<T>& l, Rank r, int n)    {        ListNodePosi(T) p = l.first();        while (r--)        {            p = p->m_next;        }        copyNodes(p, n);    }    template<typename T>    inline List<T>::List(ListNodePosi(T) p, int n)    {        copyNodes(p, n);    }    template<typename T>    inline T & List<T>::operator[](Rank r) const    {        assert(r < m_size && r >= 0);        ListNodePosi(T) p = first();        while (r--)        {            p = p->m_next;        }        return p->m_data;    }    template<typename T>    inline ListNodePosi(T) List<T>::first() const    {        assert(m_size != 0);            return m_header->m_next;    }    template<typename T>    inline ListNodePosi(T) List<T>::last() const    {        assert(m_size != 0);        return m_trailer->m_prev;    }    template<typename T>    inline ListNodePosi(T) List<T>::find(const T & e)    {        return find(e, m_size, m_trailer);    }    template<typename T>    inline ListNodePosi(T) List<T>::find(const T & e, int n, ListNodePosi(T) p)    {        p = p->m_prev;        while (n-- && p)        {            if (e == p->m_data)                return p;            p = p->m_prev;        }        return nullptr;    }    template<typename T>    inline ListNodePosi(T) List<T>::search(const T & e, int n, ListNodePosi(T) p)    {        while (n--)        {            p = p->m_prev;            if (e <= p->m_data)                break;        }        return p;    }    template<typename T>    inline ListNodePosi(T) List<T>::        search(const T & e)    {        return search(e, m_size, m_trailer);    }    template<typename T>    inline void List<T>::print() const    {        if (!empty())        {            ListNodePosi(T) p = first();            while (p != m_trailer)            {                std::cout << p->m_data << " ";                p = p->m_next;            }            std::cout << std::endl;        }    }    template<typename T>    inline ListNodePosi(T) List<T>::insertAsFirst(const T & e)    {        /*ListNodePosi(T) p = new ListNode<T>(e, m_header, m_header->m_next);        assert(p);*/        /*m_header->m_next->m_prev = p;        m_header->m_next = p;   */        ++m_size;        return m_header->insertAsNext(e);    }    template<typename T>    inline ListNodePosi(T) List<T>::insertAsLast(const T & e)    {        /*ListNodePosi(T) p = new ListNode<T>(e, m_trailer->m_prev, m_trailer);        assert(p);*/        /*m_trailer->m_prev->m_next = p;        m_trailer->m_prev = p;*/        ++m_size;        return m_trailer->insertAsPrev(e);    }    template<typename T>    inline ListNodePosi(T) List<T>::insertAfter(ListNodePosi(T) p, const T & e)    {        assert(p);        ++m_size;        return p->insertAsNext(e);    }    template<typename T>    inline ListNodePosi(T) List<T>::insertBefore(ListNodePosi(T) p, const T & e)    {        assert(p);        ++m_size;        return p->insertAsPrev(e);    }    template<typename T>    inline const T List<T>::        remove(ListNodePosi(T) p)    {        T ret = p->m_data;        p->m_prev->m_next = p->m_next;        p->m_next->m_prev = p->m_prev;        delete p;        --m_size;        return ret;    }    template<typename T>    inline int List<T>::deduplicate()    {        int old_size = m_size;        if (m_size < 2)            return 0;        ListNodePosi(T) p = m_header->m_next->m_next;        int n = 1;        while (p != m_trailer)        {            ListNodePosi(T) q = p->m_next;            if (find(p->m_data, n, p))            {                remove(p);            }            else            {                ++n;            }            p = q;        }        return old_size - m_size;    }    template<typename T>    inline int List<T>::uniqify()    {        int old_size = m_size;        if (m_size < 2)            return 0;        ListNodePosi(T) p = m_header->m_next->m_next;        ListNodePosi(T) q = p;        while (p != m_trailer)        {            q = p->m_next;            if (p->m_data == p->m_prev->m_data)                remove(p);            p = q;        }        return old_size - m_size;     }    template<typename T>    inline void List<T>::sort()    {        if (empty())            return;        sort(first(), m_size);    }    template<typename T>    inline void List<T>::sort(ListNodePosi(T) p, int n)    {        srand(static_cast<unsigned int> (time(nullptr)));        switch (rand() % 4)        {        case 0 :             insertSort(p, n);            break;        case 1 :             selectSort(p, n);            break;        case 2 :        default:            mergeSort(p, n);            break;        }    }    template<typename T>    inline void List<T>::init()    {        m_header = new ListNode<T>();        m_trailer = new ListNode<T>();        m_header->m_next = m_trailer;        m_trailer->m_prev = m_header;        m_size = 0;    }    template<typename T>    inline void List<T>::clearAllNode()    {        if (m_size)        {            ListNodePosi(T) p = first();            while (p != m_trailer)            {                ListNodePosi(T) q = p->m_next;                delete p;                p = q;            }        }        delete m_header;        delete m_trailer;    }    template<typename T>    inline void List<T>::        copyNodes(ListNodePosi(T) p, int n)    {        assert(p);        init();        while (n--)        {            insertAsLast(p->m_data);            p = p->m_next;        }    }    template<typename T>    inline void List<T>::insertSort(ListNodePosi(T) p, int n)    {        //ListNodePosi(T) q = p->m_next;        for (int i = 0; i < n; ++i)        {            //p = q;            insertAfter(search(p->m_data, i, p), p->m_data);            //q = q->m_next;            p = p->m_next;            remove(p->m_prev);        }    }    template<typename T>    inline void List<T>::selectSort(ListNodePosi(T) p, int n)    {        ListNodePosi(T) head = p->m_prev;        while (n--)        {            insertAfter(head, findMax(p, n + 1)->m_data);            p = p->m_next;            remove(p->m_prev);        }    }    template<typename T>    inline void List<T>::mergeSort(ListNodePosi(T) p, int n)    {        if (n < 2)            return;        int m = n >> 1;        ListNodePosi(T) q = p;        for (int i = 0; i < m; ++i)            q = q->m_next;        mergeSort(p, m);        mergeSort(q, n - m);        merge(p, m, q, n - m, *this);    }    template<typename T>    inline void List<T>::        merge(ListNodePosi(T) p, int n, ListNodePosi(T) q, int m, List<T> &l)    {        ListNodePosi(T) head = p->m_prev;        while (m)        {            if ((0 < n) && (p->m_data <= q->m_data))            {                if (q == (p = p->m_next))                    break;                --n;            }            else            {                insertBefore(p, l.remove((q = q->m_next)->m_prev));                --m;            }        }        p = head->m_next;     }    template<typename T>    inline ListNodePosi(T) List<T>::findMax(ListNodePosi(T) p, int n)    {        T max = p->m_data;        ListNodePosi(T) ret = p;        while (--n)        {            p = p->m_next;            if (max < p->m_data)            {                max = p->m_data;                ret = p;            }        }        return ret;    }}

测试程序

void test_list(){    MYSTL::List<int> il1;    cout << "The size is " << il1.size() << endl;    //测试insertAsLast    for (int i = 0; i < 10; ++i)        il1.insertAsLast(i);    //cout << il1 << endl;    cout << "The size is " << il1.size() << endl;    //测试insertAsFirst    for (int i = 0; i < 10; ++i)        il1.insertAsFirst(i);    //cout << il1 << endl;    cout << "The size is " << il1.size() << endl;    //测试operator[]    for (int i = 0; i < il1.size(); ++i)        cout << il1[i] << " ";    cout << endl;    MYSTL::List<string> strList;    for (int i = 1; i < 9; ++i)        strList.insertAsLast(string(i, 'e'));    //cout << strList << endl;    strList.print();    cout << "The size is " << strList.size() << endl;    cout << "find eeee is " << strList.find("eeee")->m_data << endl;    strList.insertAfter(strList.find("ee"), "hello");    strList.insertBefore(strList.find("eeee"), "world");    strList.print();    cout << "The size is " << strList.size() << endl;    //测试其他构造函数    MYSTL::List<string> strList1(strList);    strList1.print();    MYSTL::List<string> strList2(strList1.find("hello"), 4);    strList2.print();    MYSTL::List<string> strList3(strList1, 3, 2);    strList3.print();    //测试remove    strList.remove(strList.find("hello"));    strList.remove(strList.find("world"));    strList.print();    cout << "The size is " << strList.size() << endl;    MYSTL::List<int> il2;    il2.insertAsLast(23);    il2.insertAsLast(34);    il2.insertAsLast(23);    il2.insertAsLast(22);    il2.insertAsLast(34);    il2.print();    il2.deduplicate();    il2.print();    //测试sort    MYSTL::List<int> il3;    for (int i = 0; i < 10; ++i)        il3.insertAsFirst(i);    il3.print();    cout << "After sort:" << endl;    il3.sort();    il3.print();    MYSTL::List<int> il4;    il4.sort();}