C++实现单链表

单链表

相对于顺序表,多了一个next指针,用来连接数据,构成链式结构
下面是代码

#include<iostream>
#include<assert.h>
using namespace std;
typedef int DataType; 

struct SListNode 
{ 
    SListNode* _next; 
    DataType _data; 

    SListNode(DataType x) 
        :_data(x) 
        ,_next(NULL) 
    {} 
}; 

class SList 
{ 
    typedef SListNode Node; 
public: 
    SList()
        :_head(NULL)
        ,_tail(NULL)
    {}
    SList(const SList& s)
        //单链表这里使用深拷贝的方法解决深浅拷贝的问题
        :_head(NULL)
        ,_tail(NULL)
    {
        //直接用pushback来进行节点的创建,实现拷贝
        Copy(s);
    }
    //s1 = s2;
    //先把s1析构,再拷贝
    SList& operator=(const SList& s)
    {
        if(this!=&s)
        {
            Destroy();
            Copy(s);
        }
        return *this;
    }
    ~SList()
    {
        Destroy();
    }

    void PushBack(DataType x)
    {
        if(_head==NULL)
        {
            _head = _tail = new Node(x);
        }
        else
        {
            Node*tmp = new Node(x);
            _tail->_next = tmp;
            _tail = tmp;
        }
    }
    void PopBack()
    {
        if(_head==NULL)
        {
            return ;
        }
        else if(_head == _tail)//一个节点
        {
            Node*del = _head;
            delete del;
            del = NULL;
            _head = _tail = NULL;
        }
        else
        {
            Node*prev = _head;
            while(prev->_next!=_tail)
            {
                prev = prev->_next;
            }
            Node *del = _tail;
            prev->_next = del->_next;
            delete del;
            del = NULL;
            _tail = prev;

        }
    }
    void PushFront(DataType x) 
    {
        if(_head==NULL)
        {
            _head = _tail = new Node(x);
        }

        else
        {
            Insert(_head,x);
//          Node*tmp = new Node(x);
//          tmp ->_next = _head;
//          _head = tmp;
        }
    }
    void PopFront()
    {
        if(_head==NULL)
            return;
        else
        {
            Node*del = _head;
            _head = del->_next;
            delete del;
            del = NULL;
        }
    }
    // 插入一个节点在pos的前面 
    void Insert(Node* pos, DataType x)
    {
        assert(pos);
        if(pos==_head)
        {
            Node*cur = new Node(x);
            cur->_next = pos;
            _head = cur;
            //PushFront(x);
        }
        else
        {
            Node*tmp = new Node(x);
            Node*prev = _head;
            while(prev->_next!=pos)
            {
                prev = prev->_next;
            }
            tmp->_next = pos;
            prev->_next = tmp;
        }

    }
    void Erase(Node* pos)
    {
        assert(pos);
        if(pos==_head)//就直接处理掉了_head==_tail的情况
        {
            Node*del = _head;
            _head = del->_next;
            delete del;
            del = NULL;
        }
        else
            if(pos==_tail)//走到这里,肯定是有一个以上结点
            {
                Node*prev = _head;
                Node*del = _tail;
                while(prev->_next!=pos)
                {
                    prev = prev->_next;
                }
                prev->_next = del->_next;
                delete del;
                del = NULL;
                _tail = prev;
            }
//      if(pos==_head)
//      {
//          PopFront();
//      }
//      if(pos==_tail)
//      {
//          PopBack();
//      }
        else
        {
            Node*del = pos;
            Node*prev = _head;
            while(prev->_next!=pos)
            {
                prev = prev->_next;
            }
            prev->_next = del->_next;
            delete del;
            del = NULL;
        }
    }
    Node*Find(DataType x)
    {
        Node*cur = _head;
        while(cur)
        {
            if(cur->_data==x)
            {
                return cur;
            }
            cur = cur->_next;
        }
        return NULL;

    }
    void Print()
    {
        Node*cur = _head;
        while(cur)
        {
            cout<<cur->_data<<" ";
            cur = cur->_next;
        }
        cout<<endl;
    }
protected:
    void Destroy()
    {
        if(_head==NULL)
        {
            return;
        }
        else
        {
            Node*cur = _head;
            while(cur)
            {
                Node*del = cur;//这里注意要用一个临时的变量将cur保存,否则析构后就找不到他了
                cur = cur->_next;
                delete del;

            }
            _head = _tail = NULL;
        }
    }

    void Copy(const SList&s)//谁调用就拷贝谁
    {
        Node *cur = s._head;
        while(cur)
        {
            PushBack(cur->_data);
            cur = cur->_next;
        }
    }
private: 
    Node* _head; 
    Node* _tail; 
}; 

void SListTest()
{
    SList s1;
    s1.PushBack(2);
    s1.PushBack(3);
    s1.PushBack(4);
    SList s2(s1);
    SList s3;
    s3.PushBack(5);
    s3.PushBack(6);
    s3.PushBack(7);
    s3.PushBack(5);
    s3.Print();
    s2 = s3;
    s1.Print();
    s2.Print();
}
void SListTest1()
{
    SList s1;
    /*s1.PushBack(2);
    s1.PushBack(3);
    s1.PushBack(4);
    s1.PushBack(5);*/
    s1.PushFront(2);
    s1.PushFront(4);
    s1.PushFront(5);

    SListNode*ret = s1.Find(5);
    cout<<ret->_data<<endl;
    //s1.Insert(ret,0);
    s1.Erase(ret);
//  s1.PopBack();
//  s1.PopBack();
//  s1.PopBack();
//  s1.PopBack();
//  s1.PopBack();
//  s1.PopFront();
//  s1.PopFront();
//  s1.PopFront();
//  s1.PopFront();
//  s1.PopFront();
    s1.Print();

}

这里就实现了头插,尾插,头删,尾删,任意位置的插入删除,并实现代码的复用。

转载于:https://www.cnblogs.com/chan0311/p/9427333.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值