回文链表的判断

#include 

using namespace std;

struct ListNode
{
	int value;
	ListNode* next;
	ListNode(int value, ListNode* node) :value(value), next(node)
	{
	}
};

ListNode * reverList(ListNode *head)
{
	if (head == NULL || head->next == NULL)
	{
		return head;
	}
	//递找反向头并计划让每个节点准备与后面的节点反转,暂时把这个记录放入栈中,递归出的时候倒序执行反转操作
	ListNode* reverseHead = reverList(head->next);
	head->next->next = head;
	head->next = NULL;
	return reverseHead;
}

void traverseList(ListNode* head)
{
	while (head != NULL)
	{
		std::cout << head->value << "    ";
		head = head->next;
	}
	std::cout << std::endl;
}

bool isPalindromeList(ListNode * head)
{

	//思路分析,设置两个指针(一快一慢)去遍历这个链表
	//快的一次走两步,慢的一次走一步
	//当快的到了链表的终点的,即快指针遇到NULL时,
	//走不出下一步时,慢的指针正好到了原链表的正中间
	//把慢指针后面的链表反转之后与前面的链表元素一一比较
	//若相同,则是反转链表,比较的时候要依据后半部分链表反转后的链表为基准
	//因为后半部分的链表可能比前面的链表正好少一个元素
	//eg: 1 2 3 4 3 2 1 NULL 快慢指针初始都在1的位置,当快指针无法移动下一步时
	//快指针指向的是最后的1的位置,慢的在4的位置,把4后面部分反转是  1 2 3,比前半部分链表少了4
	//eg: 1 2 3 4 4 3 2 1 NULL 快慢指针初始都在1的位置,当快指针无法移动下一步时,
	//就是下一步走向空或者走不出去时,停下来走动
	//此时快指针指向的是最后的2的位置,快指针下一步会走向空,所以就就不走了,此时慢的在第一个4的位置,
	//把4后面部分反转是  1 2 3 4,与前面的一半正好相等


	//特殊情况处理
	//没有节点或者只有一个节点
	if (head == NULL || head->next == NULL) return true;

	//只有两个节点时,fast直接就到终点了,特殊处理
	if (head->next->next == NULL) return head->value == head->next->value;

	ListNode *fast = head;
	ListNode *slow = head;

	while (fast != NULL && fast->next != NULL && fast->next->next != NULL)
	{
		slow = slow->next;
		fast = fast->next->next;
	}

	//开始隔离前面和后面,然后反转后半部分
	//记录后半部分链表的头
	ListNode* secondHead = slow->next;

	//分割
	slow->next = NULL;

	//反转后半部分,secondHead指向反转后的头
	secondHead = reverList(secondHead);

	cout << "前半部分: " << endl;
	traverseList(head);

	cout << "后半部分反转后: " << endl;
	traverseList(secondHead);

	bool isPalindromeList = true;
	while (secondHead != NULL)
	{
		if (secondHead->value != head->value)
		{
			isPalindromeList = false;
			break;
		}
		secondHead = secondHead->next;
		head = head->next;
	}
	return isPalindromeList;
}

int main()
{
	ListNode* node1 = new ListNode(1, NULL);
	ListNode* node2 = new ListNode(2, NULL);
	ListNode* node3 = new ListNode(3, NULL);
	ListNode* node4 = new ListNode(4, NULL);
	ListNode* node5 = new ListNode(3, NULL);
	ListNode* node6 = new ListNode(2, NULL);
	ListNode* node7 = new ListNode(1, NULL);

	node1->next = node2;
	node2->next = node3;
	node3->next = node4;
	node4->next = node5;
	node5->next = node6;
	node6->next = node7;

	traverseList(node1);

	int k = 3;
	bool palindromeList = isPalindromeList(node1);

	cout << "result = " << palindromeList << endl;
}

回文链表的判断_第1张图片

你可能感兴趣的:(算法练习,c++)