当前位置: 首页 > news >正文

深入解析双向链表与反转算法

一、双向链表核心概念

单向链表:只能从头往后走,不能回头。双向链表:每个节点有前驱指针 + 后继指针

  • 可以从头往后、从尾往前双向遍历
  • 任意节点删除、查找更方便
  • 结构稍微复杂一点,但实用性更强

节点结构:数据域 + 前驱 prev 指针 + 后继 next 指针

二、双向链表节点定义

struct DListNode { int val; DListNode* prev; DListNode* next; DListNode(int x) : val(x), prev(nullptr), next(nullptr) {} };

三、双向链表基础操作实现

1. 尾插法创建双向链表

DListNode* createDList() { DListNode* dummy = new DListNode(0); DListNode* cur = dummy; cur->next = new DListNode(10); cur->next->prev = cur; cur = cur->next; cur->next = new DListNode(20); cur->next->prev = cur; cur = cur->next; cur->next = new DListNode(30); cur->next->prev = cur; return dummy->next; }

2. 正向、反向遍历

// 正向遍历 void printForward(DListNode* head) { DListNode* cur = head; while(cur) { cout << cur->val << " "; cur = cur->next; } cout << endl; } // 反向遍历 void printBackward(DListNode* tail) { DListNode* cur = tail; while(cur) { cout << cur->val << " "; cur = cur->prev; } cout << endl; }

3. 头部插入节点

DListNode* addHead(DListNode* head, int val) { DListNode* newNode = new DListNode(val); newNode->next = head; if(head) head->prev = newNode; return newNode; }

4. 删除指定节点

双向链表删除不用从头遍历定位前一个节点,直接自删:

void delNode(DListNode* node) { DListNode* p = node->prev; DListNode* n = node->next; p->next = n; if(n) n->prev = p; delete node; }

四、算法重点:单链表反转(必考万能模板)

迭代版(笔试首选、无递归栈溢出风险)

ListNode* reverseList(ListNode* head) { ListNode* pre = nullptr; ListNode* cur = head; ListNode* next = nullptr; while(cur != nullptr) { // 保存下一个 next = cur->next; // 反转指向 cur->next = pre; // 双指针后移 pre = cur; cur = next; } return pre; }

必背口诀:存下一个 → 改指向 → 双指针同步后移

递归版(面试常问思路)

ListNode* reverseListRecur(ListNode* head) { if(head == nullptr || head->next == nullptr) return head; ListNode* newHead = reverseListRecur(head->next); head->next->next = head; head->next = nullptr; return newHead; }

五、完整可运行测试代码

#include <iostream> using namespace std; // 双向链表节点 struct DListNode { int val; DListNode* prev; DListNode* next; DListNode(int x) : val(x), prev(nullptr), next(nullptr) {} }; // 单向链表节点(用于反转) struct ListNode { int val; ListNode* next; ListNode(int x) : val(x), next(nullptr) {} }; // 省略上面写的所有函数,直接main测试 int main() { // 双向链表测试 DListNode* dHead = createDList(); cout << "双向链表正向:"; printForward(dHead); // 单链表反转测试 ListNode* n1 = new ListNode(1); ListNode* n2 = new ListNode(2); ListNode* n3 = new ListNode(3); n1->next = n2; n2->next = n3; ListNode* res = reverseList(n1); cout << "链表反转后:"; while(res) { cout << res->val << " "; res = res->next; } return 0; }

六、今日笔试面试考点

  1. 双向链表可双向遍历,删除节点效率比单链表高
  2. 双向链表操作务必维护prev 和 next两个指针,防止断链
  3. 链表反转迭代版优先背诵,工作刷题都用它
  4. 递归反转理解思路即可,大数据量容易栈溢出
  5. 链表反转是笔试原题高频考点,必须默写熟练

七、今日总结

  1. 双向链表:多一个前驱指针,支持双向遍历
  2. 优势:删除、反向遍历更方便
  3. 链表反转掌握迭代万能模板,直接套所有题
  4. 链表反转是后续回文链表、k 个一组反转的基础
http://www.jsqmd.com/news/771162/

相关文章:

  • 深圳新闻软文发布平台怎么选?2026年最靠谱的专业平台推荐 - 代码非世界
  • 3步快速上手Playnite:免费游戏库管理器终极配置指南
  • SSMA型弯式母头射频连接器
  • AI智能体网络自动化实战:44个MCP技能赋能数据抓取与反爬
  • 大型起重机工程机械安全监控管理系统信息采集方案
  • 2026年遵义交通标志杆、标志牌与红绿灯杆采购指南:卓越交通本地源头厂家一站式解决方案 - 企业名录优选推荐
  • Arm Cortex-R82性能监控单元(PMU)架构与实战指南
  • 特斯拉Model 3/Y CAN总线DBC文件深度解析与实战指南
  • AI 后台 MCP 调用链静默中断治理:从超时盲区到分层探活的可观测性实践
  • SPSS和Python做因子分析,到底哪个更适合你?一份超详细的双工具对比实操指南
  • GPT-5.4 Pro 技术论文深度解读:从语言模型到数字员工的范式革命
  • 广州财税合规哪家好?2026年TOP5专业机构深度评测与选购指南 - 讯息观点
  • 选择谷歌SEO公司常见误区 - 速递信息
  • 体验Taotoken多模型聚合调用的低延迟与高稳定性表现
  • 特斯拉Model 3 CAN总线DBC文件终极指南:3步快速掌握车辆数据解码
  • 3分钟快速搞定Blender到Unity的FBX转换:终极完整指南
  • Docker镜像深度剖析:从逆向分析到安全实践
  • TotalDMIS2026用户可以自行修改单个测量点的位置
  • 有养肤修护型防晒霜吗?妆前养肤超奈斯的5款口碑防晒 - 全网最美
  • 原代人肝细胞长期培养模型研究:全人源三培养体系(TCS)对PHHs功能维持的影响
  • 2026年遵义交通标志牌、标志杆采购指南|卓越交通一站式工程配套方案 - 企业名录优选推荐
  • 如何快速掌握Mi-Create:小米手表表盘设计的终极免费工具指南
  • 2026年郑州铝单板、氟碳铝单板、木纹铝单板全国采购指南:方舟建材官方对接渠道与竞品深度横评 - 精选优质企业推荐官
  • 基于LandTrendr算法的GEE绘制森林最大干扰变化监测
  • 如何用netdisk-fast-download终极解决网盘下载限速问题
  • 为Hermes Agent实现主动消息推送:非侵入式AI智能体扩展实践
  • PowerDMIS方槽位置度
  • 如何3步零基础掌握缠论分析:通达信ChanlunX插件终极指南
  • 星巴克礼品卡如何快速回收,最快多久完成 - 淘淘收小程序
  • 2026年太原精准获客与GEO优化完全指南:手机号定向推广如何助力本地企业破局高成本获客 - 优质企业观察收录