用C++实现双链表的增删查改以及双向链表的逆转

在我们实现双向链表的增删查改时一定要注意各种情况
分析各种情况我们才能更好的掌握

增删查改

以下是双向链表增删查改的代码。

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

struct ListNode
{
    ListNode* _next;
    ListNode* _prev;
    DataType _data;
    ListNode(DataType x)
        :_data(x)
        , _next(NULL)
        , _prev(NULL)
    {}
};

class List
{
    typedef ListNode Node;
public:
    List()
        :_head(NULL)
        , _tail(NULL)
    {}
    List(const List& l)//拷贝构造
        :_head(NULL)
        , _tail(NULL)
    {
        if (l._head == NULL)
        {
            _head = _tail = NULL;
        }
        else
        {
            Node* head = l._head;
            while (head)
            {
                PushBack(head->_data);
                head = head->_next;
            }
        }
    }
    //l1=l2(传统写法)
    List&operator=(const List &l)
    {
        if (this != &l)
        {
            this->Clear();
            Node*head = l._head;
            while (head)
            {
                PushBack(head->_data);
                head = head->_next;
            }
            return *this;
        }
    }
    //l1=l2(现代写法)
    List&operator=(List l)
    {
        swap(_head, l._head);
        swap(_tail, l._tail);
        return *this;

    }
    void Clear()
    {
        Node*cur = _head;
        while (cur)
        {
            Node*del = cur;
            cur = cur->_next;
            delete del;

        }
        _head = _tail = NULL;
    }
    ~List()
    {
        Clear();
    }

    //增删查改
    void PushBack(DataType x)
    {
        if (_head==NULL)
        {
            _head = _tail = new Node(x);
            return;
        }
        else
        {
            Node *tmp = new Node(x);
            _tail->_next = tmp;
            tmp->_prev = _tail;
            _tail = tmp;
        }
    }
    void PopBack()
    {
        if (_head == NULL)
        {
            return;
        }
        else if (_head == _tail)
        {
            delete _head;
            _head = _tail = NULL;
        }
        else
        {
            Node*prev = _tail->_prev;
            prev->_next=NULL;
            delete _tail;
            _tail = prev;

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

        }
        else
        {
            Node*tmp = new Node(x);
            tmp->_next = _head;
            _head->_prev = tmp;
            _head = tmp;
        }
    }


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

            prev->_next = tmp;
            tmp->_prev = prev;
        }
    }
    Node* Find(DataType x)
    {
        Node*cur = _head;
        while (cur)
        {
            if (cur->_data == x)
                return cur;
        }
        cur = cur->_next;
    }
    void Erase(Node* pos)
    {
        assert(pos);
        if (pos == _head)
        {
            PopFront();
        }
        else if (pos == _tail)
        {
            PopBack();
        }
        else
        {
            Node*prev = pos->_prev;
            Node*next = pos->_next;
            prev->_next = next;
            next->_prev = prev;
            delete pos;
        }
    }
    void Print()
    {
        Node*cur = _head;
        while (cur)
        {
            cout << cur->_data << " ";
            cur = cur->_next;
        }
        cout << endl;
    }


private:
    Node* _head;
    Node* _tail;
};

双向链表的逆转

第一种情况为交换head,tail
然后head->_next
tail->_prev
直到它们相等或者tail->_next=head
结束循环

用C++实现双链表的增删查改以及双向链表的逆转_第1张图片
代码如下

    void Reverse()
    {
        Node*head = _head;
        Node*tail = _tail;
        while (head != tail&&tail->_next != head)
        //while(! (head ==tail||tail->_next == head))
        {
            swap(head->_data, tail->_data);
            head = head->_next;
            tail = tail->_prev;

        }
    }

第二种情况如下图,我们将指针进行交换,最后在交换_head与_tail

用C++实现双链表的增删查改以及双向链表的逆转_第2张图片
代码如下

    void Reverse()
    {
        Node*cur = _head;
        while (cur)
        {
            Node*next = cur->_next;
            swap(cur->_next, cur->_prev);
            cur = next;
        }
        swap(_head, _tail);
    }

完整版代码如下:

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

struct ListNode
{
    ListNode* _next;
    ListNode* _prev;
    DataType _data;
    ListNode(DataType x)
        :_data(x)
        , _next(NULL)
        , _prev(NULL)
    {}
};

class List
{
    typedef ListNode Node;
public:
    List()
        :_head(NULL)
        , _tail(NULL)
    {}
    List(const List& l)
        :_head(NULL)
        , _tail(NULL)
    {
        if (l._head == NULL)
        {
            _head = _tail = NULL;
        }
        else
        {
            Node* head = l._head;
            while (head)
            {
                PushBack(head->_data);
                head = head->_next;
            }
        }
    }
        //l1=l2(传统写法)
    List&operator=(const List &l)
    {
        if (this != &l)
        {
            this->Clear();
            Node*head = l._head;
            while (head)
            {
                PushBack(head->_data);
                head = head->_next;
            }
            return *this;
        }
    }
    //l1=l2(现代写法)
    List&operator=(List l)
    {
        swap(_head, l._head);
        swap(_tail, l._tail);
        return *this;

    }
    void Clear()
    {
        Node*cur = _head;
        while (cur)
        {
            Node*del = cur;
            cur = cur->_next;
            delete del;

        }
        _head = _tail = NULL;
    }
    ~List()
    {
        Clear();
    }
    void PushBack(DataType x)
    {
        if (_head==NULL)
        {
            _head = _tail = new Node(x);
            return;
        }
        else
        {
            Node *tmp = new Node(x);
            _tail->_next = tmp;
            tmp->_prev = _tail;
            _tail = tmp;
        }
    }
    void PopBack()
    {
        if (_head == NULL)
        {
            return;
        }
        else if (_head == _tail)
        {
            delete _head;
            _head = _tail = NULL;
        }
        else
        {
            Node*prev = _tail->_prev;
            prev->_next=NULL;
            delete _tail;
            _tail = prev;

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

        }
        else
        {
            Node*tmp = new Node(x);
            tmp->_next = _head;
            _head->_prev = tmp;
            _head = tmp;
        }
    }


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

            prev->_next = tmp;
            tmp->_prev = prev;
        }
    }
    Node* Find(DataType x)
    {
        Node*cur = _head;
        while (cur)
        {
            if (cur->_data = x)
                return cur;
        }
        cur = cur->_next;
    }
    void Erase(Node* pos)
    {
        assert(pos);
        if (pos == _head)
        {
            PopFront();
        }
        else if (pos == _tail)
        {
            PopBack();
        }
        else
        {
            Node*prev = pos->_prev;
            Node*next = pos->_next;
            prev->_next = next;
            next->_prev = prev;
            delete pos;
        }
    }
    //逆转方法1
    void Reverse()
    {
        Node*head = _head;
        Node*tail = _tail;
        while (head != tail&&tail->_next != head)
        {
            swap(head->_data, tail->_data);
            head = head->_next;
            tail = tail->_prev;

        }
    }
    //逆转方法2
    //void Reverse()
    //{
    //  Node*cur = _head;
    //  while (cur)
    //  {
    //      Node*next = cur->_next;
    //      swap(cur->_next, cur->_prev);
    //      cur = next;
    //  }
    //  swap(_head, _tail);
    //}

    void Print()
    {
        Node*cur = _head;
        while (cur)
        {
            cout << cur->_data << " ";
            cur = cur->_next;
        }
        cout << endl;
    }

private:
    Node* _head;
    Node* _tail;
};

只写了该用的函数,测试函数以及main加在下面就好。

你可能感兴趣的:(c++)