双向链表实现简单的list

双向链表结构:

定义一个如下结构体

struct Node
{
    Object data;
    Node *next;
    Node *prev;
};

下面为list的具体实现:

#include <iostream>
using namespace std;

template <typename Object>
class List
{
private:
    //链表结点的定义
    struct Node
    {
        Object data;
        Node *next;
        Node *prev;

        Node(const Object &d = Object(), Node *p = nullptr, Node *n = nullptr)
            :data(d), next(n), prev(p){}
    };
private:
    int theSize;
    Node *head;
    Node *tail;

    void init()
    {
        theSize = 0;
        head = new Node;
        tail = new Node;
        head->next = tail;
        tail->prev = head;
    }
public:
    class const_iterator
    {
    public:
        const_iterator() :current(nullptr)
        {}

        const Object &operator* () const
        {
            return retrieve();
        }

        const_iterator &operator++ ()
        {
            current = current->next;
            return *this;
        }

        const_iterator operator++(int)
        {
            const_iterator old = *this;
            ++(*this);
            return old;
        }

        bool operator== (const const_iterator &rhs) const
        {
            return current == rhs.current;
        }

        bool operator!= (const const_iterator &rhs) const
        {
            return !(*this == rhs);
        }
    protected:
        Node* current;
        Object &retrieve() const
        {
            return current->data;
        }
        const_iterator(Node *p) :current(p){}

        friend class List<Object>;
    };

    class iterator :public const_iterator
    {
    public:
        iterator(){}
        Object & operator* ()
        {
            return retrieve();
        }

        const Object & operator* () const
        {
            return const_iterator::operator*();
        }

        iterator &operator++ ()
        {
            current = current->next;
            return *this;
        }

        iterator &operator++ (int)
        {
            iterator old = *this;
            ++(*this);
            return old;
        }
    protected:
        iterator(Node *p) :const_iterator(p)
        {}

        friend class List<Object>;
    };
public:
    List()
    {
        init();
    }

    //拷贝构造函数
    List(const List &rhs)
    {
        init();
        *this = rhs;
    }

    ~List()
    {
        clear();
        delete head;
        delete tail;
    }

    //重载操作符=
    const List &operator=(const List &rhs)
    {
        if (this == &rhs)
            return *this;
        clear();
        for (const_iterator itr = rhs.begin(); itr != rhs.end(); ++itr)
        {
            push_back(*itr);
        }
        return *this;
    }

    iterator begin()
    {
        return iterator(head->next);
    }

    const_iterator begin() const
    {
        return const_iterator(head->next);
    }

    iterator end()
    {
        return iterator(tail);
    }

    const_iterator end() const
    {
        return const_iterator(tail);
    }

    int size() const
    {
        return theSize;
    }

    bool empty() const
    {
        return size() == 0;
    }

    void clear()
    {
        while (!empty())
        {
            pop_front();
        }
    }

    Object &front()
    {
        return *begin();
    }

    const Object &front() const
    {
        return *begin();
    }

    Object &back()
    {
        return *--end();
    }

    const Object &back() const
    {
        return *--end();
    }

    void push_front(const Object &x)
    {
        insert(begin(), x);
    }

    void push_back(const Object &x)
    {
        insert(end(), x);
    }

    void pop_front()
    {
        erase(begin());
    }

    void pop_back()
    {
        erase(--end());
    }

    iterator insert(iterator itr, const Object &x)
    {
        Node *p = itr.current;
        theSize++;
        Node *newNode = new Node(x, p->prev, p);
        p->prev = p->prev->next = newNode;
        return iterator(newNode);
    }

    iterator erase(iterator itr)
    {
        Node* p = itr.current;
        iterator retVal(p->next);
        p->prev->next = p->next;
        p->next->prev = p->prev;
        delete p;
        theSize--;
        return retVal;
    }

    iterator erase(iterator start, iterator end)
    {
        for (iterator itr = start; itr != end;)
        {
            itr = erase(itr);
        }
        return end;
    }
};

int main()
{
    List<int> test;
    test.push_back(1);
    test.push_back(3);
    test.push_back(5);
    test.push_front(0);
    for (List<int>::iterator itr = test.begin(); itr != test.end();itr++)
    {
        cout << *itr << ‘ ‘;
    }
    return 0;
}

测试结果:

时间: 2024-10-15 21:12:53

