C++实现算法题之反转链表

题目:定义一个函数,输入一个链表的头节点,反转该链表并输出反转后链表的头节点。
示例:
输入 : 1->2->3->4->5->NULL
输出 : 5->4->3->2->1->NULL

#include <algorithm>
#include <unordered_map>
#include <iostream>
#include <vector>

using namespace std;

// 链表结构体
struct node
{
	int data;
	struct node * next;
	node(int _data):data(_data), next(nullptr){}
};

// 创建链表
struct node* init()
{
	node* head = new node(1);
	node* node1 = new node(2);
	node* node2 = new node(3);
	node* node3 = new node(4);
	node* node4 = new node(5);

	head->next = node1;
	node1->next = node2;
	node2->next = node3;
	node3->next = node4;
	node4->next = nullptr;

	return head;
}

// 方法一:
// 先对原链表做头删操作,再对新链表做头插
node* reverseList(node* head)
{
	node *newHead = NULL;
	node *curr = NULL;

	while (head != NULL)
	{
		// 对之前的链表做头删
		curr = head;       // 让curr指针指向传入函数链表的头指针head,两指针指向保持相同
		head = head->next; // 然后让head指针指向它的next结点,此时旧链表已经完成了头删操作。

		// 对新链表做头插
		curr->next = newHead; // 让curr指针的next下一个结点指向新链表的头指针newHead,完成结点的链接,即头插入新的链表中。
		newHead = curr;       // 然后更新newHead指向为新链表的头结点。
	}

	return newHead;
}

// 方法二:
node* reverselist(node* head)
{
	if (head == NULL)
		return NULL;

	node* p0 = NULL;       // 前指针   p0为NULL
	node* p1 = head;       // 当前指针 p1为1
	node* p2 = head->next; // 后指针   p2为2

	// 开始遍历链表,循环判定因子为p1,当它为空时到达链表尾部跳出循环。否则在表中执行循环内逻辑:
	while (p1 != NULL)
	{
		// 将p1指向的当前结点的下一个结点指向p0,即前一个结点。
		p1->next = p0; // 此时p0为NULL,那么p1的下一个结点就为空了,它现在是最后一个结点。

		// 然后将p0指针指向p1,将p1指针指向p2
		// 注意这两步不可以调换顺序,否则正确向后挪移一位。此时完成了三个指针的一轮更迭。
		p0 = p1;
		p1 = p2; // 此时p0为1,p1为2,p2为3
		// 判定p2指针是否为空,如果为空说明此时p2到达了链表结尾,当前指针p1的指向为最后一个结点,它的next即为空。
		if (p2 != NULL)
		{
			p2 = p2->next; // 如果不为空,将p2更新到下一个结点,进行下一次循环。
		}
		// 下一次进行循环时,就会把截断结点链接到新链表的头部,同时更新三个指针。继续循环。
		// 此时p0为2,p1为3,p2为3
	}

	// 循环终止条件为:p1指向了链表尾部的NULL,此时p1的前指针p0即指向了反转后的链表,它就是新链表的head头指针。此时返回p0即可。
	return p0;
}

int main()
{
	// 创建链表
	node* head = init();

	// 反转链表
	//head = reverseList(head);
	head = reverselist(head);

	// 打印链表
	while (head != nullptr)
	{
		cout << head->data << endl;
		head = head->next;
	}

	return 0;
}
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

程序员之光

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值