C++数据结构 之 链表_Linked List

来源:互联网 发布:移民新西兰 知乎 编辑:程序博客网 时间:2024/06/14 06:48

C++数据结构 之 链表_Linked List

源代码只包含头文件

注:需要C++11的支持

一、链表

链表的思想类似于一根链子,环环相扣,每一个链环都是一个节点,每个节点中有自己的数据,还有指向前一个节点和后一个节点的指针。因此访问链表,不能随机访问,必须一个接一个,显然访问时间较长,但也是线性时间以内。
链表有头有尾,在本实现中,即使是空链表,头尾节点也是存在的。

支持的操作:
1、push_back (尾压入):将节点从尾部压入链表中。
2、push_front (首压入):将节点从首部压入链表中。
3、back 返回尾节点前一个节点的数据。
4、front 返回首节点下一个节点的数据。
5、front_insert 在当前节点的前一个位置一个新的节点。
6、back_front 在当先节点的下一个位置插入一个新的节点。
7、erase 删除当前节点,或者删除制定范围内的节点(此范围 [begin,end),注意括号的区别)。
8、clear 删除所有,初头尾节点以外的节点。
9、resize 添加n个默认初始化数据的节点
10、sort 按照数据less函数对象给链表排序。
11、search 返回所要查找数据的迭代器。
12、begin 返回首节点的下一个节点的迭代器。
13、end 返回尾节点的迭代器。
14 、rbegin 返回为节点的上一个节点的迭代器。
15、rend 返回首节点的迭代器。

示意图:
链表

二、源代码:

