删除链表中等于给定值 val 的所有节点。
示例:
输入: 1->2->6->3->4->5->6, val = 6
输出: 1->2->3->4->5
题目来源:https://leetcode-cn.com/problems/remove-linked-list-elements/description/
cur->data == val
是否成立,不成立则prev = cur ;cur = cur->next ;
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
struct ListNode* removeElements(struct ListNode* head, int val){
struct ListNode* cur , *prev;
cur = head ;
prev = NULL;
while(cur){
//数据等于val,则删除该节点
if(cur->val == val){
struct ListNode* next = cur->next ;
if(prev == NULL){
head = next ;
}else{
prev->next = next ;
}
free(cur);
cur = next ;
}else{
prev = cur ;
cur = cur->next ;
}
}
return head ;
}
反转一个单链表。
示例:
输入: 1->2->3->4->5->NULL
输出: 5->4->3->2->1->NULL
题目来源:https://leetcode-cn.com/problems/reverse-linked-list/submissions/
方法一:
方法二:
n2->next = n1;
;n1 = n2 ; n2 = n3 ; n3 = n3->next;
;head = n1
。方法一:
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
struct ListNode* reverseList(struct ListNode* head){
struct ListNode* head2 = NULL;
//当原有节点不为空时进行循环
while(head != NULL){
//从原有节点上取出第一个节点
struct ListNode* cur = head ;
head = head->next ;
//将取出的节点头插入head2链表中
cur->next = head2;
head2 = cur ;
}
return head2 ;
}
方法二:
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
struct ListNode* reverseList(struct ListNode* head){
if(head == NULL || head->next == NULL)
return head ;
//定义三个辅助指针变量并进行初始赋值
struct ListNode* n1 , *n2 , *n3 ;
n1 = head ;
n2 = head->next ;
n3 = n2->next ;
n1->next = NULL;
//当n2不为空时进行循环
while(n2){
//将n2节点指向反转
n2->next = n1 ;
//将三个辅助指针变量向后移动
n1 = n2 ;
n2 = n3 ;
if(n3 != NULL){
n3 = n3->next ;
}
}
head = n1 ;
return head ;
}
给定一个头结点为 head 的非空单链表,返回链表的中间结点。如果有两个中间结点,则返回第二个中间结点。
示例 :
输入:[1,2,3,4,5]
输出:此列表中的结点 3 (序列化形式:[3,4,5])
返回的结点值为 3 。 (测评系统对该结点序列化表述是 [3,4,5])。
注意,我们返回了一个 ListNode 类型的对象 ans,这样:
ans.val = 3, ans.next.val = 4, ans.next.next.val = 5, 以及 ans.next.next.next = NULL.
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/middle-of-the-linked-list
方法一:
方法二:
fast = slow = head
;方法一:
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
struct ListNode* middleNode(struct ListNode* head){
if(head == NULL )
return head ;
int size = 0 ;
struct ListNode* cur = head ;
//统计链表节点数
while(cur){
size++;
cur = cur->next ;
}
//找到第len/2+1个节点
int middle = size/2+1;
cur = head ;
while(--middle){
cur = cur->next ;
}
return cur;
}
方法二:
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
struct ListNode* middleNode(struct ListNode* head){
//设置快慢指针
struct ListNode* fast , *slow ;
fast = slow = head ;
//当快指针为最后一个节点或者为空是结束循环
while(fast && fast->next){
//快指针步长为2,慢指针步长为1
fast = fast->next->next;
slow = slow->next;
}
return slow ;
}
输入一个链表,输出该链表中倒数第k个节点。
示例
输入:1,{1,2,3,4,5}
返回值:{5}
题目链接:剑指offer找到倒数第k个节点
方法一:
步骤一:遍历链表,统计链表结点的个数size;
步骤二:返回第size-k个节点的下一个节点。
方法二:
步骤一:设置快慢指针fast = slow = head
;
步骤二:先让快指针先走k步;
步骤三:快慢指针同时向后移动,当快指针为空时,慢指针指向返回结点。
方法一:
/**
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
/**
*
* @param pListHead ListNode类
* @param k int整型
* @return ListNode类
*/
struct ListNode* FindKthToTail(struct ListNode* pListHead, int k ) {
// write code here
int size = 0;
struct ListNode* cur = pListHead;
while(cur){
size++;
cur = cur->next ;
}
cur = pListHead ;
int ret = size - k ;
while(ret--&& cur){
cur = cur->next ;
}
return cur ;
}
方法二:
/**
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
/**
*
* @param pListHead ListNode类
* @param k int整型
* @return ListNode类
*/
struct ListNode* FindKthToTail(struct ListNode* pListHead, int k ) {
// write code here
//设置快慢指针`fast = slow = head`
struct ListNode* fast , *slow ;
fast = slow = pListHead ;
//先让快指针先走k步
while(k && fast){
k--;
fast = fast->next ;
}
if(k > 0)
return NULL;
//快慢指针同时向后移动,当快指针为空时,慢指针指向返回结点
while(fast){
fast = fast->next ;
slow = slow->next ;
}
return slow ;
}
将两个升序链表合并为一个新的升序链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。
示例:
输入:1->2->4, 1->3->4
输出:1->1->2->3->4->4
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/merge-two-sorted-lists
方法一:
申请一个链表,将两个链表中元素按升序赋给新链表节点的val中,销毁两个链表并返回新链表。
方法二:
步骤一:申请一个新的表头,并设置指向当前节点的指针cur = NULL
;
步骤二:设置指向两个有序链表当前节点的指针cur1、cur2;
步骤三:比较cur1->val
与cur2->val
的值,将值较小的节点插入新链表中,即if(cur) cur->next = cur1(或cur2);
步骤四:当cur1 != NULL && cur2 != NULL
时,不断重复步骤三;
步骤五:将剩余的链表元素直接插入新的链表中;
步骤六:返回新的链表。
方法一的具体实现与合并两个数组的方法类似,故这里不详细讲述。
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
struct ListNode* mergeTwoLists(struct ListNode* l1, struct ListNode* l2){
//创建新的链表
struct ListNode* newList , * cur , *cur1 , *cur2 ;
cur1 = l1 ;
cur2 = l2 ;
//创建头节点
struct ListNode* head =(struct ListNode*)malloc(sizeof(struct ListNode));
head->next = NULL;
newList = cur = head ;
//将较小者插入新链表中
while(cur1 && cur2){
struct ListNode* inst;
if(cur1->val <= cur2->val){
inst = cur1 ;
cur1 = cur1->next ;
}else{
inst = cur2 ;
cur2 = cur2->next ;
}
cur->next = inst ;
cur = inst ;
}
//将剩余元素加入新链表
if(cur1){
cur->next = cur1;
}
if(cur2){
cur->next = cur2;
}
newList = head->next;
free(head);
return newList ;
}