C++——实现双向循环链表(带头结点)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/Paranoid_cc/article/details/80945960

双向链表也叫双链表,是链表的一种,它的每个数据结点中都有两个指针,分别指向直接后继和直接前驱。所以,从双向链表中的任意一个结点开始,都可以很方便地访问它的前驱结点和后继结点。一般我们都构造双向循环链表。
简单的画一个双向循环简易图:

下面就用C++实现一下基本操作
当然也有 C 语言 版的,只是单链表操作
https://blog.csdn.net/Paranoid_cc/article/details/79707761

先分开写吧
1、四个重要的函数:构造函数、拷贝构造函数、赋值运算符重载、析构函数。

//构造函数
    List(size_t n,const DataType& data)
    {
        _CreateHead();
        for (size_t i = 0; i < n; ++i)
            PushBack(data);
    }

    List(DataType* first, DataType* last)
    {
        _CreateHead();
        while (first != last)
            PushBack(*first++);
    }

//拷贝构造函数
    List(const List& L)
    {
        _pHead = new Node();
        _pHead->_pNext = _pHead;
        _pHead->_pPre = _pHead;

        Node* pCur = L._pHead->_pNext;
        while (pCur != L._pHead)
        {
            this->PushBack(pCur->_data);
            pCur = pCur->_pNext;
        }
    }

//赋值运算符重载
    List& operator=(const List& s)
    {
        if (this != &s)
        {
            this->Clear();
            Node* pCur = s._pHead->_pNext;
            while (pCur != s._pHead)
            {
                this->PushBack(pCur->_data);
                pCur = pCur->_pNext;
            }
        }
        return *this;
    }

//析构函数
    ~List()
    {
        Clear();
        delete _pHead;
        _pHead = NULL;
    }

2、对链表的数据的操作(删除和插入)

//尾插
    void PushBack(const DataType& data)
    {
        Node* pNewNode = new Node(data);
        pNewNode->_pPre = _pHead->_pPre;
        pNewNode->_pNext = _pHead;
        _pHead->_pPre = pNewNode;
        pNewNode->_pPre->_pNext = pNewNode;
    }

//尾删
    void PopBack()
    {
        if (Empty())
            return;
        Node* pDelNode = _pHead->_pPre;
        pDelNode->_pPre->_pNext = _pHead;
        _pHead->_pPre = pDelNode->_pPre;

        delete pDelNode;
    }

    //头插
    void PushFront(const DataType& data)
    {
        Node* pNewNode = new Node(data);
        pNewNode->_pNext = _pHead->_pNext;
        pNewNode->_pPre = _pHead;
        _pHead->_pNext = pNewNode;
        pNewNode->_pNext->_pPre = pNewNode;
    }

    //头删
    void PopFront()
    {
        if (Empty())
            return;
        Node* pDelNode = _pHead->_pNext;
        _pHead->_pNext = pDelNode->_pNext;
        pDelNode->_pNext->_pPre = _pHead;
        delete pDelNode;
    }

    //任意位置插入
    Node* Insert(Node* pos, const DataType& data)
    {
        Node* pNewNode = new Node(data);
        pNewNode->_pNext = pos;
        pNewNode->_pPre = pos->_pPre;
        pNewNode->_pPre->_pNext = pNewNode;
        pos->_pPre = pNewNode;

        return pNewNode;
    }

    //任意位置删除
    Node* Erase(Node* pos)
    {
        if (NULL == pos || pos == _pHead)
            return NULL;

        Node* ret = pos->_pNext;
        pos->_pPre->_pNext = pos->_pNext;
        pos->_pNext->_pPre = pos->_pPre;

        delete pos;
        return ret;
    }

3、对链表空间的操作

//链表的大小
size_t Size()const
    {
        Node* pCur = _pHead->_pNext;
        size_t count = 0;
        while (pCur != _pHead)
        {
            count++;
            pCur = pCur->_pNext;
        }
        return count;
    }

    //判空
    bool Empty()const
    {
        return _pHead->_pNext == _pHead;
    }

    //改变链表的大小
    void ReSize(size_t newSize, const DataType& data = DataType())
    {
        int gap = newSize - Size();
        if (gap > 0)//链表元素增多了 
        {
            while (gap--)
                PushBack(data);//尾插
        }
        else
        {
            while (gap++)//链表元素减少了
                PopBack();
        }
    }

下面给出完成的操作代码以及测试代码和结果图

#define _CRT_SECURE_NO_WARNINGS
#define NULL 0
#include<iostream>
#include<string.h>
#include<assert.h>
using namespace std;

//双向循环链表(带头结点)
typedef int DataType;
struct Node
{
    Node* _pNext;
    Node* _pPre;
    DataType _data; 

    //构造函数
    Node(const DataType& data = DataType())
        :_pNext(NULL)
        , _pPre(NULL)
        , _data(data)
    {}
};

class List
{
publicList()
    {
        _CreateHead();
    }

    //构造函数
    List(size_t n,const DataType& data)
    {
        _CreateHead();
        for (size_t i = 0; i < n; ++i)
            PushBack(data);
    }

    List(DataType* first, DataType* last)
    {
        _CreateHead();
        while (first != last)
            PushBack(*first++);
    }

    //拷贝构造函数
    List(const List& L)
    {
        _pHead = new Node();
        _pHead->_pNext = _pHead;
        _pHead->_pPre = _pHead;

        Node* pCur = L._pHead->_pNext;
        while (pCur != L._pHead)
        {
            this->PushBack(pCur->_data);
            pCur = pCur->_pNext;
        }
    }

    //赋值运算符重载
    List& operator=(const List& s)
    {
        if (this != &s)
        {
            this->Clear();
            Node* pCur = s._pHead->_pNext;
            while (pCur != s._pHead)
            {
                this->PushBack(pCur->_data);
                pCur = pCur->_pNext;
            }
        }
        return *this;
    }

