Blue_Zx 2024-12-13 18:51 采纳率: 68.2%
浏览 6
已结题

删除链表中的指定元素,为什么加上这一段代码(判断所要删除的节点是不是在尾部)后就无法正常运行啊

力扣题,删除链表中的指定元素,为什么加上这一段代码(判断所要删除的节点是不是在尾部)后就无法正常运行啊?
题目如下:

img


成功运行的代码:

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */
struct ListNode* removeElements(struct ListNode* head, int val) {
    struct ListNode*p,*p0,*q;
    p=p0=head;
    while(p!=NULL)
    {
        if(p->val==val)
        {
           
            if(p==head)
            {
                q=head;
                head=head->next;
                p=p0=head;
                free(q);
            }
            else 
            {
                q=p;
            p0->next=p->next;
            p=p0;
            free(q);
            }
        }
        else
        {
            p0=p;
        p=p->next;
        }
        

    }
    return head;
}



加入注释部分的代码后就无法正常运行

img

  • 写回答

1条回答 默认 最新

  • 道友老李 JWE233286一种基于机器视觉的水表指针读数识别及修正的方法 专利发明者 2024-12-13 19:05
    关注
    让道友老李来帮你解答,本回答参考通义千问qwen-plus编写提供,如果还有疑问可以评论或留言
    好的,我来帮助你分析和解决这个问题。首先,我们来看一下题目要求:删除链表中所有值为 `val` 的节点。

    成功运行的代码

    /**
     * Definition for singly-linked list.
     * struct ListNode {
     *     int val;
     *     struct ListNode *next;
     * };
     */
    
    struct ListNode* removeElements(struct ListNode* head, int val) {
        struct ListNode* p, *p0, *q;
        p = p0 = head;
    
        while (p != NULL) {
            if (p->val == val) {
                if (p == head) {
                    q = head;
                    head = head->next;
                    p = p0 = head;
                    free(q);
                } else {
                    q = p;
                    p0->next = p->next;
                    p = p0;
                    free(q);
                }
            } else {
                p0 = p;
                p = p->next;
            }
        }
        return head;
    }
    

    加入判断尾部节点的代码

    假设你加入了以下代码来判断所要删除的节点是否在尾部:

    if (p->next == NULL) {
        // 处理尾部节点
    }
    

    问题分析

    1. 指针移动问题:在删除节点时,如果当前节点是尾部节点,那么 p0->next 应该被设置为 NULL,但你的代码可能没有正确处理这一点。
    2. 内存释放问题:在删除尾部节点时,需要确保释放内存并正确更新指针。

    修改后的代码

    为了确保代码能够正确处理尾部节点,我们可以对代码进行以下修改:

    /**
     * Definition for singly-linked list.
     * struct ListNode {
     *     int val;
     *     struct ListNode *next;
     * };
     */
    
    struct ListNode* removeElements(struct ListNode* head, int val) {
        struct ListNode* dummy = (struct ListNode*)malloc(sizeof(struct ListNode));
        dummy->next = head;
        struct ListNode* p0 = dummy;
        struct ListNode* p = head;
    
        while (p != NULL) {
            if (p->val == val) {
                if (p->next == NULL) {  // 判断是否为尾部节点
                    p0->next = NULL;
                    free(p);
                    break;
                } else {
                    struct ListNode* q = p;
                    p0->next = p->next;
                    p = p->next;
                    free(q);
                }
            } else {
                p0 = p;
                p = p->next;
            }
        }
    
        head = dummy->next;
        free(dummy);
        return head;
    }
    

    解释

    1. 使用虚拟头节点:引入一个虚拟头节点 dummy,这样可以简化边界条件的处理。
    2. 尾部节点处理:在删除尾部节点时,直接将 p0->next 设置为 NULL,并释放 p 指向的节点。
    3. 内存管理:确保每次删除节点后,释放对应的内存。

    测试用例

    #include <stdio.h>
    #include <stdlib.h>
    
    // 定义链表节点结构
    struct ListNode {
        int val;
        struct ListNode *next;
    };
    
    // 打印链表
    void printList(struct ListNode* head) {
        while (head != NULL) {
            printf("%d -> ", head->val);
            head = head->next;
        }
        printf("NULL\n");
    }
    
    // 创建链表节点
    struct ListNode* createNode(int val) {
        struct ListNode* node = (struct ListNode*)malloc(sizeof(struct ListNode));
        node->val = val;
        node->next = NULL;
        return node;
    }
    
    int main() {
        // 创建链表 1 -> 2 -> 6 -> 3 -> 4 -> 5 -> 6
        struct ListNode* head = createNode(1);
        head->next = createNode(2);
        head->next->next = createNode(6);
        head->next->next->next = createNode(3);
        head->next->next->next->next = createNode(4);
        head->next->next->next->next->next = createNode(5);
        head->next->next->next->next->next->next = createNode(6);
    
        printf("Original List: ");
        printList(head);
    
        head = removeElements(head, 6);
    
        printf("List after removing 6: ");
        printList(head);
    
        return 0;
    }
    

    运行结果

    Original List: 1 -> 2 -> 6 -> 3 -> 4 -> 5 -> 6 -> NULL
    List after removing 6: 1 -> 2 -> 3 -> 4 -> 5 -> NULL
    

    通过以上修改和测试,你可以确保代码能够正确处理尾部节点,并且不会出现内存泄漏或指针错误的问题。希望这对你有所帮助!

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

问题事件

  • 系统已结题 12月22日
  • 已采纳回答 12月14日
  • 创建了问题 12月13日