链表数据结构以及指针

1.虚拟头结点的应用

虚拟头结点在处理head节点的操作时经常用到,如果不用虚拟头结点,可能得分情况讨论,如删除操作,我们知道在删除一个节点的时候是需要用前一个节点来操作,使得前一个节点的next=next->next,而在处理head时候,由于没有之前的节点,所以创作一个虚拟头结点dummy就非常要必要而且省去了分类讨论,具体代码模拟如下

ListNode* del(ListNode *head, int x) {
    ListNode dummy;
    dummy.next = head;
    ListNode* prev = &dummy;
    ListNode* curr = head;

    while (curr != NULL) {
        if (curr->val == x) {
            prev->next = curr->next;
            delete curr;  // 使用 delete 代替 free
        } else {
            prev = curr;
        }
        curr = prev->next;
    }

    return dummy.next;  // 返回新的头节点
}

2.如果题目是删除倒数第n个节点,如果恰好是头结点,那么也必用dummy

struct ListNode* removeNthFromEnd(struct ListNode* head, int n) {
    struct ListNode *dummy=malloc(sizeof(struct ListNode));
    struct ListNode*first=dummy;
    struct ListNode*second=dummy;
    dummy->next=head;
    n++;
    while(n--&&first!=NULL)
    {
        first=first->next;
    }   
    while(first!=NULL)
    {
        first=first->next;
        second=second->next;
    }
    struct ListNode*op=second->next;
    second->next=second->next->next;
    free(op);
    return dummy->next;
}

这是给dummy分配动态内存的写法,dummy本来就是指针类型所以给*first赋值合情合理,而下边的法二就不一样了

/**
 * 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* removeNthFromEnd(ListNode* head, int n) {
        struct ListNode dummy;
        struct ListNode*fast=&dummy;
        struct ListNode*slow=&dummy;
        dummy.next=head;//是个对象而不是指针不能用dummt->next
        
        n++;
        while(n--&&fast!=NULL)
        {
           fast=fast->next;
        }
        
        while(fast!=NULL)
        {
            fast=fast->next;
            slow=slow->next;
        }
        
        slow->next=slow->next->next;
        
        return dummy.next;//不return head是为了防止删除首节点,
    }
};

如图,dummy就是这个ListNode类型的变量,不是指针类型,所以给*first赋值的时候需要对

dummy取地址即&dummy,因为dummy不是指针变量,所以访问下一个时候用dummy.next而不是dummt->next,如果dummy被定义的时候是指针类型(如第一个代码)那么使用dummy->next而不是dummy.next

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值