    //析构函数
    ~List()
    {
        Clear();
        delete _pHead;
        _pHead = NULL;
    }

    //尾插
    void PushBack(const DataType& data)
    {
        Node* pNewNode = new Node(data);
        pNewNode->_pPre = _pHead->_pPre;
        pNewNode->_pNext = _pHead;
        _pHead->_pPre = pNewNode;
        pNewNode->_pPre->_pNext = pNewNode;
    }

    //尾删
    void PopBack()
    {
        if (Empty())
            return;
        Node* pDelNode = _pHead->_pPre;
        pDelNode->_pPre->_pNext = _pHead;
        _pHead->_pPre = pDelNode->_pPre;

        delete pDelNode;
    }

    /*
    void PushBack(const DataType& data)//尾插
    {
        Node* pNewNode = new Node(data);
        if (NULL == _pHead)
        {
            _pHead = pNewNode;
            _pHead->_pNext = _pHead;
            _pHead->_pPre = _pHead;
        }
        else
        {
            Node* pTail = _pHead->_pPre;
            pTail->_pNext = pNewNode;
            pNewNode->_pPre = pTail;
            pNewNode->_pNext = _pHead;
            _pHead->_pPre = pNewNode;
        }
    }

    void PopBack()//尾删
    {
        if (NULL == _pHead)//链表为空
            return;
        else if (_pHead->_pNext == _pHead)//只有一个结点
        {
            delete _pHead;
            _pHead = NULL;
        }
        else//有多个结点
        {
            Node* pPreTail = _pHead->_pPre->_pPre;
            delete pPreTail;
            pPreTail->_pNext = _pHead;
            _pHead->_pPre = pPreTail;
        }
    }
    */

     //头插
    void PushFront(const DataType& data)
    {
        Node* pNewNode = new Node(data);
        pNewNode->_pNext = _pHead->_pNext;
        pNewNode->_pPre = _pHead;
        _pHead->_pNext = pNewNode;
        pNewNode->_pNext->_pPre = pNewNode;
    }

    //头删
    void PopFront()
    {
        if (Empty())
            return;
        Node* pDelNode = _pHead->_pNext;
        _pHead->_pNext = pDelNode->_pNext;
        pDelNode->_pNext->_pPre = _pHead;
        delete pDelNode;
    }

    //任意位置插入
    Node* Insert(Node* pos, const DataType& data)
    {
        Node* pNewNode = new Node(data);
        pNewNode->_pNext = pos;
        pNewNode->_pPre = pos->_pPre;
        pNewNode->_pPre->_pNext = pNewNode;
        pos->_pPre = pNewNode;

        return pNewNode;
    }

    //任意位置删除
    Node* Erase(Node* pos)
    {
        if (NULL == pos || pos == _pHead)
            return NULL;

        Node* ret = pos->_pNext;
        pos->_pPre->_pNext = pos->_pNext;
        pos->_pNext->_pPre = pos->_pPre;

        delete pos;
        return ret;
    }

    size_t Size()const
    {
        Node* pCur = _pHead->_pNext;
        size_t count = 0;
        while (pCur != _pHead)
        {
            count++;
            pCur = pCur->_pNext;
        }
        return count;
    }

    bool Empty()const
    {
        return _pHead->_pNext == _pHead;
    }

    void ReSize(size_t newSize, const DataType& data = DataType())
    {
        int gap = newSize - Size();
        if (gap > 0)//链表元素增多了 
        {
            while (gap--)
                PushBack(data);//尾插
        }
        else
        {
            while (gap++)//链表元素减少了
                PopBack();
        }
    }

    //取出链表第一个元素的数据
    DataType& Front()
    {
        assert(!Empty());
        return  _pHead->_pNext->_data;
    }
    const DataType& Front()const
    {
        assert(!Empty());
        return  _pHead->_pNext->_data;
    }

    DataType& Back()
    {
        assert(!Empty());
        return _pHead->_pPre->_data;
    }
    const DataType& Back() const
    {
        assert(!Empty());
        return _pHead->_pPre->_data;
    }

    void Clear()
    {
        Node* pCur = _pHead->_pNext;
        while (pCur != _pHead)
        {
            pCur = Erase(pCur);
        }
    }

private:
    void _CreateHead()
    {
        _pHead = new Node;
        _pHead->_pNext = _pHead;
        _pHead->_pPre = _pHead;
    }

    //打印函数
    friend ostream& operator<<(ostream& _cout, const List& l)
    {
        Node* pCur = l._pHead->_pNext;
        while (pCur != l._pHead)
        {
            _cout << pCur->_data << " ";
            pCur = pCur->_pNext;
        }
        return _cout;
    }

private:
    Node* _pHead;
};

void TestList()
{
    List l1;
    List l2(10,5);
    cout << l2 << endl;

    int array[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
    List l3(array, array + sizeof(array) / sizeof(DataType));
    cout << l3.Size() << endl;
    cout << l3 << endl;
    cout << l3.Front() << endl;
    cout << l3.Back() << endl;

    l3.ReSize(5);
    cout << l3.Size() << endl;
    cout << l3 << endl;
    cout << l3.Front() << endl;
    cout << l3.Back() << endl;

    l3.ReSize(15,6);
    cout << l3.Size() << endl;
    cout << l3 << endl;
    cout << l3.Front() << endl;
    cout << l3.Back() << endl;
}

int main()
{
    TestList();
    return 0;
}

结果图

后面会发出C++实现的动态顺序表的操作

猜你喜欢

转载自blog.csdn.net/Paranoid_cc/article/details/80945960
今日推荐