链表利用:分区与回文判断 [复制链接]
发表于 2025-10-12 13:41:28 | 显示全部楼层 |阅读模式
目次
链表分区(Partition)
功能概述
代码实现
要点与难点
注意事项
链表回文判断(PalindromeList)
功能概述
代码实现
要点与难点
注意事项
总结


   在链表干系的算法标题中,明确链表的根本布局和利用至关告急。本日我们深入探究两个经典的链表标题:链表分区和链表回文判断,通过具体分析代码实现,明确此中的要点、难点和注意事项。
  

作者主页:共享家9527-CSDN博客



链表分区(Partition)


功能概述


链表分区的目标是将给定链表按照某个值 x 举行分别,使得全部小于 x 的节点排在大于或便是 x 的节点之前。

代码实现


 
  1. cpp
  2. class Partition {
  3. public:
  4.     ListNode* partition(ListNode* pHead, int x) {
  5.         // 定义用于存储大于等于x节点链表的头指针和尾指针,以及小于x节点链表的头指针和尾指针,还有遍历原链表的指针
  6.         struct ListNode* greatHead, *greattail, *lessHead, *lesstail, *cur; 
  7.         // 为大于等于x节点链表的头指针和尾指针分配内存,并初始化为同一节点
  8.         greatHead = greattail = (struct ListNode*)malloc(sizeof(struct ListNode)); 
  9.         // 为小于x节点链表的头指针和尾指针分配内存,并初始化为同一节点
  10.         lessHead = lesstail = (struct ListNode*)malloc(sizeof(struct ListNode)); 
  11.         // 将遍历指针指向原链表头节点
  12.         cur = pHead;  
  13.         // 遍历原链表进行尾插
  14.         while(cur)
  15.         {
  16.             if(cur->val < x)
  17.             {
  18.                 // 将当前小于x的节点接到less链表的尾部
  19.                 lesstail->next = cur;  
  20.                 // 更新less链表的尾指针为当前节点
  21.                 lesstail = cur;   
  22.                 // 原链表中cur指针继续指向下一个节点
  23.                 cur = cur->next;  
  24.             }
  25.             else
  26.             {
  27.                 // 将当前大于等于x的节点接到great链表的尾部
  28.                 greattail->next = cur; 
  29.                 // 更新great链表的尾指针为当前节点
  30.                 greattail = cur;  
  31.                 // 原链表中cur指针继续指向下一个节点
  32.                 cur = cur->next;  
  33.             }
  34.         }
  35.         // 将less链表和great链表连接起来
  36.         lesstail->next = greatHead->next;  
  37.         // 将great链表的最后一个节点的next指针置为NULL,避免原链表的链接干扰
  38.         greattail->next = NULL;           
  39.         // 返回less链表的第一个有效节点(去掉虚拟头节点)
  40.         return lessHead->next; 
  41.     }
  42. };
复制代码
要点与难点

   
  1. 捏造头节点的使用:为简化链表利用,创建了两个捏造头节点 lessHead 和 greatHead ,分别用于存储小于 x 和大于便是 x 的节点。这制止了对链表头节点的特殊处理处罚,让代码更简便同一。
  
  2. 尾插法:通过 lesstail 和 greattail 指针,采取尾插法将原链表中的节点分别插入到两个新链表中,保持节点的相对次序。
  
  3. 链表毗连:遍历竣事后,将 lesstail 的 next 指针指向 greatHead->next ,实现两个链表的毗连。
  
  4. 末了节点处理处罚:必须将 greattail 的 next 指针设为 NULL ,否则大概会形成环或导致错误的链表布局。
  
注意事项

   
  - 内存分配:使用 malloc 分配内存时,记得在不再使用时开释内存,制止内存走漏。
  
  - 边界条件:思量链表为空或只有一个节点的环境,确保代码的鲁棒性。
  
链表回文判断(PalindromeList)


功能概述


判断给定的链表是否为回文链表,即正向和反向读取链表节点的值是雷同的。

代码实现


 
  1. cpp
  2. class PalindromeList {
  3.   public:
  4.     bool chkPalindrome(ListNode* A) {
  5.         // 定义慢指针,初始指向链表头节点
  6.         struct ListNode* slow = A; 
  7.         // 定义快指针,初始指向链表头节点
  8.         struct ListNode* fast = A; 
  9.         // 利用快慢指针找链表中间节点,快指针每次走两步,慢指针每次走一步
  10.         while (fast->next) { 
  11.             slow = slow->next;
  12.             fast = fast->next;
  13.             // 如果快指针还有下一个节点,再走一步
  14.             if (fast->next) { 
  15.                 fast = fast->next;
  16.             }
  17.         }
  18.         // 用于存储反转后半部分链表的新头指针
  19.         struct ListNode* change = NULL; 
  20.         // 从中间节点开始处理后半部分链表
  21.         struct ListNode* head = slow; 
  22.         // 反转链表的后半部分
  23.         while (head) {
  24.             // 保存当前节点的下一个节点
  25.             struct ListNode* next = head->next; 
  26.             // 将当前节点指向前一个节点,实现反转
  27.             head->next = change; 
  28.             // 更新新的头指针为当前节点
  29.             change = head; 
  30.             // 继续处理下一个节点
  31.             head = next; 
  32.         }
  33.         // 比较链表的前半部分和反转后的后半部分
  34.         while (slow) {
  35.             // 如果对应节点值不相等,返回false
  36.             if (A->val != change->val) { 
  37.                 return false;
  38.             }
  39.             // 前半部分链表指针后移
  40.             A = A->next; 
  41.             // 反转后的后半部分链表指针后移
  42.             change = change->next; 
  43.         }
  44.         // 所有对应节点值都相等,返回true
  45.         return true; 
  46.     }
  47. };
复制代码
要点与难点

   
  1. 快慢指针:使用快慢指针找到链表的中心节点。快指针每次移动两步,慢指针每次移动一步,当快指针到达链表末了时,慢指针恰恰指向中心节点。这是找到链表中心位置的高效方法。
  
  2. 链表反转:将链表的后半部分举行反转,通过改变指针方向实现。在反转过程中,必要鉴戒处理处罚指针的指向,确保链表布局不被粉碎。
  
  3. 比力判断:从链表的两头开始比力节点的值,若全部值都雷同,则链表为回文链表。
  
注意事项

   
  - 指针利用:在链表反转过程中,要注意生存当前节点的下一个节点,以免丢失链表布局。
  
  - 边界条件:思量链表长度为奇数和偶数的环境,确保代码在各种环境下都能精确判断。好比链表长度为奇数时,中心节点单独处理处罚,不到场比力;链表长度为偶数时,中心两个节点分别属于前后两部分到场比力 。
  

总结


   链表利用必要对指针有深入的明确和纯熟的运用。无论是链表分区照旧回文判断,关键在于公道使用指针来遍历、修改链表布局。在实现过程中,要注意边界条件的处理处罚、内存管理以及代码的可读性和可维护性。通过不绝练习和总结,我们可以更好地把握链表干系的算法标题,进步编程本领。

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

×
回复

使用道具 举报

登录后关闭弹窗

登录参与点评抽奖  加入IT实名职场社区
去登录
快速回复 返回顶部 返回列表