目录
前言:
大家经过前面的学习,已经对链表有了初步的了解,那么,我为大家准备了几道题目,大家一起来练习巩固一下吧!
一、反转单链表
给你单链表的头节点
head
,请你反转链表,并返回反转后的链表。
先来一道简单题来练练手,题目的要求为反转链表,相信会有部分同学会说,像数组一样,从后往前遍历不就行了,对此我只能说,很抱歉,这个是单链表,不是双链表(以后做题无说明均为单链表),那既然是单链表,我们又该如何破局呢?大家可自行思考一下方法。
本题提供的方法为三指针法(方法不唯一,以下题均如此),即运用三指针进行求解。以下为思路:
代码如下:
typedef struct ListNode ListNode;
struct ListNode* reverseList(struct ListNode* head) {
if(head == NULL)
{
return head;
}
ListNode* p1,*p2,*p3;
p1 = NULL,p2 = head,p3 = p2->next;
while(p2)
{
p2->next = p1;
p1 = p2;
p2 = p3;
if(p3)
p3 = p3->next;
}
return p1;
}
题目链接:. - 力扣(LeetCode)
大家可自行前去练习。
二、链表的中间结点
给你单链表的头结点
head
,请你找出并返回链表的中间结点。如果有两个中间结点,则返回第二个中间结点。
本题方法为:双指针法。
具体实现思路为:使用快慢指针,一个比另外一个快一步即可。以下是一个例子帮助大家理解:很直观的例子就是五十步笑百步:假设路一共100米,慢逃兵走一步,快逃兵走两步,那么当快逃兵走到终点时,慢逃兵刚好就停在中间,然后开始五十步笑百步。
代码实现如下:
typedef struct ListNode ListNode;
struct ListNode* middleNode(struct ListNode* head) {
ListNode* fast = head;
ListNode* slow = head;
while(fast && fast->next)
{
slow = slow->next;
fast = fast->next->next;
}
return slow;
}
题目链接:. - 力扣(LeetCode)
三、合并两个有序链表
将两个升序链表合并为一个新的 升序 链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。
此题要求为对其合并并排序,相信有人会有这样想法:先插入在排序,其实这个方法说可以也可以,就是有点麻烦,因为这是链表不是数组,修改链表的指向,是比较麻烦的一件事。所以,我们采取以下的方法:创建一个新链表,并设立哨兵位。然后逐渐插入,把这两个链表元素值最小的进行插入,这样即可满足题目要求。
代码实现:
typedef struct ListNode ListNode;
struct ListNode* mergeTwoLists(struct ListNode* list1, struct ListNode* list2) {
//如果List1和list2中有一个为空就直接返回另一个链表
if(list1 == NULL)
{
return list2;
}
if(list2 == NULL)
{
return list1;
}
//定义l1,l2指针分别指向list1和list2的头节点
ListNode* l1, *l2;
ListNode* newhead, *newtail;
//给新链表的开辟一个哨兵位
newhead = newtail = (ListNode*)malloc(sizeof(ListNode));
l1 =