欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

双向链表(c++封装)

程序员文章站 2022-05-06 21:41:53
...
 双向链表是链表的一种,它的每个数据结点中都有两个指针,分别指向直接后继和直接前驱。所以,从双向链表中的任意一个结点开始,都可以很方便地访问它的前驱结点和后继结点。结构图如下所示:其中_pPre是双向链表的前驱结点,_pNext是它的后继结点,_data是数据域

双向链表(c++封装)

代码实现:

#define _CRT_SECURE_NO_WARNINGS 1
#include<iostream>
#include<assert.h>
using namespace std;
typedef int DataType;
class Node
{
public:
    Node(const DataType& data) 
        : _pNext(NULL) 
        , _pPre(NULL) 
        , _data(data) 
    {} 
    Node* _pNext; 
    Node* _pPre; 
    DataType _data; 
};
class List 
{ 
public: 
      friend ostream& operator<<(ostream& _cout, const List& list)//输出运算符的重载  
    {  
        Node* pCur = list._pHead;  
        if (pCur == NULL)//空链表  
            _cout << "NULL";  
        else  
        {  
            while (pCur->_pNext)
            {  
                _cout << pCur->_data << "->";  
                pCur = pCur->_pNext;  
            }  
            _cout << pCur->_data << "->";  
            _cout << "NULL";  
        }  
        return _cout;  
    }  
    List() 
        : _pHead(NULL) 
    {} 
    List(DataType* array, size_t size) 
    { 
        for(size_t i = 0; i < size; ++i) 
        {
            PushBack(array[i]);
        }

     }  
   List& operator=(const List& list)//赋值运算符的重载  
    {  
        Node* pCur = list._pHead;  
        if (this != &list)  
        {  
            while (pCur->_pNext)  
            {  
                PushBack(pCur->_data);  
                pCur = pCur->_pNext;  
            }  
            PushBack(pCur->_data);  
        }  
        return *this;  
    }  
void PushBack(const DataType data);//尾插
void PopBack();//尾删
void PushFront(const DataType data); //头插
void PopFront();。。头删
Node* Find(const DataType data);//寻找指定元素
Node* Erase(Node* pos); //任意位置删除
Node* Insert(Node* pos, const DataType& data); //任意位置插入
size_t Size()//求节点个数
{
    size_t i=0;
    Node* pCur=_pHead;
    if(_pHead==NULL)
    {
        return 0;
    }
    else
    {
        while(pCur->_pNext)
        {
            ++i;
            pCur=pCur->_pNext;
        }
        return i+1;
    }
}

void Clear()
{
    Node* pCur=_pHead;
    if(_pHead==NULL)
    {
        return;
    }
    else
    {
        while(pCur->_pNext==NULL)
        {
            pCur->_pPre->_pNext=NULL;
            delete pCur;
        }
        _pHead=NULL;
    }
}
~List()
    {
        Node* _pCur=_pHead;
        if(_pHead==NULL&&_pHead->_pNext==NULL)
        {
            return;
        }
        while(_pHead&&_pHead->_pNext)
        {
            _pCur=_pHead;
            _pHead=_pHead->_pNext;
            delete _pCur;
        }
        delete _pHead;
    }
private: 
Node* _pHead; 
};

void List::PushBack(const DataType data) 
{ 
    Node* pTail = _pHead; 
    Node* pNewNode = new Node(data); 
    if(_pHead==NULL)
    {
        _pHead=pNewNode;
        pNewNode->_pPre=pTail;
    }
    else
    {
        while(pTail->_pNext)
        {
            pTail = pTail->_pNext; 
        }
        pTail->_pNext = pNewNode; 
        pNewNode->_pPre = pTail; 
    } 
    pNewNode->_data=data;
    pNewNode->_pNext=NULL;
} 

void List::PopBack()
{
    Node* pCur=_pHead;
    if(pCur==NULL)
    {
        return;
    }
    else
    {
        while(pCur->_pNext)
        {
            pCur=pCur->_pNext;
        }   
        pCur->_pPre->_pNext=NULL;   
        delete pCur;
    }
}
void List::PushFront(const DataType data)
{
    Node* NewNode=new Node(data);
    if(_pHead==NULL)
    {
        NewNode->_data=data;
        NewNode->_pNext=_pHead;
        NewNode->_pPre=NULL;
        _pHead=NewNode;
    }
    _pHead->_pPre=NewNode;
}
void List::PopFront()
{
    Node* pCur=_pHead;
    if(pCur==NULL)
    {
        return;
    }
    else
        _pHead=_pHead->_pNext;
        _pHead->_pPre=NULL;
        delete pCur;
}
Node* List::Find(const DataType data)
{
    Node* pCur=_pHead;
    if(pCur==NULL)
    {
        return NULL;
    }
    else if((pCur->_pNext==NULL)&&(pCur->_data==data))
    {
        return pCur;
    }
    else
    {
        while(pCur->_pNext)
        {
            if(pCur->_data==data)
                return pCur;
            pCur=pCur->_pNext;
        }
    }
    return NULL;
}

Node* List::Insert(Node* pos, const DataType& data)//任意位置删除
{
    Node* NewNode=new Node(data);
    assert(pos);
    if(pos==_pHead)
    {
        PushFront(data);
    }
    else if(pos->_pNext==NULL)
    {
        PushBack(data);
    }
    else
    {
        NewNode->_pNext=pos;
        pos->_pPre->_pNext=NewNode;
        NewNode->_pPre=pos->_pPre;
        pos->_pPre=NewNode;
        NewNode->_data=data;
    }
    return _pHead;
}

Node* List::Erase(Node* pos)
{
    if(pos==NULL)
    {
        return _pHead;
    }
    if(pos==_pHead)
    {
        PopFront();
    }
    else
    {
        pos->_pPre->_pNext=pos->_pNext;
        pos->_pNext->_pPre=pos->_pPre;
        delete pos;
    }
    return _pHead;
}
DataType array[]={1,2,3};
List list(array,sizeof(array)/sizeof(array[0]));
void Test1()//PushBack PopBack 
{
    list.PushBack(4);
    cout<<list<<endl;
    list.PopBack();
    cout<<list<<endl;
}
void Test2()//PushFront PopFront
{
    list.PushFront(0);
    cout<<list<<endl;
    list.PopFront();
    cout<<list<<endl;
}

void Test4()//Size Clear 
{
    cout<<list<<endl;
    size_t size=list.Size();
    cout<<"Size="<<size<<endl;
    list.Clear();
    cout<<list<<endl;
}
void Test5()//Insert Find
{
    Node* pos=list.Find(2);
    list.Insert(pos,5);
    cout<<list<<endl;
}

void Test6()//Erase
{
    Node* pos=list.Find(2);
    list.Erase(pos);
    cout<<list<<endl;
}
void Test7()//赋值运算符的重载
{
    List list2;
    list2=list;
    cout<<list2<<endl;
}
int main()
{
    //Test1();
    //Test2();
    //Test3();
    //Test4();
    //Test5();
    //Test6();
    Test7();
    system("pause");
    return 0;
}

相关标签: 双向链表