单链表和顺序表能够处理的问题都差不多,但是链表的优点在于能够节省空间,空间的利用率更高,程序执行的效率更快,链表的基本操作也是面试官喜欢考察的问题之一,链表是一种基本的数据结构,下面主要是利用c++来实现链表的基本功能。



//单向链表
#include <assert.h>

typedef int DataType;
class SListNode
{
     friend class SList;      //定义友元,类SList中可以用类SListNode的成员
public:
     SListNode(DataType x)   //构造函数
        :Data(x)
        , Next(NULL)
     { }
     
private:
     DataType Data;     //数据域
     SListNode * Next;     //指针域
};

class SList
{
public:
     void pushBack(DataType x)     //尾插节点
     {
         if (_head == NULL)    //考虑没有节点的情况
         {
             _head = new SListNode(x);    //new会自动调用构造函数
             _tail = _head;
          }
         else
         {
             _tail->Next = new SListNode(x);
             _tail = _tail->Next;
          }
     }
      
     void popBack()   //尾删节点
     {
         if (_head == _tail)
         {
             if (_head)
             {
                 delete _head;
                 _head = _tail = NULL;
              }
         }
        else
       {
            SListNode * tmp = _tail;
            SListNode * cur = _head;
            while (cur)
            {
                 if (cur->Next->Next == NULL)
                {
                     delete tmp;
                     _tail = cur;
                     _tail->Next = NULL;
                 }
                 cur = cur->Next;
            }
         }
     }
     
     void pushFront(DataType x)    //头插节点
     {
          SListNode * tmp = new SListNode(x);
          tmp->Next = _head;
          _head = tmp;
      }
      
     void popFront()    //头删节点
    {
         SListNode * tmp = _head;
         if (tmp != NULL)    //考虑无节点的情况
         {
             _head = _head->Next;
             delete tmp;
          }
     }
     
     void Insert(SListNode * pos, DataType x)    //任意位置插入节点
     {
          assert(pos);
          if (pos == _tail)
          {
              pushBack(x);
          }
          else
         {
              SListNode * tmp = new SListNode(x);
              tmp->Next = pos->Next;
              pos->Next = tmp;
          }
     }
     
     SListNode * Find(DataType x)   //查找
     {
         SListNode * cur = _head;
         while (cur != NULL)
        {
            if (cur->Data == x)
            {
                return cur;
            }
            else
           {
                cur++;
            }
        }
        if (cur == NULL)
        {
             cout << "查找不到!" << endl;
         }
     }
     
      void Erase(SListNode * pos)    //删除pos位置上的数据
      {
          assert(pos);
          SListNode * cur = _head;
          while (cur->Next != pos)
          {
              cur = cur->Next;
          }
          cur->Next = pos->Next;
          delete pos;
      }
      
      void PrintSList()    //格式输出
     {
         SListNode *cur = _head;
         while (cur)
         {
             cout << cur->Data << " " ;
             cur = cur->Next;
          }
             cout << endl;
      }
      
      void Clear()     //释放全部节点
      {
          SListNode * cur = _head;
          while (cur)
          {
              SListNode *tmp = cur;
              cur = cur->Next;
              delete tmp;
          }
      }
public:
      SList()   //无参构造函数
         :_head(NULL)
         , _tail(NULL)
      {}
      
 //深拷贝
      SList(const SList & S)     //拷贝构造函数
         :_head(NULL)
         , _tail(NULL)
     {
         SListNode * cur = S._head;
         while (cur)
         {
             this->pushBack(cur->Data);
             cur = cur->Next;
         }
     }
     
     ~SList()    //析构函数
    {
        Clear();
     }
     
 //传统写法
     SList& operator=(const SList & s)      //赋值运算符重载
     {
         if (this != &s)    //考虑自己给自己赋值的情况
         {
             this->Clear();    //需要释放全部的节点,delete只能释放一个节点
             SListNode * cur = s._head;
             while (cur)
             {
                 this->pushBack(cur->Data);
                 cur = cur->Next;
              }
         }
      }
      
 ////现代写法
 //SList & operator=(const SList & s)
 //{
 // swap(_head, s._head);
 // swap(_tail, s._tail);
 // return *this;
 //}
 
private:
     SListNode * _head;      //指向头节点的指针
     SListNode * _tail;      //指向尾节点的指针
};