链表的实现

1.概念
1)容器:利用类模板构建的一组泛型化的数据结构。
2)泛型算法:利用函数模板构建的一组与元素和容器的类型无关的通用算法。
3)迭代器:利用操作符重载为不同的容器提供接口一致的元素访问方式,协助泛型算法做到容器无关。
2.实现案例
双向线性链表
正向顺序可写迭代器
线性查找

// 双向线性链表容器及其迭代器和泛型算法
#include <cstring>
#include <iostream>
#include <stdexcept>
using namespace std;
// 双向线性链表容器
template<typename T>
class List {
public:
    // 构造、析构、拷贝构造、拷贝赋值
    List (void) : m_head (NULL),
        m_tail (NULL) {}
    ~List (void) {
        clear ();
    }
    List (List const& that) :
        m_head (NULL), m_tail (NULL) {
        for (Node* node = that.m_head;
            node; node = node->m_next)
            push_back (node->m_data);
    }
    List& operator= (List const& that) {
        if (&that != this) {
            List list = that;
            swap (m_head, list.m_head);
            swap (m_tail, list.m_tail);
        }
        return *this;
    }
    // 获取首元素
    T& front (void) {
        if (empty ())
            throw underflow_error (
                "链表下溢!");
        return m_head->m_data;
    }
    T const& front (void) const {
        return const_cast<List*> (this)->
            front ();
    }
    // 向首部压入
    void push_front (T const& data) {
        m_head = new Node (data, NULL,
            m_head);
        if (m_head->m_next)
            m_head->m_next->m_prev =
                m_head;
        else
            m_tail = m_head;
    }
    // 从首部弹出
    void pop_front (void) {
        if (empty ())
            throw underflow_error (
                "链表下溢!");
        Node* next = m_head->m_next;
        delete m_head;
        m_head = next;
        if (m_head)
            m_head->m_prev = NULL;
        else
            m_tail = NULL;
    }
    // 获取尾元素
    T& back (void) {
        if (empty ())
            throw underflow_error (
                "链表下溢!");
        return m_tail->m_data;
    }
    T const& back (void) const {
        return const_cast<List*> (this)->
            back ();
    }
    // 向尾部压入
    void push_back (T const& data) {
        m_tail = new Node (data, m_tail);
        if (m_tail->m_prev)
            m_tail->m_prev->m_next =
                m_tail;
        else
            m_head = m_tail;
    }
    // 从尾部弹出
    void pop_back (void) {
        if (empty ())
            throw underflow_error (
                "链表下溢!");
        Node* prev = m_tail->m_prev;
        delete m_tail;
        m_tail = prev;
        if (m_tail)
            m_tail->m_next = NULL;
        else
            m_head = NULL;
    }
    // 删除所有匹配元素
    void remove (T const& data) {
        for (Node* node = m_head, *next;
            node; node = next) {
            next = node->m_next;
            if (equal (node->m_data,
                data)) {
                if (node->m_prev)
                    node->m_prev->m_next=
                        node->m_next;
                else
                    m_head =
                        node->m_next;
                if (node->m_next)
                    node->m_next->m_prev=
                        node->m_prev;
                else
                    m_tail =
                        node->m_prev;
                delete node;
            }
        }
    }
    // 清空
    void clear (void) {
        while (! empty ())
            pop_front ();
    }
    // 判空
    bool empty (void) const {
        return ! m_head && ! m_tail;
    }
    // 大小
    size_t size (void) const {
        size_t nodes = 0;
        for (Node* node = m_head;
            node; node = node->m_next)
            ++nodes;
        return nodes;
    }
    // 随机访问
    // O(N)
    T& operator[] (size_t i) {
        for (Node* node = m_head; node;
            node = node->m_next)
            if (! i--)
                return node->m_data;
        throw out_of_range("下标越界!");
    }
    T const& operator[] (size_t i) const{
        return const_cast<List&> (
            *this)[i];
    }
    // 插入输出流
    friend ostream& operator<< (
        ostream& os, List const& list) {
        for (Node* node = list.m_head;
            node; node = node->m_next)
            os << *node;
        return os;
    }
private:
    // 节点
    class Node {
    public:
        Node (T const& data,
            Node* prev = NULL,
            Node* next = NULL) :
            m_data (data), m_prev (prev),
            m_next (next) {}
        friend ostream& operator<< (
            ostream& os,
            Node const& node) {
            return os << '('
                << node.m_data << ')';
        }
        T     m_data; // 数据
        Node* m_prev; // 前指针
        Node* m_next; // 后指针
    };
    // 判等函数的通用版本
    bool equal (T const& a,
        T const& b) const {
        return a == b;
    }
    Node* m_head; // 头指针
    Node* m_tail; // 尾指针
public:
    // 正向顺序可写迭代器
    // 正向:增向尾,减向首
    // 顺序:一次只能迭代一个元素
    // 可写:目标元素可被修改
    class Iterator {
    public:
        Iterator (Node* head = NULL,
            Node* tail = NULL,
            Node* node = NULL) :
            m_head (head), m_tail (tail),
            m_node (node) {}
        bool operator== (
            Iterator const& it) const {
            return m_node == it.m_node;
        }
        bool operator!= (
            Iterator const& it) const {
            return ! (*this == it);
        }
        Iterator& operator++ (void) {
            if (m_node)
                m_node = m_node->m_next;
            else
                m_node = m_head;
            return *this;
        }
        Iterator const operator++ (int) {
            Iterator old = *this;
            ++*this;
            return old;
        }
        Iterator& operator-- (void) {
            if (m_node)
                m_node = m_node->m_prev;
            else
                m_node = m_tail;
            return *this;
        }
        Iterator const operator-- (int) {
            Iterator old = *this;
            --*this;
            return old;
        }
        T& operator* (void) const {
            return m_node->m_data;
        }
        T* operator-> (void) const {
            return &**this;
        }
    private:
        Node* m_head;
        Node* m_tail;
        Node* m_node;
        friend class List;
    };
    // 获取起始迭代器
    // 指向首元素
    Iterator begin (void) {
        return Iterator (m_head, m_tail,
            m_head);
    }
    // 获取终止迭代器
    // 指向尾元素之后
    Iterator end (void) {
        return Iterator (m_head, m_tail);
    }
    // 插入
    // 在loc迭代器的目标元素之前插入data
    // 返回指向新插入元素的迭代器
    Iterator insert (Iterator loc,
        T const& data) {
        if (loc == end ()) {
            push_back (data);
            return Iterator (m_head,
                m_tail, m_tail);
        }
        else {
            Node* node = new Node (data,
                loc.m_node->m_prev,
                loc.m_node);
            if (node->m_prev)
                node->m_prev->m_next =
                    node;
            else
                m_head = node;
            node->m_next->m_prev = node;
            return Iterator (m_head,
                m_tail, node);
        }
    }
    // 删除
    // 删除loc迭代器的目标元素
    // 返回指向被删元素下一个位置的迭代器
    Iterator erase (Iterator loc) {
        if (loc == end ())
            throw invalid_argument (
                "无效参数!");
        if (loc.m_node->m_prev)
            loc.m_node->m_prev->m_next =
                loc.m_node->m_next;
        else
            m_head = loc.m_node->m_next;
        if (loc.m_node->m_next)
            loc.m_node->m_next->m_prev =
                loc.m_node->m_prev;
        else
            m_tail = loc.m_node->m_prev;
        Node* next = loc.m_node->m_next;
        delete loc.m_node;
        return Iterator (m_head, m_tail,
            next);
    }
};
// 判等函数针对char const*类型的特化版本
template<>
bool List<char const*>::equal (
    char const* const& a,
    char const* const& b) const {
    return ! strcmp (a, b);
}
// 线性查找
/*
int find (int data[], int size, int key){
    for (int i = 0; i < size; ++i)
        if (data[i] == key)
            return i;
    return -1;
}
int* find (int* begin, int* end,int key){
    int* it;
    for (it = begin; it != end; ++it)
        if (*it == key)
            break;
    return it;
}
*/
template<typename IT, typename KEY>
IT find (IT begin,IT end,KEY const& key){
    IT it;
    for (it = begin; it != end; ++it)
        if (*it == key)
            break;
    return it;
}
// 测试用例
void test1 (void) {
    List<int> list;
    list.push_front (40);
    list.push_front (30);
    list.push_front (20);
    list.push_front (10);
    list.push_front (0);
    cout << list << endl;
    // 0 10 20 30 40
    list.front () = 5;
    cout << list << endl;
    // 5 10 20 30 40
    List<int> const& cr = list;
//    ++cr.front ();
    cout << cr.front () << endl; // 5
    list.pop_front ();
    cout << list << endl;
    // 10 20 30 40
    list.push_back (50);
    list.push_back (60);
    list.push_back (70);
    list.push_back (80);
    list.push_back (90);
    cout << list << endl;
    // 10 20 30 40 50 60 70 80 90
    list.back () += 5;
    cout << list << endl;
    // 10 20 30 40 50 60 70 80 95
    List<int> const* cp = &list;
//    cp->back ()--;
    cout << cp->back () << endl; // 95
    list.pop_back ();
    cout << list << endl;
    // 10 20 30 40 50 60 70 80
    list.push_front (50);
    list.push_front (50);
    list.push_back (50);
    list.push_back (50);
    cout << list << endl;
    // 50 50 10 20 30 40 50 60 70 80 50
    // 50
    list.remove (50);
    cout << list << endl;
    // 10 20 30 40 60 70 80
    cout << boolalpha << list.empty ()
        << ' ' << list.size () << endl;
    // false 7
    list.clear ();
    cout << list.empty () << ' '
        << list.size () << endl;
    // true 0
    try {
        list.pop_front ();
    }
    catch (exception& ex) {
        cout << ex.what () << endl;
    }
}
void test2 (void) {
    List<int> l1;
    l1.push_back (100);
    l1.push_back (200);
    l1.push_back (300);
    l1.push_back (400);
    l1.push_back (500);
    List<int> l2 = l1; // 拷贝构造
    cout << "l1: " << l1 << endl;
    cout << "l2: " << l2 << endl;
    ++l1.front ();
    --l2.back ();
    cout << "l1: " << l1 << endl;
    cout << "l2: " << l2 << endl;
    l2 = l1; // 拷贝赋值
    cout << "l1: " << l1 << endl;
    cout << "l2: " << l2 << endl;
    l1.pop_front ();
    l2.pop_back ();
    cout << "l1: " << l1 << endl;
    cout << "l2: " << l2 << endl;
}
void test3 (void) {
    char sa[][256] = {"北京", "上海",
        "北京", "广州", "北京"};
//    char const* sa[] = {"北京", "上海",
//        "北京", "广州", "北京"};
//    List<string> ls;
    List<char const*> ls;
    for (size_t i = 0; i < sizeof (sa) /
        sizeof (sa[0]); ++i)
        ls.push_back (sa[i]);
    cout << ls << endl;
    ls.remove ("北京");
    cout << ls << endl;
}
void test4 (void) {
    List<int> list;
    for (int i = 1; i <= 10; ++i)
        list.push_back (i);
    cout << list << endl;
    /*
    // O(N^2)
    size_t size = list.size ();
    for (size_t i = 0; i < size; ++i)
        list[i] *= list[i];
    */
    // O(N)
    for (List<int>::Iterator it =
        list.begin (); it != list.end ();
        ++it)
        *it *= *it;
    cout << list << endl;
}
void test5 (void) {
    List<int> list;
    list.insert (list.end (), 10);
    list.insert (list.end (), 50);
    list.insert (list.end (), 90);
    cout << list << endl;
    // 10 50 90
    List<int>::Iterator loc =
        list.begin ();
    list.insert (
        list.insert (
            list.insert (
                ++loc, 40), 30), 20);
    cout << list << endl;
    // 10 20 30 40 50 90
    loc = list.end ();
    list.insert (
        list.insert (
            list.insert (
                --loc, 80), 70), 60);
    cout << list << endl;
    // 10 20 30 40 50 60 70 80 90
    loc = list.begin ();
    list.erase (
        list.erase (
            list.erase (++++++loc)));
    cout << list << endl;
    // 10 20 30 70 80 90
}
void test6 (void) {
    int ai[] = {13, 27, 19, 33, 51};
    size_t size = sizeof (ai ) /
        sizeof (ai[0]);
    int* pi = find (ai, ai + size, 33);
//    int* pi = find (ai, ai + size, 32);
    if (pi == ai + size)
        cout << "没找到!" << endl;
    else
        cout << "找到了:" << *pi <<endl;
    List<string> ls;
    ls.push_back ("济南");
    ls.push_back ("菏泽");
    ls.push_back ("潍坊");
    ls.push_back ("滨州");
    ls.push_back ("临沂");
    List<string>::Iterator it = find (
        ls.begin (), ls.end (), "滨州");
//    List<string>::Iterator it = find (
//        ls.begin (), ls.end (), "淄博");
    if (it == ls.end ())
        cout << "没找到!" << endl;
    else
        cout << "找到了:" << *it <<endl;
}
// 进程入口
int main (void) {
//    test1 ();
//    test2 ();
//    test3 ();
//    test4 ();
//    test5 ();
    test6 ();
    return 0;
}
#include <iostream>
#include <list>
#include <algorithm>
using namespace std;
void print (list<int> const& li) {
    for (list<int>::const_iterator it =
        li.begin (); it != li.end ();
        ++it)
        cout << *it << ' ';
    cout << endl;
}
class IntCmp {
public:
    IntCmp (bool raise = true) :
        m_raise (raise) {}
    bool operator() (int a, int b) const{
        if (m_raise)
            return a < b;
        else
            return a > b;
    }
private:
    bool m_raise;
};
int main (void) {
    int ai[] = {10,10,20,20,10,20,30,20,
        20,10,10};
    list<int> l1 (ai, ai + sizeof (ai) /
        sizeof (ai[0]));
    print (l1);
//    sort (l1.begin (), l1.end ());
    l1.sort (IntCmp ());
    print (l1);
    l1.sort (IntCmp (false));
    print (l1);
    l1.unique ();
    cout << "l1: ";
    print (l1);
    list<int> l2;
    l2.push_back (1000);
    l2.push_back (2000);
    l2.push_back (3000);
    l2.push_back (4000);
    l2.push_back (5000);
    cout << "l2: ";
    print (l2);
    list<int>::iterator pos = l1.begin();
    /*
    l1.splice (++pos, l2);
    *//*
    list<int>::iterator del = l2.begin();
    l1.splice (++pos, l2, ++++del);
    */
    list<int>::iterator begin =
        l2.begin (), end = l2.end ();
    l1.splice (++pos, l2, ++begin,
        --end);
    cout << "l1: ";
    print (l1);
    cout << "l2: ";
    print (l2);
    l1.clear ();
    l1.push_back (100);
    l1.push_back (500);
    l1.push_back (700);
    l2.clear ();
    l2.push_back (200);
    l2.push_back (300);
    l2.push_back (600);
    l2.push_back (800);
    l2.push_back (900);
    cout << "l1: ";
    print (l1);
    cout << "l2: ";
    print (l2);
    l1.merge (l2);
    cout << "l1: ";
    print (l1);
    cout << "l2: ";
    print (l2);
    return 0;
}
原文地址:https://www.cnblogs.com/LuckCoder/p/8668393.html