C/C++ 双链表之逆序的实例详解

C/C++ 双链表之逆序的实例详解

本文将详细讲解如何使用 C/C++ 实现双链表的逆序操作,以及具体实现代码的细节。在这篇文章中,我们将会介绍双链表的概念以及如何实现双链表的逆序操作。

双链表的概念

双链表是一种链式存储数据的结构,它类似于单向链表,但每个节点有两个指针分别指向该节点的前驱节点和后继节点。由于它的链式存储结构,双链表灵活、高效,在许多应用场景中都被广泛使用。

双链表的逆序操作

双链表的逆序操作是将双链表的存储顺序从原来的正序调整为逆序的一种操作。在实际应用中,逆序操作也被广泛使用,它可以用于实现链式结构的反转、实现栈等其他数据结构。

下面是代码示例:

struct ListNode {
    int val;
    ListNode *prev;
    ListNode *next;
    ListNode(int x) : val(x), prev(NULL), next(NULL) {}
};

ListNode* reverseList(ListNode* head) {
    ListNode* curr = head;
    ListNode* prev = NULL;
    while (curr != NULL) {
        ListNode* next = curr->next;
        curr->next = prev;
        curr->prev = next; // 注意此处的修改,将 prev 指向 next 节点
        prev = curr;
        curr = next;
    }
    return prev;
}

在上面的代码中,我们定义了一个结构体 ListNode 表示双链表节点的数据结构,它包含三个成员变量:一个 val 表示该节点存储的值,以及两个指针 prevnext 分别指向该节点的前驱节点和后继节点。

我们还实现了一个名为 reverseList 的函数,该函数用于实现双链表的逆序操作。该函数的参数为指向链表头节点的指针 head,返回值为指向逆序后的链表头节点的指针。该函数的实现过程如下:

  1. 定义两个指针 currprev,初始时分别指向链表的头节点和 NULL。
  2. 遍历链表,对于遍历到的每个节点,执行以下操作:
  3. 定义指针 next,将其指向当前节点的后继节点 next = curr->next
  4. 修改节点的指针,将当前节点的后继指针 curr->next 指向其前驱节点 prev,将当前节点的前驱指针 curr->prev 指向其后继节点 next
  5. prev 指针指向当前节点 prev = curr
  6. curr 指针指向下一个节点 curr = next
  7. 遍历结束后,返回 prev 指针即为逆序后的链表头节点。

代码示例

下面是一个完整的代码示例,包含了链表的创建、打印、插入、删除、查找和逆序等常用操作。

#include <iostream>
using namespace std;

struct ListNode {
    int val;
    ListNode *prev;
    ListNode *next;
    ListNode(int x) : val(x), prev(NULL), next(NULL) {}
};

class List {
public:
    List() {
        head = new ListNode(0);
        tail = new ListNode(0);
        head->next = tail;
        tail->prev = head;
    }

    ~List() {
        ListNode* curr = head;
        while (curr != NULL) {
            ListNode* next = curr->next;
            delete curr;
            curr = next;
        }
    }

    void print() {
        ListNode* curr = head->next;
        while (curr != tail) {
            cout << curr->val << " ";
            curr = curr->next;
        }
        cout << endl;
    }

    void insert(int val) {
        ListNode* node = new ListNode(val);
        node->prev = tail->prev;
        node->next = tail;
        tail->prev->next = node;
        tail->prev = node;
    }

    void remove(int val) {
        ListNode* curr = head->next;
        while (curr != tail) {
            if (curr->val == val) {
                curr->prev->next = curr->next;
                curr->next->prev = curr->prev;
                delete curr;
                break;
            }
            curr = curr->next;
        }
    }

    ListNode* find(int val) {
        ListNode* curr = head->next;
        while (curr != tail) {
            if (curr->val == val) {
                return curr;
            }
            curr = curr->next;
        }
        return NULL;
    }

    void reverse() {
        ListNode* curr = head->next;
        ListNode* prev = NULL;
        while (curr != tail) {
            ListNode* next = curr->next;
            curr->next = prev;
            curr->prev = next; // 注意此处的修改,将 prev 指向 next 节点
            prev = curr;
            curr = next;
        }
        head->next = prev;
        prev->prev = head;
    }

private:
    ListNode* head;
    ListNode* tail;
};

int main() {
    List list;
    list.insert(1);
    list.insert(2);
    list.insert(3);
    list.insert(4);
    list.insert(5);
    cout << "原链表:" << endl;
    list.print();
    list.remove(3);
    cout << "删除节点 3 后的链表:" << endl;
    list.print();
    ListNode* node = list.find(2);
    cout << "查找节点 2:" << endl;
    cout << node->val << endl;
    cout << "逆序后的链表:" << endl;
    list.reverse();
    list.print();
    return 0;
}

