重排链表(c++实现)

这道题同时也是leetcode上的重排链表题

题目要求如下:

给定一个单链表L: A0→A1→…→An-1→An, 将它重排为: A0→An→A1→An-1→A2→An-2→…。要求原地(in-place)操作且不改变结点中的内容。例如:给定1→2→3→4,重排为1→4→2→3。

代码实现思路:

利用快慢指针求解,可以设定两个指针,一个快指针,一个慢指针,快指针一次走两个节点,慢指针一次走一个节点,当快指针指向的下一个节点为空(一共有奇数个节点),或者快指针的下下一个节点为空(一共有偶数个节点),停止遍历。将两段链表分开,并将后半段链表倒转,然后依次插入到第一段链表中,完成题目。

代码实现:

#include"pch.h"
#include<cstdlib>
#include<cstdio>
using namespace std;

struct Node {
	int n;
	Node* next;
	Node()
	{
		n = 0;
		next = NULL;
	}
};
Node* makeLinkedList()//手动制作链表
{
	Node* a = new Node;
	a->n = 1;
	Node* b = new Node;
	b->n = 2;
	Node* c = new Node;
	c->n = 3;
	Node* d = new Node;
	d->n = 4;
	a->next = b;
	b->next = c;
	c->next = d;
	return a;
}
void printLinkedList(Node* a)//打印链表
{
	Node* first = a;
	while (first != NULL)
	{
		printf_s("%d", first->n);
		if (first->next != NULL)
			printf_s("->");
		else
			printf_s("\n");
		first = first->next;
	}
}
Node* reorderList(Node* head)//重排链表 
{
	if (!head || !head->next) return NULL;
	Node *slow = head, *fast = head, *p = head, *q = head;//声明快慢指针和两个备用指针

	//分割原链表
	while (fast->next && fast->next->next)
		slow = slow->next, fast = fast->next->next;
	fast = slow->next;
	slow->next = NULL;
	p = fast;
	q = fast->next;
	fast->next = NULL;
	
	//反转第二段链表,反转结束后p代表后半段链表的首节点,q代表前半段链表的首节点
	while (q)
	{
		auto tem = q->next;
		q->next = p;
		p = q, q = tem;
	}
	q = head;

	//将后半段链表依次插入前半段链表
	while (q && p)
	{
		auto tem1 = q->next, tem2 = p->next;
		p->next = q->next;
		q->next = p;
		q = tem1, p = tem2;
	}

	//返会原来的首节点
	return head;
}
int main()
{
	Node* input = makeLinkedList();
	printLinkedList(input);	
	Node* result = reorderList(input);
	printLinkedList(result);
}

实现结果:

猜你喜欢

转载自blog.csdn.net/weixin_41106545/article/details/83239603