链表的定义以及实现

**

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

**。

这里写图片描述


/*
数据结构: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 3



void 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 = 9
A.Head->pre = 14

A.End->next = Head
A.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容器模版中的各个函数使用方法,实现了比较简单的双链表

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值