单链表反转的几种方法

单链表的构建

链表是一种在物理上非连续、非顺序的数据结构,由若干节点(node)组成。

本文讨论的是不带头节点的单链表。

#include <iostream>
#include <queue>

using namespace std;

struct ListNode {
	int val;
	struct ListNode *next;
	ListNode() = default;
	ListNode(int x) :
			val(x), next(NULL) {
	}
};

ListNode* creatList(deque<int>& nodeList) {
	if (!nodeList.size()) return nullptr;
	ListNode* p = new ListNode();
	ListNode* head = p;	
	while (nodeList.size()) {
		int val = nodeList.front();
		nodeList.pop_front();
		p -> val = val;
		if (nodeList.size()) {
			p -> next = new ListNode();
			p = p -> next;
		}
	}
	return head;
}

int main(int argc, char *argv[]) {
	deque<int> nodeList{67,0,24,58};
	ListNode* head = creatList(nodeList);
	return 0;
}

递归法

递归的本质就是“递”和“归”,具体来讲可以分为三个步骤:1. 找出等价关系 2. 找到递归停止条件 3. 理清递归函数每次的功能(计算什么内容)

递归法反转链表的递归步骤:

  1. 等价关系:当前结点的指针反转需要在其下一个结点指针反转的前提下进行(否则会产生内存泄漏)。
  2. 停止条件:当“递”到链表的最后一个结点时停止,表示链表已查找到最后。
  3. 每次的功能:调整相邻结点间指针的指向。
//递归法
    ListNode* reverList(ListNode* head) {
        if (!head || !head -> next) {
            return head;
        }
        ListNode* p = reverList(head -> next);
        head -> next -> next = head;
        head -> next = NULL;
        return p;
    }

头插法

头插法对于带头结点的单链表较为方便,其本质是将每一个结点都插入头结点的后方,形成一个与给定顺序呈倒序的链表

ListNode* reverList(ListNode* head) {
	if (!head) return nullptr;
	ListNode* p = new ListNode(-1);
	ListNode* res = p;
	ListNode* tempNode = head;
	ListNode* originList = head -> next;
	while (originList) {
		tempNode -> next = p -> next;
		p -> next = tempNode;
		tempNode = originList;
		originList = originList -> next;
		
	}
	tempNode -> next = p -> next;
	p -> next = tempNode;
	res = p -> next;
	delete p;
	return res;
}

三指针方法

三指针的方法即取三个指向前缀、当前、后缀结点的指针,逐步调整即可

ListNode* reverList(ListNode* head) {
	if (!head) return nullptr;
	ListNode* pre = nullptr;
	ListNode* cur = head;
	ListNode* temp = cur;
	while (cur) {
		temp = temp -> next;
		cur -> next = pre;
		pre = cur;
		cur = temp;
	}
	return pre;
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值