在上面的代码中,我们定义了一个名为 List 的链表类,该类封装了链表的创建、打印、插入、删除、查找和逆序等常用操作。通过该类,我们可以轻松地实现链表的基本功能。

总结

本文详细介绍了如何使用 C/C++ 实现双向链表的逆序操作,并提供了实现代码和相关示例。在实际应用中,逆序操作是实现链式结构的反转和栈等其他数据结构的关键操作之一。通过本文的学习,相信读者已经对双向链表和逆序操作有了更加深入的了解。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:C/C++ 双链表之逆序的实例详解 - Python技术站

(0)
上一篇 2023年6月27日
下一篇 2023年6月27日

相关文章

  • Win10怎么在鼠标右键菜单中添加快捷关机/重启/注销/锁屏等功能?

    可以通过修改注册表来在鼠标右键菜单中添加快捷关机/重启/注销/锁屏等功能。下面是完整攻略: 打开注册表编辑器,方法是按下Win+R组合键,输入“regedit”并按回车键。 在注册表中导航到以下路径:HKEY_CLASSES_ROOT\Directory\Background\shell 在“shell”下右键新建一个“项”,命名为“快捷关机”(或其他你想添…

    other 2023年6月27日
    00
  • QT实现贪吃蛇游戏代码详解

    QT实现贪吃蛇游戏代码详解 1. 介绍 贪吃蛇是一款经典的游戏,在QT中实现贪吃蛇游戏,可以通过练习,加深对游戏编程的理解,也可以加深对QT编程的熟练程度。 2. 程序结构 在QT中实现贪吃蛇游戏,建议采用以下的结构: – main.cpp – mainwindow.h – mainwindow.cpp – snake.h – snake.cpp 其中,ma…

    other 2023年6月26日
    00
  • 关于c/c++语言的eof(c++实现闰年判断)

    关于c/c++语言的eof(c++实现闰年判断) 在c/c++语言中,判断一个年份是否为闰年是比较常见的问题。本文将简单介绍如何使用eof在c++中进行闰年判断。 什么是闰年 闰年是指能够被4整除,但不能被100整除,或者可以被400整除的年份。例如,2000年是闰年,但1900年不是闰年。 c++实现闰年判断 在c++中,可以使用简单的if-else语句来…

    其他 2023年3月28日
    00
  • linux刷新dns

    当需要刷新Linux系统的DNS缓存时,可以使用以下步骤: 步骤1:清除本地DNS缓存 在Linux系统中,可以使用以下命令清除本地DNS缓存: sudo systemd-resolve –flush-caches 该命令清除本地DNS缓存,并强制系统重新查询DNS服务器以获取最新的DNS记录。 步骤2:修改DNS服务器 如果DNS服务器已更改,则需要修改…

    other 2023年5月6日
    00
  • newtonsoftjsonjtoken的用法

    Newtonsoft.Json JToken的用法 在使用C#开发中,未免会遇到需要解析Json数据的情况。而Newtonsoft.Json是一个强大且普及度极高的Json处理库,被广泛应用于各个领域。在Newtonsoft.Json中,JToken是处理Json数据的基本单元。JToken提供了许多实用的属性和方法,使我们能够更方便地获取、修改、删除Jso…

    其他 2023年3月28日
    00
  • 巧妙破除网页右键禁用的十大绝招

    我来给你详细讲解一下“巧妙破除网页右键禁用的十大绝招”的攻略。如下: 快速了解 右键菜单是网页常用的交互方式,有些网站为了保护自己的内容,会禁用右键菜单 这是可以被绕过的,我们可以使用以下方法来破除网页右键禁用: 禁用网页脚本 通过浏览器插件破解禁用 直接调用浏览器API 在浏览器控制台中修改DOM结构 然后再用JS重新开启右键菜单 详细解释 1. 禁用网页…

    other 2023年6月27日
    00
  • 详解Linux批量更改文件后缀名

    详解Linux批量更改文件后缀名攻略 在Linux系统中,我们可以使用rename命令来批量更改文件的后缀名。下面是一个详细的攻略,包含了两个示例说明。 步骤一:安装rename命令 首先,我们需要确保系统中已经安装了rename命令。如果没有安装,可以通过以下命令来安装: sudo apt-get install rename 步骤二:进入目标文件夹 使用…

    other 2023年8月5日
    00
  • php实现无限级分类查询(递归、非递归)

    下面是详细讲解“php实现无限级分类查询(递归、非递归)”的完整攻略。 无限级分类查询 无限级分类,是指一个数据表中的数据具有层次关系,例如商品分类、栏目分类等。无限级分类查询是指在查询这个分类数据表时,要将所有的数据归类到不同的层级中,以便于在页面上展示并且方便用户浏览。 数据库设计 在设计数据库表时,需要添加一个 parent_id 字段,来表示父级分类…

    other 2023年6月27日
    00
合作推广
合作推广
分享本页
返回顶部