判断单链表是否为回文,快慢指针和栈

判断单链表是否为回文,快慢指正加栈的方式解决
首先输入这个链表的长度,然后用尾插的方式,初始化链表。接下来用快慢指针。
快指针每次走两步,慢指针每次走一步,当快指针的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;
}

猜你喜欢

转载自blog.csdn.net/weixin_44545549/article/details/106845722