【数据结构与算法 经典例题】链表的回文结构(图文详解)

【数据结构与算法 经典例题】链表的回文结构(图文详解)回文结构 Palindromics 是指一个序列或字符串从前往后读和从后往前读是相同的

大家好,欢迎来到IT知识分享网。

            💓 博客主页:倔强的石头的CSDN主页 

             📝Gitee主页:倔强的石头的gitee主页

   ⏩ 文章专栏:《数据结构与算法 经典例题》C语言

                                  期待您的关注

1b7335aca73b41609b7f05d1d366f476.gif

 

目录

一、问题描述

二、解题思路

三、C语言代码实现


一、问题描述

【数据结构与算法 经典例题】链表的回文结构(图文详解)

二、解题思路

回文结构(Palindromic structure)是指一个序列或字符串从前往后读和从后往前读是相同的。

对于数组来说,直接采取上述方法便可以判断是否是回文结构。但对于单链表来说,则是行不通的,因为单链表只能顺序访问,不能随机访问。

判断单链表是否是回文结构的关键是对单链表中元素逐个比较的方法

第二步:
将链表中间结点及以后的节点反转(相当于链表的后半段构成了反转的新的链表)

第三步:
两个指针,分别指向原链表的第一个节点和新链表的第一个节点
将两个指针指向的节点的数据进行比对(这相当于从原链表的两端开始比对)
如果节点的数据不同,返回false
如果节点数据相同,继续比对下一个,直到任一指针指向空,退出循环,返回true



 前两步需要单独封装两个函数,分别是求链表的中间节点和反转链表

具体实现可以参考这两篇文章,本文不再详细阐述

 【数据结构与算法 刷题系列】求链表的中间结点-CSDN博客

【数据结构与算法刷题系列】(C语言)反转链表-CSDN博客

节点比较和移动的时候,对于奇数个节点的链表和偶数个节点的链表处理方式和效果是相同的,如图

奇数个节点的链表处理过程

1.初始链表

【数据结构与算法 经典例题】链表的回文结构(图文详解)

2.求得链表中间节点

【数据结构与算法 经典例题】链表的回文结构(图文详解)

3.将中间节点及之后的节点反转

需要注意:

虽然链表后半部分的结构被反转,next指针被改变

但中间节点的前一个节点的next指针未被改变,依然指向初始的中间节点

【数据结构与算法 经典例题】链表的回文结构(图文详解)
4.比较过程

两个指针对比指向节点的值,若相等,各走一步

【数据结构与算法 经典例题】链表的回文结构(图文详解)

【数据结构与算法 经典例题】链表的回文结构(图文详解)

【数据结构与算法 经典例题】链表的回文结构(图文详解)

【数据结构与算法 经典例题】链表的回文结构(图文详解)两个指针同时走向了NULL,说明链表为回文结构 

偶数个节点的链表处理过程

1.初始链表

【数据结构与算法 经典例题】链表的回文结构(图文详解)

2.求得链表中间节点

【数据结构与算法 经典例题】链表的回文结构(图文详解)

3.将中间节点及之后的节点反转

【数据结构与算法 经典例题】链表的回文结构(图文详解)

4.比较过程

两个指针对比指向节点的值,若相等,各走一步

【数据结构与算法 经典例题】链表的回文结构(图文详解)

【数据结构与算法 经典例题】链表的回文结构(图文详解)

【数据结构与算法 经典例题】链表的回文结构(图文详解)

有一个指针先走向了NULL,说明链表是回文结构

由此也说明,通过比较元素判断回文结构时,有一个指针走向了NULL,就已经完成了判断,应当退出循环

三、C语言代码实现

//链表的回文结构 //对于一个链表,请设计一个时间复杂度为O(n),额外空间复杂度为O(1)的算法,判断其是否为回文结构。 //给定一个链表的头指针A,请返回一个bool值,代表其是否为回文结构。 struct ListNode { int val; struct ListNode* next; }; struct ListNode* middleNode(struct ListNode* head) { //求链表的中间节点 struct ListNode* slow, * fast; //创建快慢指针 slow = fast = head; //初始化 while (fast && fast->next) { //当快指针可以移动两步时执行循环 slow = slow->next; //慢指针走一步 fast = fast->next->next; //快指针走两步 } return slow;//遍历完成时,slow所指节点就是中间节点 } struct ListNode* reverseList(struct ListNode* head) { if (head == NULL) return head;//对空链表做特殊处理 else { struct ListNode* n1, * n2, * n3; n1 = NULL; n2 = head; n3 = n2->next; while (n2) { //当n2指向空时,链表节点已经遍历完成,next指针修改完成 n2->next = n1; n1 = n2; n2 = n3; if (n3)//对n3判空,防止对空指针解引用 n3 = n3->next; } return n1;//当循环结束时,n1是原链表的尾节点,反转后的首节点 } } bool chkPalindrome(struct ListNode* A) { struct ListNode* mid = middleNode(A); //求出中间节点 struct ListNode* rmid = reverseList(mid);//后半部反转后的中间节点 while (rmid && A)//节点逐个对比 { if (rmid->val != A->val) return false; rmid = rmid->next; A = A->next; } return true;; }

免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://haidsoft.com/130242.html

(0)
上一篇 2025-08-18 16:45
下一篇 2025-08-18 17:00

相关推荐

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注微信