zoukankan      html  css  js  c++  java
  • 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();
    
    }

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

  • 相关阅读:
    db.Exec和db.Query的区别
    golang两种get请求获取携带参数的方式
    gin实现中间件middleware
    gin操作session
    笔札-有触动的句子
    并发的基本概念
    售货员的难题
    传球游戏之最小总代价
    状压dp入门
    [COCI 2010] OGRADA
  • 原文地址:https://www.cnblogs.com/chan0311/p/9427333.html
Copyright © 2011-2022 走看看