#ifndef LIST_H#define LIST_H#include <memory>#include <stdexcept>#include <vector>#include <algorithm>using std::shared_ptr;using std::make_shared;template<typename Data>class List {    friend class const_iterator;private:    struct Node {        Node() = default;        Data data;        shared_ptr<Node> prev = nullptr;        shared_ptr<Node> next = nullptr;    };    shared_ptr<Node> head = make_shared<Node>();    shared_ptr<Node> tail = make_shared<Node>();    void initialize() {        head->next = tail;        tail->prev = head;    }    size_t List_Size = 0;public:    // CLASS const_iterator    class const_iterator {        friend class List<Data>;    public:        const_iterator() = default;        ~const_iterator() = default;        const_iterator(shared_ptr<Node> p) : ptr(p) {}        const Data& operator*() const {            return ptr->data;        }        const_iterator& operator+(long long LL) {            for (auto i = 0; i != LL; ++i) {                if (ptr->next != nullptr) {                    ptr = ptr->next;                }            }            return *this;        }        const_iterator& operator-(long long LL) {            for (auto i = 0; i != LL; ++i) {                if (ptr->prev != nullptr) {                    ptr = ptr->prev;                }            }            return *this;        }        const_iterator& operator++() {            ptr = ptr->next;            return *this;        }        const_iterator& operator++(int) {            const_iterator temp = *this;            ++*this;            return temp;        }        const_iterator& operator--() {            ptr = ptr->prev;            return *this;        }        const_iterator& operator--(int) {            const_iterator temp = *this;            --*this;            return temp;        }        bool operator==(const const_iterator &rhs) const {            return ptr == rhs.ptr;        }        bool operator!=(const const_iterator &rhs) const {            return !(*this == rhs);        }    protected:        shared_ptr<Node> ptr;    };    // CLASS iterator    class iterator : public const_iterator {        friend class List<Data>;    public:        iterator() = default;        ~iterator() = default;        Data& operator*() {            return ptr->data;        }        const Data& operator*() const {            return const_iterator::operator*();        }        iterator& operator+(long long LL) {            for (auto i = 0; i != LL; ++i) {                if (ptr->next != nullptr) {                    ptr = ptr->next;                }            }            return *this;        }        iterator& operator-(long long LL) {            for (auto i = 0; i != LL; ++i) {                if (ptr->prev != nullptr) {                    ptr = ptr->prev;                }            }            return *this;        }        iterator& operator++() {            ptr = ptr->next;            return *this;        }        iterator& operator++(int) {            iterator temp = *this;            ++*this;            return temp;        }        iterator& operator--() {            ptr = ptr->prev;            return *this;        }        iterator& operator--(int) {            iterator temp = *this;            --*this;            return temp;        }    protected:        iterator(shared_ptr<Node> p) : const_iterator(p) {}    };    // CLASS const_reverse_iterator    class const_reverse_iterator {        friend class List<Data>;    public:        const_reverse_iterator() = default;        ~const_reverse_iterator() = default;        const_reverse_iterator(shared_ptr<Node> p) : ptr(p) {}        const Data& operator*() const {            return ptr->data;        }        const_reverse_iterator& operator+(long long LL) {            for (auto i = 0; i != LL; ++i) {                if (ptr->prev != nullptr) {                    ptr = ptr->prev;                }            }            return *this;        }        const_reverse_iterator& operator-(long long LL) {            for (auto i = 0; i != LL; ++i) {                if (ptr->next != nullptr) {                    ptr = ptr->next;                }            }            return *this;        }        const_reverse_iterator& operator++() {            ptr = ptr->prev;            return *this;        }        const_reverse_iterator& operator++(int) {            const_reverse_iterator temp = *this;            ++*this;            return temp;        }        const_reverse_iterator& operator--() {            ptr = ptr->next;            return *this;        }        const_reverse_iterator& operator--(int) {            const_reverse_iterator temp = *this;            --*this;            return temp;        }        bool operator==(const const_reverse_iterator& rhs) {            return ptr == rhs.ptr;        }        bool operator!=(const const_reverse_iterator& rhs) {            return !(*this == rhs);        }    protected:        shared_ptr<Node> ptr;    };    // CLASS reverse_iterator    class reverse_iterator : public const_reverse_iterator {        friend class List<Data>;    public:        reverse_iterator() = default;        ~reverse_iterator() = default;        Data& operator*() {            return ptr->data;        }        const Data& operator*() const {            return const_reverse_iterator::operator*();        }        reverse_iterator& operator+(long long LL) {            for (auto i = 0; i != LL; ++i) {                if (ptr->prev != nullptr) {                    ptr = ptr->prev;                }            }            return *this;        }        reverse_iterator& operator-(long long LL) {            for (auto i = 0; i != LL; ++i) {                if (ptr->next != nullptr) {                    ptr = ptr->next;                }            }            return *this;        }        reverse_iterator& operator++() {            ptr = ptr->prev;            return *this;        }        reverse_iterator& operator++(int) {            reverse_iterator temp = *this;            ++*this;            return temp;        }        reverse_iterator& operator--() {            ptr = ptr->next;            return *this;        }        reverse_iterator& operator--(int) {            reverse_iterator temp = *this;            --*this;            return temp;        }    protected:        reverse_iterator(shared_ptr<Node> p) : const_reverse_iterator(p) {}    };public:    List() { initialize(); }    ~List() = default;    //List(const List &rhs) {    //  clear();    //  for (auto &i : rhs) {    //      push_back(i);    //  }    //}    //List& operator=(const List &rhs) {    //  if (this == &rhs) {    //      return *this;    //  }    //  clear();    //  for (auto &i : rhs) {    //      push_back(i);    //  }    //  return *this;    //}    iterator begin() {        return iterator(head->next);    }    const_iterator begin() const {        return const_iterator(head->next);    }    reverse_iterator rbegin() {        return reverse_iterator(tail->prev);    }    const_reverse_iterator rbegin() const {        return const_reverse_iterator(tail->prev);    }    iterator end() {        return iterator(tail);    }    const_iterator end() const {        return const_iterator(tail);    }    reverse_iterator rend() {        return reverse_iterator(head);    }    const_reverse_iterator rend() const {        return const_reverse_iterator(head);    }    // Front insert.    iterator front_insert(iterator itr, const Data& data) {        shared_ptr<Node> p = itr.ptr;        ++List_Size;        auto a = make_shared<Node>();        a->data = data;        a->prev = p->prev;        a->next = p;        p->prev = a;        a->prev->next = a;        return iterator(a);        //return iterator(p->prev = p->prev->next = make_shared<Node>(data, p->prev, p));    }    iterator front_insert(iterator itr) {        shared_ptr<Node> p = itr.ptr;        ++List_Size;        auto a = make_shared<Node>();        a->prev = p->prev;        a->next = p;        p->prev = a;        a->prev->next = a;        return iterator(a);    }    // Back_insert.    iterator back_insert(iterator itr, const Data& data) {        shared_ptr<Node> p = itr.ptr;        ++List_Size;        auto a = make_shared<Node>();        a->data = data;        a->prev = p;        a->next = p->next;        p->next = a;        a->next->prev = a;        return iterator(a);        //return iterator(p->next = p->next->prev = make_shared<Node>(data, p, p->next));    }    iterator back_insert(iterator itr) {        shared_ptr<Node> p = itr.ptr;        ++List_Size;        auto a = make_shared<Node>();        a->prev = p;        a->next = p->next;        p->next = a;        a->next->prev = a;        return iterator(a);    }    iterator erase(iterator itr) {        shared_ptr<Node> p = itr.ptr;        iterator itaval(p->next);        try {            if (p == head) {                throw runtime_error("No elements can erase!");            }            else if (p == tail) {                throw runtime_error("No elements can erase!");            }            else {                p->prev->next = p->next;                p->next->prev = p->prev;                --List_Size;            }        }        catch (runtime_error err) {            cout << err.what() << endl;        }        return itaval;    }    iterator erase(iterator begin, iterator end) {  // [begin, end)        while (begin != end) {            begin = erase(begin);        }        return iterator(end);    }    void clear() {        while (!empty()) {            pop_front();        }    }    void print() {        for (auto &i : *this) {            cout << i << endl;        }    }    void resize(long long LL) {        for (auto i = 0; i != LL; ++i) {            push_back();        }    }    void resize(long long LL, const Data &x) {        for (auto i = 0; i != LL; ++i) {            push_back(x);        }    }    void sort() {        std::vector<Data> temp_v;        for (auto &i : *this) {            temp_v.push_back(i);        }        std::stable_sort(temp_v.begin(), temp_v.end());        clear();        for (auto &i : temp_v) {            push_back(i);        }    }    iterator search(const Data &x) {        auto temp_count = 0;        for (auto &i : *this) {            if (i != x) {                ++temp_count;            }            else {                break;            }        }        return begin() + temp_count;    }    bool empty() { return List_Size == 0; }    size_t size() { return List_Size; }    Data& front() { return *begin(); }    const Data& front() const { return front(); }    Data& back() { return *--end(); }    const Data& back() const { return back(); }    void push_front() { front_insert(begin()); }    void push_front(const Data &x) { front_insert(begin(), x); }    void push_back() { back_insert(--end()); }    void push_back(const Data &x) { back_insert(--end(), x); }    void pop_front() { erase(begin()); }    void pop_back() { erase(--end()); }};#endif // !LIST_H

注释:所有对节点的访问,已经抽象成为使用迭代器访问。

0 0
原创粉丝点击