带头结点和不带头结点

1. 结构区别

  • 不带头结点

    • 链表的第一个结点直接存储有效数据。

    • 头指针(head)直接指向第一个数据结点。

    • 空链表时,头指针为NULL

    struct Node *head = NULL; // 空链表
  • 带头结点

    • 链表的第一个结点是头结点,不存储有效数据,仅作为辅助结点。

    • 头指针始终指向头结点,头结点的next指向第一个数据结点。

    • 空链表时,头结点的nextNULL

struct Node *head = (struct Node*)malloc(sizeof(struct Node));
head->next = NULL; // 空链表

2. 操作区别

(1) 插入操作

  • 不带头结点
    插入到链表头部时需修改头指针,需传递头指针的地址或返回新头指针。

    void insertAtFront(struct Node **head, int data) {
        struct Node *newNode = createNode(data);
        newNode->next = *head;
        *head = newNode;
    }
  • 带头结点
    头结点始终存在,插入操作无需修改头指针,只需操作头结点的next

    void insertAtFront(struct Node *head, int data) {
        struct Node *newNode = createNode(data);
        newNode->next = head->next;
        head->next = newNode;
    }

(2) 删除操作

  • 不带头结点
    删除第一个结点时需修改头指针。

    void deleteFirstNode(struct Node **head) {
        if (*head == NULL) return;
        struct Node *temp = *head;
        *head = (*head)->next;
        free(temp);
    }
  • 带头结点
    删除第一个数据结点时,只需操作头结点的next

void deleteFirstNode(struct Node *head) {
    if (head->next == NULL) return;
    struct Node *temp = head->next;
    head->next = temp->next;
    free(temp);
}

3. 优缺点

4. 应用场景

  • 不带头结点
    适用于对内存敏感的场景,或已知链表操作不会频繁修改头部的情况。

  • 带头结点
    简化代码逻辑,适合频繁在头部插入/删除的场景(如栈的实现)。

// 不带头结点:插入需处理头指针
struct Node* head = NULL;
insertAtFront(&head, 10);

// 带头结点:插入无需处理头指针
struct Node* head = createHeaderNode();
insertAtFront(head, 10);

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值