【线性表(一)】:链表之双向循环链表

四、双向循环链表的实现

template <class T>
class CycDulList{
public:
    CycDulList():head_(nullptr),size_(0){}
    ~CycDulList();

    //获取链表大小
    size_t size(){return size_;}
    //判断链表是否为空
    bool empty(){ return size_==0;}
    //获取头节点
    ListNode<T> *get_head(){return head_;}
    //获取任意位置节点
    ListNode<T> *get_node(const int &index);
    //根据节点获取该节点的下标
    int get_index(const T &value);

    //双向链表插入元素
    void push_back(const T &value);//在尾部插入元素
    void push_front(const T &value);//在头部插入元素
    void insert(const int &index,const T &value);//在任意位置插入元素

    //双向链表删除元素
    T pop_front();//删除首元素
    T pop_back();//删除尾元素
    T erase(const int &index);//删除任意位置元素

    //双向链表修改元素
    void set(const int &index,const T &value);

    //双向链表查询元素
    T front();//获取首元素
    T back();//获取尾元素
    T get(const int &index);//获取任意位置元素

    //打印链表
    void print();
private:
    ListNode<T> *head_;
    size_t size_;
};

template <class T>
CycDulList<T>::~CycDulList()
{
    if(head_!= nullptr){
        head_->front->next= nullptr;
        while(head_!= nullptr){
            ListNode<T> *temp=head_;
            head_=head_->next;
            delete temp;
            temp= nullptr;
        }
        size_=0;
    }
}

template <class T>
ListNode<T>* CycDulList<T>::get_node(const int &index)
{
    if(index < 0 || index >=size_){
        cout<<"index out of range,index < 0 or index > size_"<<endl;
        exit(0);
    }

    int i=0;
    ListNode<T> *cur=head_;
    while(i<index){
        cur=cur->next;
        ++i;
    }

    return cur;
}

template <class T>
int CycDulList<T>::get_index(const T &value)
{
    for(int i=0;i<size_;++i){
        if(get(i)==value){
            return i;
        }
    }

    return -1;
}

template <class T>
void CycDulList<T>::push_back(const T &value)
{
    ListNode<T> *node=new ListNode<T>(value);
    if(size_==0){
        push_front(value);
    }else{
        node->front=head_->front;
        node->next=head_;
        head_->front->next=node;
        head_->front=node;
    }
    ++size_;
}

template <class T>
void CycDulList<T>::push_front(const T &value)
{
    ListNode<T> *node=new ListNode<T>(value);
    if(size_==0){
        head_=node;
        head_->next=head_;
        head_->front=head_;
    }else{
        node->next=head_;
        node->front=head_->front;
        head_->front->next=node;
        head_->front=node;
        head_=node;
    }
    ++size_;
}

template <class T>
void CycDulList<T>::insert(const int &index, const T &value)
{
    if(index < 0 || index >size_){
        cout<<"index out of range,index < 0 or index > size_"<<endl;
        exit(0);
    }

    if(index == 0){
        push_front(value);
    }else if(index==size_){
        push_back(value);
    }else{
        int key=0;
        ListNode<T> *p=head_;
        while(key<index){
            p=p->next;
            ++key;
        }

        ListNode<T> *node=new ListNode<T>(value);
        node->next=p;
        node->front=p->front;
        p->front->next=node;
        p->front=node;

        ++size_;
    }
}

template <class T>
T CycDulList<T>::pop_front()
{
    if(size_==0){
        return -1;
    }else if(size_==1){
        T value=head_->value_;

        delete head_;
        head_= nullptr;
        --size_;
        return value;
    }else{
        T value=head_->value_;

        ListNode<T> *p=head_;
        head_=head_->next;

        head_->front=p->front;
        p->front->next=head_;

        delete p;
        p= nullptr;
        --size_;
        return value;
    }
}

template <class T>
T CycDulList<T>::pop_back()
{
    if(size_==0){
        return -1;
    }else if(size_==1){
        return pop_front();
    } else{
        T value=head_->front->value_;
        ListNode<T> *p=head_->front;

        head_->front=p->front;
        p->front->next=head_;

        delete p;
        p= nullptr;
        --size_;
        return value;
    }
}

template <class T>
T CycDulList<T>::erase(const int &index)
{
    if(index < 0 || index >= size_){
        cout<<"index out of range,index < 0 or index >= size_"<<endl;
        exit(0);
    }

    if(index==0){
        return pop_front();
    }else if (index==size_-1){
        return pop_back();
    }else{
        int key=0;
        ListNode<T> *p=head_;
        while(key < index){
            p=p->next;
            ++key;
        }

        p->front->next=p->next;
        p->next->front=p->front;
        T value=p->value_;
        delete p;
        p= nullptr;
        --size_;

        return value;
    }
}

template <class T>
void CycDulList<T>::set(const int &index, const T &value)
{
    if(index < 0 || index >= size_){
        cout<<"index out of range,index < 0 or index >= size_"<<endl;
        exit(0);
    }
    int key=0;
    ListNode<T> *p=head_;
    while(key < index){
        p=p->next;
        ++key;
    }
    p->value_=value;
}

template <class T>
T CycDulList<T>::front()
{
    if(head_== nullptr){
        return NULL;
    }else{
        return head_->value_;
    }
}

template <class T>
T CycDulList<T>::back()
{
    if(head_== nullptr){
        return NULL;
    }else{
        return head_->front->value_;
    }
}

template <class T>
T CycDulList<T>::get(const int &index)
{
    if(index < 0 || index >= size_){
        cout<<"index out of range,index < 0 or index >= size_"<<endl;
        exit(0);
    }

    if(index==0){
        return front();
    } else if(index ==size_-1){
        return back();
    }else{
        int key=0;
        ListNode<T> *p=head_;
        while(key < index){
            p=p->next;
            ++key;
        }

        return p->value_;
    }
}

template <class T>
void CycDulList<T>::print()
{
    for(int i=0;i<size_;++i){
        cout<<get(i)<<" ";
    }
    cout<<endl;
}

参考链接:

带头节点的双向循环链表的基本操作

数据结构-双向链表&双向循环链表

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值