首先先介绍链表中心对称是什么?就是链表第一个与倒数第一个元素相同,第二个元素与倒数第二个元素相等......,(可以想象成一条由数值构成的线段对折后能重合)。例如,xyx,xyyx都是中心对称,但xyyz就不是中心对称。
算法思路:
- 让链表的前一半元素入栈;
- 处理后面的一半元素时,访问第一个元素(后一半链表的第一个元素),栈就弹出一个元素,与其比较,若相等,则将链表的下一个元素与栈中再弹出的元素比较,直到链表的末尾。
- 若栈是空栈(即全部匹配上了),就可以得出链表中心对称
- 当链表中的某一个元素与栈中弹出的元素不相等,即链表不是中心对称。
图解:
比如咱们要比较abcdcba是否是中心对称,先将链表的一半元素入栈即(7 / 2 = 3)a、b、c入栈,因为d是对称中心,故需要将链表指针要从d处后移至d的后驱。
1、先将链表的前一半元素入栈
2、d为对称中心,p要向后移一个
3、栈Pop出一个元素,与链表后一半的第一个元素对比(即此时p指向的结点)
4、p向后移,直到p指向链表的末尾
算法实现:
链表的存储结构
typedef char ElemType;
typedef struct Lnode{
ElemType data;
strcut Lnode *next;
}LinkList;
int SymList(LinkList *L, int n)
{
// L为带头结点的n个元素的单链表
int i;
char str[n/2] // 存储链表前一半的栈
p = L->next;
for (i = 0; i < n / 2; i++) // 链表前一半入栈
{
s[i] = p->data;
p = p->next;
}
i--; //在for循环最后多加了1,需要减去
if (n % 2 == 1) // 判断是否有对称中心
p = p->next;
while (p != NULL && s[i] == p->data) // 判断是否中心对称
{
i--; // i是栈的栈顶指针
p = p->next;
}
if (i == -1) // 由于最后一次比较完后(此时i=0),i还要自减,故i=-1栈空
return 1; // 链表中心对称
else
return 0; // 链表不中心对称