判断单链表是否为回文,快慢指正加栈的方式解决
首先输入这个链表的长度,然后用尾插的方式,初始化链表。接下来用快慢指针。
快指针每次走两步,慢指针每次走一步,当快指针的next为NULL时(也就是快指针走到了最后一个),那么慢指针刚好就在中间,因为链表没有环,所以将链表的情况分为奇数和偶数两种情况。当长度为奇数时,快指针第一步就走两步,慢指针第一步就走一步,当长度为偶数时,快指针第一步走一步,慢指针第一步不动。两种情况也就第一步不同,其余步数都相同。直到快指针走到末尾为止。
#include<stdio.h>
#include<malloc.h>
typedef struct _NODE
{
int data;
struct _NODE* next;
}NODE;
NODE* p;//快指针
NODE* q;//慢指针
NODE* r;//记录链表的末尾
int a[101];//用栈的形式,存放链表的后半段
int m,m3;//m表示输入的数是奇数还是偶数,m3表示数组a中存放的数字的个数
NODE* Initialization(int num, NODE* head)//链表初始化,再加上添加链表长度
{
NODE* s;
s = (NODE*)malloc(sizeof(NODE));
if (head == NULL)
{
s->data = num;
s->next = NULL;
head = s;
r = s;
return head;
}
s->data = num;
s->next = NULL;
r->next = s;
r = s;
return head;
}
NODE* PJring(NODE* p, NODE* head)//快
{
if (p->next == NULL || m == 0)
{
p = head->next;
return p;
}
if (p->next->next == NULL)
{
p = head;
return p;
}
p = p->next->next;
return p;
}
NODE* QJring(NODE* q, NODE* head)//慢
{
if (q->next == NULL || m == 0)
{
q = head;
m = -1;
return q;
}
else
{
q = q->next;
return q;
}
}
void Link(NODE* q)//将链表的后半段压入栈a中
{
q = q->next;
int i = 0;
while (1)
{
a[i] = q->data;
q = q->next;
i++;
if (q == NULL)
{
break;
}
}
}
int Compare(NODE* p,int m3)//将链表的前半段和栈a中的进行比较
{
while (m3--)
{
if (a[m3] != p->data)
{
break;
}
p = p->next;
}
return m3;
}
int main()
{
NODE* head;
int num, n;
head = NULL;
scanf("%d", &n);
m = n % 2;
m3 = n / 2;
while (n--)
{
scanf("%d", &num);
head = Initialization(num, head);
}
p = head;
q = head;
while (1)
{
p=PJring(p,head);
q=QJring(q,head);
if (p->next == NULL)
{
Link(q);
break;
}
}
p = head;
m3 = Compare(p,m3);
if (m3 == -1)
{
printf("是回文链\n");
}
else
{
printf("不是回文链\n");
}
return 0;
}