C/C++之双向链表&双向循环链表

  • 双向链表特点
    • 每一个节点除了数据域,还有next指针域指向下一个节点,pre指针域指向前一个节点
    • 头节点的pre是NULL,末尾节点的next是NULL
#include<iostream>
#include<stdlib.h>
#include<time.h>
using namespace std;

//单链表的实现
struct ListNode{
        ListNode (int data=0)
        :data(data)
        ,next(nullptr)
        ,pre(nullptr)
        {}
        int data;   //数据域
        ListNode *next;//指针域,指向下一个节点
        ListNode *pre;//指向前一个节点
};

class DoubleLink{
public:
        DoubleLink(){
                head = new ListNode();
        }
        ~ DoubleLink(){
                ListNode *p = head;
                while(p!=nullptr){
                        head = head->next;
                        delete p;
                        p = head;
                }
        }
public:
        void InsertHead(int val){
                ListNode *node = new ListNode(val);
                node->next = head->next;
                node->pre = head;
                if(head->next!=nullptr){
                        head->next->pre = node;
                }
                head->next = node;
        }
        void InsertTail(int val){
                ListNode *node = new ListNode(val);
                ListNode *p = head;
                while(p->next!=nullptr){
                        p = p->next;
                }
                node->pre = p;
                p->next = node;

        }
        void Remove(int val){
                ListNode *p = head->next;
                while(p->next!=nullptr){
                        if(p->data==val){
                                p->pre->next = p->next;
                                if(p->next!=nullptr){
                                        p->next->pre = p->pre;
                                }
                                //如果删除所有val
                                ListNode *pnext = p->next;
                                delete p;
                                //如果删除所有val
                                p =pnext;
                                return;
                        }
                        p = p->next;
                }

        }
        void show() const{
                ListNode *p = head->next;
                while(p!=nullptr){
                        cout<<p->data<<"   ";
                        p = p->next;
                }
        }
private:
        ListNode *head;

};


int main(){
        DoubleLink dlink;
        dlink.InsertTail(11);
        dlink.InsertTail(22);
        dlink.InsertTail(33);
        dlink.InsertTail(44);
        dlink.InsertTail(55);
        dlink.show();
        cout<<endl;
        dlink.InsertHead(99);
        dlink.show();
        cout<<endl;
        dlink.Remove(99);
        dlink.show();
        cout<<endl;
        dlink.Remove(55);
        dlink.show();
        cout<<endl;
        dlink.Remove(33);
        dlink.show();
        cout<<endl;
}
  • 双向循环链表特点
    • 每一个节点除了数据域,还有next指针域指向下一个节点,pre指针域指向前一个节点
    • 头节点的pre是尾节点,末尾节点的next是头节点
#include<iostream>
#include<stdlib.h>
#include<time.h>
using namespace std;

//单链表的实现
struct ListNode{
    ListNode (int data=0)
    :data(data)
    ,next(nullptr)
    ,pre(nullptr)
    {}
    int data;   //数据域
    ListNode *next;//指针域,指向下一个节点
    ListNode *pre;//指向前一个节点
};

class DoubleCircleLink{
public:
    DoubleCircleLink(){
        head = new ListNode();
        head->next = head;
        head->pre = head;
    }
    ~ DoubleCircleLink(){
//析构函数,最后需要将头节点也释放,防止野指针
        ListNode *p = head->next;
        while(p!=head){
            head->next = p->next;
            p->next->pre = head;
            delete p;
            p = head->next;
        }
        delete head;
        head = nullptr; 
    }
public:
    void InsertHead(int val){
        ListNode *node = new ListNode(val);
        node->next = head->next;
        node->pre = head;
        head->next->pre = node;
        head->next = node;
    }
//尾插法,头节点的前驱就是尾节点,直接在这儿中间插就行,时间复杂度O(1)
    void InsertTail(int val){
        ListNode *node = new ListNode(val);
        ListNode *p = head->pre;
        node->pre = p;
        p->next = node;
        node->next = head;
        head->pre = node;
    }
    void Remove(int val){
        ListNode *p = head->next;
        while(p!=head){
                if(p->data==val){
                        p->pre->next = p->next;
                        p->next->pre = p->pre;
                        //如果删除所有val
                        //ListNode *pnext = p->next;
                        delete p;
                        //如果删除所有val
                        //p = pnext;
                        return;
                }
                p = p->next;
        }

    }
    void show() const{
        ListNode *p = head->next;
        while(p!=head){
                cout<<p->data<<"   ";
                p = p->next;
        }
    }
private:
    ListNode *head;
    ListNode *tail;
};

int main(){
    DoubleCircleLink dclink;
    dclink.InsertTail(11);
    dclink.InsertTail(22);
    dclink.InsertTail(33);
    dclink.InsertTail(44);
    dclink.InsertTail(55);
    dclink.show();
    cout<<endl;
    dclink.InsertHead(99);
    dclink.show();
    cout<<endl;
    dclink.Remove(99);
    dclink.show();
    cout<<endl;
    dclink.Remove(55);
    dclink.show();
    cout<<endl;
    dclink.Remove(33);
    dclink.show();
    cout<<endl;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值