反转链表的四种方法

反转链表的四种方法

给你单链表的头节点 head ,请你反转链表,并返回反转后的链表。

示例 1:

img

输入:head = [1,2,3,4,5]
输出:[5,4,3,2,1]

示例 2:

img

输入:head = [1,2]
输出:[2,1]

示例 3:

输入:head = []
输出:[]

1.迭代法

因为单链表只能由当前节点查找到后一个节点,因此使用迭代法时,需要保存当前节点的后一个节点。

struct Node* reverseList(struct Node* head) {
    struct Node *prev = NULL;
	struct Node *cur = head;
	struct Node *next;

    while (cur != NULL) {
    	//用next指针保存cur下一个数据的地址
        next = cur->next;
        //调转当前节点指针的方向,为上一个节点的地址
        cur->next = prev;
        //prev保存当前节点的地址
        prev = cur;
        cur = next;
    }

    return prev;
}

2.头插法

由于单链表只能单向操作,由此可以想到链表的插入操作,把每一个节点的数据用头插法一一放入一个新的链表中,就能实现链表的反转操作了。

struct Node* reverseList(struct Node* head) {
	//创建一个新的链表节点
    struct Node* newHead = NULL;
    while (head != NULL) {
    	//用nextNode保存待操作节点的下一个节点的地址
        struct Node* nextNode = head->next;
        //将当前节点用头插法插入新创建的链表当中
        head->next = newHead;
        newHead = head;
        head = nextNode;
    }
	//返回反转之后的链表
    return newHead;
}

3.原地反转法

与头插法类似,区别在于头插法通过建立一个新链表实现,原地反转法直接对原链表作出修改,借助两个指针实现。

1、初始状态,令beg指向第一个的开始节点,end指向beg->next

2、将end节点摘除,添加到新链表的头部

3、将end指向beg->next,然后将end所指节点摘除并且添加到当前头部

struct Node* reverseList(struct Node* head) {
	struct Node* beg = NULL;
	struct Node* end = NULL;
	//如果是空链或者只有一个节点,就直接返回头指针
	if(head==NULL || head->next==NULL) {
		return head;
	}else{
		beg = head;
		end = head->next;
		while(end != NULL) {
			//将end指向的节点摘出并插入到最前面
			beg->next = end->next;
			end->next = head;
			head = end;
			end = beg->next;
		}
	}
	return head;
}

4.递归法

struct Node* reverseList(struct Node* head) {
	//如果是空链或者只有一个节点,就直接返回头指针
    if (head == NULL || head->next == NULL) {
        return head;
    }
	//递归调用反转函数,此时restReversed保存最后一个节点的数据
    struct Node* restReversed = reverseList(head->next);
    //从后往前依次将节点的指向反转,并将最后一个节点里面的指针指向NULL
    head->next->next = head;
    head->next = NULL;

    return restReversed;
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值