C++实现双链表

双向链表

主要实现了头插,头删,尾插尾删,任意位置的插入删除,链表的逆置以及链表的深浅拷贝

在这里说明一下,链表用的最多的就是数据的插入什么的,所以这里解决深浅拷贝问题,用的是深拷贝,单链表,顺序表也是一样,都是用了深拷贝。
双向链表相比较于单链表而言,相对复杂一点,有两个指针,来进行实现链式结构
先面试具体代码

#include<iostream>
#include<assert.h>
using namespace std;
typedef int DataType;
struct ListNode 
{ 
    ListNode* _next; 
    ListNode* _prev; 
    DataType _data;
    ListNode(DataType x)
        :_next(NULL)
        ,_prev(NULL)
        ,_data(x)
    {}
}; 

class List 
{ 
    typedef ListNode Node; 
public: 
    List()
        :_head(NULL)
        ,_tail(NULL)
    {}
    List(const List& l)
        :_head(NULL)
        ,_tail(NULL)
    {
        //pushback
        Copy(l);
    }
    List& operator=(const List& l)
    {
        if(this!=&l)
        {
            Clear();
            Copy(l);
        }
        return *this;
    }
    ~List()
    {
        Clear();
    }

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

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

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

        }
    }
    void Erase(Node* pos)
    {
        assert(pos);
        if(pos==_head)
        {
            Node*del = _head;
            Node*next = _head->_next;
            delete del;
            del = NULL;
            _head = next;

        }
        else
            if(pos==_tail)
            {
                Node*del = _tail;
                Node*prev = _tail->_prev;
                prev->_next = del->_next;
                delete del;
                del = NULL;
                _tail = prev;
            }
            else
            {
                Node*prev = pos->_prev;
                Node*next = pos->_next;
                Node*del = pos;
                prev->_next = next;
                next->_prev = prev;
                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 Reverse()
    {
        if(_head==NULL)
            return;
        else if(_head==_tail)
            return;
        else
        {
            Node*left = _head;
            Node*right = _tail;
            while((left->_next!= right->_prev)&&(left->_prev != right))
            {
                swap(left->_data,right->_data);
                left = left->_next;
                right = right->_prev;
            }
        }
    }
    void Print()
    {
        Node*cur = _head;
        while(cur)
        {
            cout<<cur->_data<<" ";
            cur = cur->_next;
        }
        cout<<endl;

    }
    void Clear()
    {
        Node*cur = _head;
        while(cur)
        {
            Node*del = cur;
            cur = cur->_next;
            delete del;
            del = NULL;
        }
        _head = _tail = NULL;
    }
    void Copy(const List&l)
    {
        Node*cur = l._head;
        while(cur)
        {
            PushBack(cur->_data);
            cur = cur->_next;
        }
    }
private: 
    Node* _head; 
    Node* _tail; 
}; 

void ListTest()
{
    List l1;
    l1.PushBack(2);
    l1.PushBack(3);
    l1.PushBack(4);
    l1.PushBack(5);
    /*l1.PopBack();
    l1.PopBack();
    l1.PopBack();
    l1.PopBack();
    l1.PopBack();*/
    //l1.PushFront(5);
    //ListNode*ret = l1.Find(5);
    //l1.Erase(ret);
    //l1.PopBack();
    l1.Print();

}
void ListTest1()
{
    List l1;
    l1.PushBack(2);
    l1.PushBack(3);
    l1.PushBack(4);
    l1.PushBack(5);
    l1.Reverse();
    /*l1.PopFront();
    l1.PopFront();
    l1.PopFront();
    l1.PopFront();
    l1.PopFront();*/

    l1.Print();

}
void ListTest2()
{
    List l1;
    l1.PushBack(2);
    l1.PushBack(3);
    l1.PushBack(4);
    l1.PushBack(5);
    List l2(l1);
    List l3;
    l3 = l1;
    l1.Print();
    l2.Print();
    l3.Print();
}

转载于:https://www.cnblogs.com/chan0311/p/9427332.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值