链表的虚拟头结点

文章介绍了在处理链表时使用虚拟头结点如何简化删除操作,包括如何处理头结点和非头结点的删除,并通过力扣题目203的示例展示了两种不同的实现方式:直接删除和使用虚拟头结点删除。虚拟头结点使得头结点和中间结点的删除统一,提高了代码的简洁性和可读性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

链表的虚拟头结点简单应用

        在对链表进行操作时,采用虚拟头结点的方法会使得操作简单很多。

        例如,在对于链表进行删除操作时(删掉链表中的某个结点),对于头结点以外的结点删除时,是通过其前一个结点直接指向该结点的下一个结点来实现删除该结点的效果。

        如上图中,要删除数据域为2的结点,则让它的前驱结点直接指向2结点的后驱结点,然后释放其内存即可。如下图所示。

 

         但是如果要删除的结点是头结点,则不能采取上述操作,因为头结点并没有前驱节点。所以需要单独进行头结点的删除操作。头结点的删除操作如下图所示,将head后移,然后释放掉之前头结点的内存。

        当引入虚拟头结点时就可以将头结点和之外结点的删除操作整合起来,只需要一段代码就可以实现两种情况的删除。

         当引入了虚拟头结点dummyNode以后,如果要删除头结点1只需要将dummyNode指向结点1的后驱结点,然后释放结点1的内存;这样就将两种情况的删除整合起来了,只需要一种操作就可以实现。

 力扣题目203:移除链表元素

        如上所述,采用两种方法对于链表的元素进行删除。

1)直接删除

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode() : val(0), next(nullptr) {}
 *     ListNode(int x) : val(x), next(nullptr) {}
 *     ListNode(int x, ListNode *next) : val(x), next(next) {}
 * };
 */
class Solution {//如果要删除的结点是头节点,则需要单独实现;中间结点的删除则为常规链表的删除方法
public:
    ListNode* removeElements(ListNode* head, int val) {
        while (head != nullptr && head->val == val) {
            ListNode* temp = head;
            head = head->next;
            delete temp;
        }
        ListNode* cur = head;
        while (cur != nullptr && cur->next != nullptr) {
            if (cur->next->val == val) {
                ListNode* temp = cur->next;
                cur->next = cur->next->next;
                delete temp;
            }
            else 
                cur = cur->next;
        }
        return head;
    }
};

2)虚拟头结点进行删除

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode() : val(0), next(nullptr) {}
 *     ListNode(int x) : val(x), next(nullptr) {}
 *     ListNode(int x, ListNode *next) : val(x), next(next) {}
 * };
 */
class Solution {//采用虚拟头节点的方法,将删除头节点和中间结点的方法合为一个
public:
    ListNode* removeElements(ListNode* head, int val) {
        ListNode* dummyNode = new ListNode(0);
        dummyNode->next = head;//设置一个虚拟头结点
        ListNode* cur  = dummyNode;
        while (cur->next != nullptr) {
            if (cur->next->val == val) {
                ListNode* temp = cur->next;
                cur->next = cur->next->next;
                delete temp;
            }
            else {
                cur = cur->next;
            }
        }
        head = dummyNode->next;
        delete dummyNode;
        return head;
    }
};

总结

        在链表的相关操作中,虚拟头结点的方法是很常用的。采用虚拟头结点可以简化很多的操作。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值