题一:移除链表元素
我们可以看出这道题是让我们删除特定数据,我们可以用双指针来解这道题:
如果首元素为val,那么cur和head一起后移:
如果没有碰到val,那么就会cur后移,并且提前将cur传给perv:
如若不是在首位碰到了val ,那么perv的下一个节点将会被覆值为cur的下一个节点,然后cur
将被继续赋值为perv的下一个节点,再返回原来的head头地址!!!
如图:
代码:
struct ListNode* removeElements(struct ListNode* head, int val) {
struct ListNode* cut = head, * pevr = NULL;
while (cut)
{
if (cut->val == val)
{
if (cut == head)
{
head = cut->next;
cut = head;
}
else
{
pevr->next = cut->next;
cut =pevr->next;
}
}
else
{
pevr = cut;
cut = cut->next;
}
}
return head;
}
题目二:
中间节点
我们有一个处理链表的重要思路:快慢指针,我们可以先定义快指针的速度是慢指针的两倍,然后我们在设置一个结尾的条件即可
图示思路:
这时候返回slow即可
当节点的数目为偶数的时候
如图所示:
当快指针指向NULL时,结束循环!!!
此时会指向中间第二节点,题目得解
代码:
struct ListNode* reverseList(struct ListNode* head){
struct ListNode* p = head;
struct ListNode* q = NULL;
while(p)
{
struct ListNode* temp = p->next;
p->next = q;
q = p;
p = temp;
}
return q;
}
题目三:反转链表
这道题乐言使用的是三指针,直接断链再连上
我们首先定义一个结构体指针p指向head,再定义一个结构体指针指向空,链表的节点不变,我们进入循环while(),括号里放p的值,然后再定义一个结构体指针tmp指向p的下一个节点,这样我们可以得到我们想得到的循环次数
进入循环,我们让p的下一个节点指向q(也就是刚刚定义的空指针)
再将p的值赋值为q,再将p转移回原来的下一个节点,也就是tmp
这样操作的话,我们逐句带入的话,q的值会从NULL到1->NULL到2->1->NULL............然后最后实现链表的反置!!!
代码如下:
struct ListNode* reverseList(struct ListNode* head){
struct ListNode* p = head;
struct ListNode* q = NULL;
while(p)
{
struct ListNode* temp = p->next;
p->next = q;
q = p;
p = temp;
}
return q;
}
题目四:合并两个有序链表
我们首先先初始化一个指针p,再初始化一个指向空指针的指针pp,然后进入循环,比较链表的首节点的元素大小进行比较,哪个小就指向哪个,然后再进行比较,循环往复
代码如下:
struct ListNode* mergeTwoLists(struct ListNode* list1, struct ListNode* list2)
{
struct ListNode *p = NULL, **pp = &p;
while (list1 && list2)
{
if (list1->val < list2->val)
{
*pp = list1;
list1 = list1->next;
}
else
{
*pp = list2;
list2 = list2->next;
}
pp = &(*pp)->next;
}
*pp = list1 ? list1 : list2;
return p;
}
希望此篇可以帮助到大家