【C++实现双链表】

概要:本期主要学习双链表的结构、头插法建表、尾插法建表以及双链表的操作实现。

一、双链表长啥样?

双链表是单链表的变形,增加了一个前驱指针,指向当前节点的前一节点。如下图所示:
在这里插入图片描述

二、双链表有什么特点?

双链表相对于单链表,最主要的区别是它多了一个前驱指针域,指向前一节点的地址。因此,双链表可以访问当前节点的前一节点,时间复杂度为O(1)。

三、双链表的操作实现

0.双链表的结构以及初始化
class DoubleLinkedList
{
    
    
private:
    class Node
    {
    
    
    public:
        Node() {
    
    }
        QString data;
        Node *pre;//指向前一个节点,前驱指针
        Node *next;//指向后一个节点,后继指针
    };

    Node *head;
    int length;

public:
    DoubleLinkedList();
};
DoubleLinkedList::DoubleLinkedList()
{
    
    
    head = new Node;
    head->data = "";
    head->next = nullptr;
    head->pre = nullptr;
    length = 0;
}
1.头插法创建双链表
//头插法创建双链表(链表内节点顺序与输入顺序相反)
void DoubleLinkedList::HeadCreateDoubleLinkedList(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 == nullptr)//空链表
        {
    
    
            _newNode->next = nullptr;
            _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++;
    }
}
2.尾插法创建双链表
//尾插法创建双链表(链表内节点顺序与输入顺序一致)
void DoubleLinkedList::TailCreateDoubleLinkedList(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 = _node->next;//1.将新节点的后继指针指向当前节点的后一节点
//        _node->next->pre = _newNode;//2.将当前节点的后一节点的前驱指针指向新节点(尾插法,当前节点永远为尾结点)
        _newNode->pre = _node;//3.将新节点的前驱指针指向当前节点
        _node->next = _newNode;//4.将当前节点的后继指针指向新节点
        _node = _node->next;//当前指向节点后移
        i++;
    }
}
3.打印双链表
void DoubleLinkedList::DisplayDoubleLinkedList()
{
    
    
    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 == nullptr)
        {
    
    
            return ;
        }
        _node = _node->next;
    }
}
4.在双链表中插入节点
//在指定节点后插入节点
 void DoubleLinkedList::BackInsertNodeToDoubleLinkedList(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++;
    }
}
5.删除双链表中的节点
//删除指定节点
void DoubleLinkedList::DeleteNodeFromDoubleLinkedList(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/129304253
今日推荐