struct ListNode* deleteNode(struct ListNode* head, int val){
if(head->val == val) {
return head->next;
}
struct ListNode* pre = head;
// 没找到待删除的节点,继续遍历查找
while ((pre->next != NULL) && (pre->next->val != val)) {
pre = pre->next;
}
// 找到
if(pre->next != NULL) {
pre->next = pre->next->next;
}
return head;
}
给定单向链表的头指针和一个要删除的节点的值,定义一个函数删除该节点。
返回删除后的链表的头节点。
这个是题解,其实简单,但是有一点我不理解就是说while(cur)与whille(cur->next)的区别,遍历的次数的区别嘛
while(cur)是判断当前节点是不是为null
whille(cur->next)判断下一个节点是不是null
如果循环的时候同时需要前后两个节点,那么用后者
因为删除当前节点的时候要当前节点的前一个节点指向后一个节点,这样才能删除节点,所以要有记录前一个节点的指针,如果只用一个指针,那就提前判断下一个节点的值,这样就能将其直接指向->next->next,以此删除目标节点
不知道你这个问题是否已经解决, 如果还没有解决的话:解决方案:
1.1 定义一个结构体Node来表示链表中的节点,包含value和next两个成员变量:
typedef struct Node {
int value;
struct Node* next;
} Node;
1.2 定义一个函数deleteNode来实现删除节点的功能,该函数有两个参数,一个是链表的头节点head,另一个是给定的要删除的值val:
Node* deleteNode(Node* head, int val) {
// 先特判头节点需要删除的情况
while (head && head->value == val) {
Node* temp = head;
head = head->next;
free(temp);
}
// 处理头节点之后的节点
Node* cur = head;
while (cur && cur->next) {
if (cur->next->value == val) {
Node* temp = cur->next;
cur->next = temp->next;
free(temp);
}
else {
cur = cur->next;
}
}
return head;
}
1.3 在删除过程中需要注意处理头节点需要删除的情况,因为头节点没有prev指针,需要对head进行特判。
在遍历链表时,使用while(cur)和while(cur->next)的区别在于前者可以遍历到最后一个节点,而后者只能遍历到倒数第二个节点。因为当cur->next为NULL时,while(cur->next)中的条件不满足,循环结束,而while(cur)中的条件仍然为真,因此可以遍历到最后一个节点。
遍历链表时使用while(cur)是比while(cur->next)更常用的方式,因为很多情况下需要遍历到链表的最后一个节点,而使用后者需要在循环外添加一次对最后一个节点的特判处理。使用while(cur)的遍历次数和链表的长度相同,而使用while(cur->next)的遍历次数比链表的长度少1。