【C++实现循环双链表】

概要:本期学习循环双链表的结构、基本操作的实现。

一、什么是循环双链表?

循环双链表是基于双链表的基础上,增加了尾结点的后继指针指向头结点,头结点的前驱指针指向尾结点的区别。
具体结构如下图所示:
在这里插入图片描述

二、循环双链表的操作实现

0.循环双链表的结构和初始化

class CyclicDoubleLinkedList
{
    
    
private:
    class Node{
    
    
    public:
        QString data;
        Node *next;
        Node *pre;
    };
    Node *head;
    int length;
public:
    CyclicDoubleLinkedList();
};
CyclicDoubleLinkedList::CyclicDoubleLinkedList()
{
    
    
    head = new Node;
    head->next = head;//指向自身
    head->pre = head;//指向自身
    head->data = "";
    length = 0;
}

1.创建循环双链表

头插法
void CyclicDoubleLinkedList::HeadCreateCyclicDoubleLinkedList(int n)
{
    
    
    Node *_node = new Node;
    _node = head;
    length = n;
    int i = 0;
    while(i < n)
    {
    
    
        qDebug()<<QStringLiteral("请输入第")<<i<<QStringLiteral("个节点的值:")<<endl;
        Node *_newNode = new Node;
        string str;
        cin>>str;
        _newNode->data = QString::fromStdString(str);
        if(_node->next == head)//空链表
        {
    
    
            _newNode->next = head;
            _node->next = _newNode;
            _newNode->pre = _node;
        }
        else
        {
    
    
            _newNode->next = _node->next;//1.将新节点的后继指针指向当前节点的后一节点
            _node->next->pre = _newNode;//2.将当前节点的后一节点的前驱指针指向新节点
            _newNode->pre = _node;//3.将新节点的前驱指针指向当前节点
            _node->next = _newNode;//4.将当前节点的后继指针指向新节点
        }
        i++;
    }
}
尾插法
void CyclicDoubleLinkedList::TailCreateCyclicDoubleLinkedList(int n)
{
    
    
    Node *_node = new Node;
    _node = head;
    length = n;
    int i = 0;
    while(i < n)
    {
    
    
        qDebug()<<QStringLiteral("请输入第")<<i<<QStringLiteral("个节点的值:")<<endl;
        Node *_newNode = new Node;
        string str;
        cin>>str;
        _newNode->data = QString::fromStdString(str);
        _newNode->next = head;//1.将新节点的后继指针指向头结点
        head->pre = _newNode;//2.将头节点的前驱指针指向新节点(尾插法,当前节点永远为尾结点)
        _newNode->pre = _node;//3.将新节点的前驱指针指向当前节点
        _node->next = _newNode;//4.将当前节点的后继指针指向新节点
        _node = _node->next;//当前指向节点后移
        i++;
    }
}

2.打印循环双链表

void CyclicDoubleLinkedList::DisplayCyclicDoubleLinkedList()
{
    
    
    if(length == 0)
    {
    
    
        qDebug()<<QStringLiteral("链表为空!")<<endl;
        return ;
    }
    Node *_node = head->next;//节点1
    int i = 0;
    while(_node)
    {
    
    
        qDebug()<<QStringLiteral("第")<<i++<<QStringLiteral("个节点的数据:")<<_node->data<<endl;
        if(_node->next == head)
        {
    
    
            return ;
        }
        _node = _node->next;
    }
}

3.在循环双链表中增加节点

void CyclicDoubleLinkedList::BackInsertNodeToCyclicDoubleLinkedList(int index, QString data)
{
    
    
    if(index < 0 || index >=length)
    {
    
    
        qDebug()<<QStringLiteral("输入位置有误!")<<endl;
        return ;
    }
    Node *_node = new Node;
    if(length == 0)
    {
    
    
        _node = head;
    }
    else
    {
    
    
        _node = head->next;
    }
    int i = 0;
    while(_node)
    {
    
    
        if(i == index -1)
        {
    
    
            Node *_newNode = new Node;
            _newNode->data = data;//赋值
            _newNode->next = _node->next;//1.将新节点的后继指针指向当前节点的后一节点
            _node->next->pre = _newNode;//2.将当前节点的后一节点的前驱指针指向新节点
            _newNode->pre = _node;//3.将新节点的前驱指针指向当前节点
            _node->next = _newNode;//4.将当前节点的后继指针指向新节点
            length ++;
            qDebug()<<QStringLiteral("节点插入成功!")<<endl;
            return;
        }
        if(_node->next == nullptr)
        {
    
    
            qDebug()<<QStringLiteral("节点插入失败!")<<endl;
            return ;
        }
        _node = _node->next;
        i++;
    }
}
4.删除双链表中指定节点
void CyclicDoubleLinkedList::DeleteNodeFromCyclicDoubleLinkedList(int index)
{
    
    
    if(index < 0 || index >=length)
    {
    
    
        qDebug()<<QStringLiteral("输入位置有误!")<<endl;
        return ;
    }
    Node *_node = new Node;
    if(length == 0)
    {
    
    
        qDebug()<<QStringLiteral("链表为空,无法进行删除操作!")<<endl;
        return ;
    }
    else
    {
    
    
        _node = head->next;
    }
    int i = 0;
    while(_node)
    {
    
    
        if(i == index-1)
        {
    
    
            Node *_delNode = _node->next;
            _node->next = _delNode->next;
            _delNode->next = _node;
            delete _delNode;
            _delNode = NULL;
            qDebug()<<QStringLiteral("节点删除成功!")<<endl;
            length --;
            return ;
        }
        if(_node->next == nullptr)
        {
    
    
            qDebug()<<QStringLiteral("节点删除失败!")<<endl;
            return ;
        }
        _node = _node->next;
        i++;
    }
}

结尾

本期对于循环双链表的学习就到这,下期我们学习栈的相关知识。

猜你喜欢

转载自blog.csdn.net/wddkxg/article/details/129315595