C语言实现——反转链表

     力扣题号:206. 反转链表

一、题目描述

反转一个单链表,要求不能申请额外的内存空间。

二、示例

输入:1→2→3→4→5→6→NULL

输出:6→5→4→3→2→1→NULL

三、求解思路

实现对单链表的反转,有三种方法,分别为:双指针法,递归法,头插法。其中,头插法是对当前链表中的所有元素再进行一次头插法,实现链表的反转。

四、代码实现

#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include <stdlib.h>

typedef struct Lnode {
	int data;
	struct Lnode* next;
}Lnode, * Linklist;


/*
头插法插入链表
参数说明
L -- 传入链表
x -- 结点上的数据
*/
bool headInsert(Linklist& L, int x) {

	Lnode* newnode = (Lnode*)malloc(sizeof(Lnode));
	if (newnode == NULL) {
		return false;
	}
	newnode->data = x;
	newnode->next = L;
	L = newnode;

	return true;
}

/*
双指针法反转链表
参数说明
L -- 传入链表
*/
void doublePointerReverse(Linklist &L) {
	Lnode* cur = L;
	Lnode* pre = NULL;
	
	while (cur) {
		Lnode* tmp = cur->next;
		cur->next = pre;
		pre = cur;
		cur = tmp;
	}
	L = pre;
}

/*
递归法反转链表
参数说明
L -- 传入链表
*/
Lnode* reverse(Lnode* cur, Lnode* pre) {
	if (cur == NULL) {
		return pre;
	}
	Lnode* tmp = cur->next;
	cur->next = pre;
	return reverse(tmp,cur);
}
void recursionReverse(Linklist& L) {
	L = reverse(L,NULL);
}

/*
头插法法反转链表
参数说明
L -- 传入链表
*/
void headInsertionReverse(Linklist& L) {
	Lnode* head = NULL;
	while (L)
	{
		Lnode* tmp = L->next;
		
		// 将原链表中的结点插入新的链表中
		L->next = NULL;
		if (head != NULL) {
			L->next = head;
		}
		head = L;

		// 原链表向后移动
		L = tmp;
	}
	L = head;
}

/*
打印链表
参数说明
L -- 传入链表
*/
void print(Linklist L) {

	if (L == NULL) {
		return;
	}
	while (L) {
		printf("%3d", L->data);
		L = L->next;
	}
	printf("\n");
}


int main() {

	// 创建链表
	Linklist L = NULL;
	headInsert(L, 1);
	headInsert(L, 2);
	headInsert(L, 2);
	headInsert(L, 3);
	headInsert(L, 5);
	headInsert(L, 7);
	headInsert(L, 7);

	printf("Linklist:\n");
	print(L);

	// 双指针法
	printf("双指针法: \n");
	doublePointerReverse(L);
	print(L);

	// 递归法
	printf("递归法: \n");
	recursionReverse(L);
	print(L);

	// 头插法反转
	printf("头插法反转: \n");
	headInsertionReverse(L);
	print(L);

	return 0;
}

五、运行结果

  • 9
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是C语言实现链表反转的代码: ``` #include <stdio.h> #include <stdlib.h> // 双链表节点结构体 typedef struct ListNode { int val; struct ListNode* next; struct ListNode* prev; } ListNode; // 反转双链表函数 ListNode* reverseList(ListNode* head) { ListNode* prev = NULL; ListNode* curr = head; while (curr != NULL) { ListNode* next = curr->next; curr->next = prev; curr->prev = next; prev = curr; curr = next; } return prev; } // 打印双链表函数 void printList(ListNode* head) { while (head != NULL) { printf("%d ", head->val); head = head->next; } printf("\n"); } int main() { // 创建双链表 ListNode* node1 = (ListNode*)malloc(sizeof(ListNode)); node1->val = 1; ListNode* node2 = (ListNode*)malloc(sizeof(ListNode)); node2->val = 2; ListNode* node3 = (ListNode*)malloc(sizeof(ListNode)); node3->val = 3; ListNode* node4 = (ListNode*)malloc(sizeof(ListNode)); node4->val = 4; node1->next = node2; node2->prev = node1; node2->next = node3; node3->prev = node2; node3->next = node4; node4->prev = node3; node4->next = NULL; // 打印原始双链表 printf("Original List: "); printList(node1); // 反转双链表 ListNode* newHead = reverseList(node1); // 打印反转后的双链表 printf("Reversed List: "); printList(newHead); return 0; } ``` 代码解析: 1. 定义了一个双链表节点结构体,包括节点值、下一个节点指针和上一个节点指针。 2. 定义了一个反转双链表的函数,参数为头节点指针,返回值为反转后的头节点指针。 3. 在反转双链表函数中,定义了三个指针变量,分别代表前一个节点、当前节点和下一个节点。初始时,前一个节点为NULL,当前节点为头节点。 4. 使用while循环遍历整个双链表,每次迭代时,先将当前节点的下一个节点保存到next指针中,然后将当前节点的next指针指向前一个节点,将prev指针指向next节点,更新前一个节点为当前节点,当前节点为next节点。 5. 最后返回前一个节点,即为反转后的头节点。 6. 定义了一个打印双链表的函数,参数为头节点指针,直接遍历整个链表,打印每个节点的值。 7. 在main函数中,创建了一个包含4个节点的双链表,并打印原始链表。 8. 调用反转双链表函数,得到反转后的链表头节点指针,并打印反转后的链表

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值