一、删除链表中等于给定值 val 的所有结点
二、反转一个单链表
方法一:掰指针,用到3个指针
方法二:头插
struct ListNode* reverseList(struct ListNode* head) {
struct ListNode* rhead = NULL;
struct ListNode* cur = head;
while(cur)
{
struct ListNode* next = cur->next;
//头插
cur->next = rhead;
rhead = cur;
//迭代
cur = next;
}
return rhead;
}
三、链表的中间节点
方法:快慢指针
struct ListNode* middleNode(struct ListNode* head) {
struct ListNode* slow = head;
struct ListNode* fast = head;
while(fast && fast->next)
{
slow = slow->next;
fast = fast->next->next;
}
return slow;
}
四、倒数第k个节点
方法:快慢指针 fast先走k步或者k-1步
int kthToLast(struct ListNode* head, int k){
struct ListNode* slow = head;
struct ListNode* fast = head;
while(k--)
{
if(fast == NULL)
return NULL;
fast = fast->next;
}
while(fast)
{
slow = slow->next;
fast = fast->next;
}
return slow->val;
}
五、合并两个有序链表
方法:取小的尾插
这里使用带哨兵位的头节点会省去很多麻烦
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的头节点
struct ListNode* l1, *l2;
struct ListNode* newhead, *newtail;
//给新链表的开辟一个哨兵位
newhead = newtail = (struct ListNode*)malloc(sizeof(struct ListNode));
l1 = list1,l2 = list2;
while(l1 && l2)
{
if(l1->val <= l2->val)
{
newtail->next = l1;
newtail = newtail->next;
l1 = l1->next;
}
else
{
newtail->next = l2;
newtail = newtail->next;
l2 = l2->next;
}
}
if(l1)
{
newtail->next = l1;
}
if(l2)
{
newtail->next = l2;
}
//新链表的第一个节点是头节点为无效数据,因此返回头节点的next
return newhead->next;
}