链表的定义以及实现

来源:互联网 发布:红米1s支持4g网络吗 编辑:程序博客网 时间:2024/05/21 07:11

**

链表是一种物理存储单元上非连续、非顺序的存储结构,数据元素的逻辑顺序是通过链表中的指针链接次序实现的。链表由一系列结点(链表中每一个元素称为结点)组成,结点可以在运行时动态生成。每个结点包括两个部分:一个是存储数据元素的数据域,另一个是存储下一个结点地址的指针域

**。

这里写图片描述

/*数据结构:list功能:      front() 返回第一个元素      back() 返回最后一个元素      clear() 删除所有元素      empty() 如果list是空的则返回true      push_back() 在list的末尾添加一个元素      push_front() 在list的头部添加一个元素      pop_back() 删除最后一个元素      pop_front() 删除第一个元素      size() 返回list中的元素个数      splice() 合并两个list      reverse() 把list的元素倒转      begin()  返回链表第一个元素的迭代器      end()    返回链表最后一个元素的迭代器      erase() 删除迭代器所指向的一个元素      insert() 通过迭代器在指定位置的元素位置之前插入新元素来扩展容器。/************ 暂时未实现************//*  sort() 给list排序  merge() 排序合并两个list*/#include <iostream>template <typename type>class List;template <typename type>class Iterator;template <typename type>class Node{private:    type data;    Node *next;    Node *pre;public:    Node():next(NULL),pre(NULL){}    Node(type data):data(data),next(NULL),pre(NULL){}    friend class List<type>;    friend class Iterator<type>;};/* Iterator 迭代器功能需求:     1.重载运算符 *     2.重载运算符 ->     3.重载运算符 ++     4.重载运算符 --     5.重载运算符 ==     6.重载运算符 !=     7.返回该结点*/template <typename type>class Iterator{private:   Node<type> *node;public:    Iterator():node(NULL){}    Iterator(Node<type> *node):node(node){}    type& operator *()const    {        return (node->data);    }    Node<type>* operator ->()const    {        return node;    }    Iterator operator ++() // ++ 前缀    {       node = node->next;       return *this;    }    Iterator operator --()    {       node = node->pre;       return *this;    }     Iterator operator ++(int)// ++ 后缀    {       Iterator temp = (*this);       ++(*this);  //重载过的方法       return temp;    }     Iterator operator --(int)    {       Iterator temp = (*this)       --(*this);       return temp;    }    bool operator ==(const Iterator B)const    {        return (node==B.node);    }    bool operator !=(const Iterator B)const    {        return (node!=B.node);    }    Node<type>* getNode()const    {        return node;    }};template <typename type>class List{private:    Node<type> *Head;    Node<type> *End;    std::string::size_type Size;public:    typedef Iterator<type> Iterator;    Iterator begin()    {        Iterator iter(Head->next);        return iter;    }    Iterator end()    {        Iterator iter(End->next);        return iter;    }    List():Size(0)    {      Head = new Node<type>();  //头节点不存数据      End = Head;    }~List(){    Node<type> *temp = Head;    Node<type> *temp2 = NULL;    while(!temp)    {        temp2 = temp;        temp = temp->next;        delete temp2;    }}bool empty(){  return Size==0;}Node<type>& front(){return Head->next;}Node<type>& back(){return End;}void clear(){  if(empty()) return;  Node<type> *temp = Head->next;  Node<type> *temp2 = NULL;  while(!empty())  {     if(temp->next)     temp2 = temp->next;     delete temp;     temp = temp2;     Size--;  }}void insert(Iterator it,type data){  Node<type>* itq = it.getNode();  if(!itq) return;  Node<type>* d = new Node<type>(data);   d->pre = itq->pre;   itq->pre->next = d;   d->next = itq;   itq->pre = d;   Size++;}/* 因为是插入在迭代器所指向的元素之前,所以End位置不会发生变化*/void push_front(type data){    Node<type> *d = new Node<type>(data);    if(Head == End)         //第一个元素的情况    {    d->next = Head;    d->pre = Head;    Head->next = d;    Head->pre = d;    End = d;    Size++;    }    else    {     /* d->next = Head->next;      d->pre = Head;      Head->next = d;      Size++;*/      insert(begin(),data);    }}void push_back(type data){    Node<type> *d = new Node<type>(data);    if(Head == End)         //第一个元素的情况    {    d->next = End;     //Head    d->pre = End;      //    End = d;    Head->next=d;    Head->pre=d;    Size++;    return;    }    else    {      d->next = End->next;      d->pre = End;      End->next = d;      End = d;      Size++;       return;    }}void erase(Iterator& it){    Node<type> *p1 = it.getNode;    Node<type> *p2 = p1->pre;    if(!p1)return;    else    {        p2->next = p1->next;        p1->next->pre = p1->pre;        delete p1;        End = p2->next;        it();        Size--;    }}// head 1 2 3void pop_back(){ earse(Head->next);}void pop_front(){ earse(End);}// head 0 1 2//void splice(List& B){    if(!B.empty())    {        B.Head->next->pre = End;        End->next = B.Head->next;        End = B.End;        /*↑连接处指针变换↑*/        Head->pre = End;        End->next = Head;         /*↑头尾处指针变换↑*/         Size+=B.Size;         B.Head->next = NULL;         B.Head->pre = NULL;         B.Size = 0;         /*↑把链表B置为空↑*/    }}/*A.Head->next = 9A.Head->pre = 14A.End->next = HeadA.End->pre = 13*/void reverse()  //采用头插法{    if(empty()||Size==1) return;     Node<type> *i = Head->next;     Node<type> *temp;     Node<type> *temp2;     // Head->next = i;     temp2 = i->next;   //提前保存第二个结点数据      Head->pre = i;      i->next = Head;      End = i;     // i->pre = Head;      temp = i;     for(i=temp2;i!=Head;i=temp2)     {         Head->next = i;         i->pre = Head;         temp->pre = i;         temp2 = i->next;         i->next = temp;         temp = i;     }}/* 1 0 6 7 7 6 0 1*/void Print(){    std::cout<<"\n输出该链表"<<std::endl; //   std::cout<<d->data<<" ";    for(Node<type> *d =Head->next;d!=Head&&d;d=d->next)    {    //  std::cout<<"sdfs";      std::cout<<d->data<<" ";    }}void inversePrint(){    std::cout<<"\n逆序输出该链表"<<std::endl; //   std::cout<<d->data<<" ";    for(Node<type> *d =End;d!=Head&&d;d=d->pre)    {    /*  if(d->pre==NULL)        std::cout<<"d->pre==NULL"<<std::endl;      else if(d->pre==Head)        std::cout<<"d->pre==Head"<<std::endl;        粗心点1:头插法倒转list时,没改变End标识,导致后面出现BUG    */      std::cout<<d->data<<" ";    }}std::string::size_type size(){return Size;}};

由于对基础知识掌握的不太牢固,导致写这篇代码时查阅了很多资料,迭代器,友元,以及复习了一遍链表的构造和最基础的功能表,参考了STL容器模版中的各个函数使用方法,实现了比较简单的双链表