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();

}

這裏就實現了頭插,尾插,頭刪,尾刪,任意位置的插入刪除,並實現代碼的複用。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章