双向链表实现简单的list的相关文章

双向链表的简单Java实现-sunziren

写在前面,csdn的那篇同名博客就是我写的,我把它现在在这边重新发布,因为我实在不想用csdn了,那边的广告太多了,还有就是那个恶心人的"阅读更多"按钮,惹不起我躲得起. 在上次分享完单向链表的简单编写后,索性对于双向链表进行了一定的了解,在上次的基础上进行了一定程度的改进,做了一个非循环的双向链表. 双向链表的特点在于每个节点不仅知道自己的下属节点而且还知道自己的父节点.在双向链表的逆序方法中,我使用的队列来支持这个操作,利用了队列的先进先出的特点. 1 package demo_4

c语言 双向链表的简单操作-创建、插入、删除

数据结构-双向链表的创建.插入和删除 双向链表是数据结构中重要的结构,也是线性结构中常用的数据结构,双向指针,方便用户从首结点开始沿指针链向后依次遍历每一个结点,结点的前驱和后继查找方便. #include <stdio.h> #include <stdlib.h> //双向链表结点的定义 typedef struct dbnode { int data; struct dbnode *prio, *next; }DbNode, linkdblist; //创建双向链表 DbNod

双向链表的简单实现

package dataStructure; public class DoubleLinkedList<T> { private final Node<T> head; private int count = 0; public DoubleLinkedList() { head = new Node<T>(null,null,null); head.pre = head; head.next = head; } public int size() { return

双向链表(3) - 反转双向链表

双向链表的反转过程,可以参考下面的例图: (a) 原始双向链表 (b) 反转后的双向链表 下面是一个用于反转双向链表的简单方法.所需要做的事情就是交换每个节点的前向指针和后向指针,然后调整链表的头指针和尾指针. #include <iostream> struct Node { int data; Node *next; // 指向下一个节点 Node *prev; // 指向前一个节点 }; //对链表进行反转 void reverse(Node **head) { Node *temp =

JAVA实现单双向链表的增、删、改、查

单向链表 package com.ywx.link; /** * 单向链表 * @author vashon * */ public class LinkTest { public static void main(String[] args) { Link l=new Link(); l.addNode("A"); l.addNode("B"); l.addNode("C"); l.addNode("D"); l.addNo

redis 5.0.7 源码阅读——双向链表

redis中动态字符串sds相关的文件为:adlist.h与adlist.c 一.数据结构 redis里定义的双向链表,与普通双向链表大致相同 单个节点: 1 typedef struct listNode { 2 struct listNode *prev; 3 struct listNode *next; 4 void *value; 5 } listNode; 链表: 1 typedef struct list { 2 listNode *head; 3 listNode *tail; 4

一口气说出Redis 5种数据结构及对应使用场景,面试要加分的

整理了一些Java方面的架构.面试资料(微服务.集群.分布式.中间件等),有需要的小伙伴可以关注公众号[程序员内点事],无套路自行领取 更多优选 一口气说出 9种 分布式ID生成方式,面试官有点懵了 3万字总结,Mysql优化之精髓 为了不复制粘贴,我被逼着学会了JAVA爬虫 技术部突然宣布:JAVA开发人员全部要会接口自动化测试框架 写在前边 也当过面试官,面试过不少应聘者,因为是我自己招人自己用,所以我不会看应聘者造火箭的技术有多牛比,只看拧螺丝的手艺瓷不瓷实.毕竟以后是一个整体,拖了大家后

详谈双向链表的实现与简单操作

1.单链表的一个优点是结构简单,但是它也有一个缺点,即在单链表中只能通过一个结点的引用访问其后续结点,而无法直接访问其前驱结点,要在单链表中找到某个结点的前驱结点,必须从链表的首结点出发依次向后寻找,但是需要Ο (n)时间.为此我们可以扩展单链表的结点结构,使得通过一个结点的引用,不但能够访问其后续结点,也可以方便的访问其前驱结点.扩展单链表结点结构的方法是,在单链表结点结构中新增加一个域,该域用于指向结点的直接前驱结点.扩展后的结点结构是构成双向链表的结点结构.在双向链表中进行查找与在单链表中

C语言双向链表简单实现及图示(初始化/插入节点/删除节点)

-------------------------------------------- 双向链表 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 和单向链表相比有以下优势: 插入删除不需要移动元素外,可以原地插入删除 可以双向遍历 - - - - -