链表 - 头节点的意义

说明

  • 初学数据结构时,对于在链表中额外定义一个空数据的头结点不理解,不明白其优劣,认为可有可无,有时为了节省内存空间而去掉该节点,但是定义头结点是有其意义和作用的。
  • 头结点示意图:链表 - 头节点的意义_第1张图片
    链表 - 头节点的意义_第2张图片

缺点

  • 多定义了一个结点,多占用了一个结点的内存。
  • 改善方式:可以采用linux kernel中的list实现方式(结点中只包含结点指针不包含结点数据),减少头节点的内存占用。

优点

  • 单链表或双链表删除或插入节点时,如果没有头结点,处理有两种情况:
  1. 操作的对象不是第一个结点,只需要将前一个节点的next 指向后一个节点。
  2. 操作的对象是第一个结点,相对于第一种情况,由于没有前节点,所以不能按照第一种情况的方式处理,需要更改链表的头指针指向下一个节点。
  • 如果有头结点,只存在一种情况:不是第一个结点,因此按照上面第一种情况进行处理就好了,这样代码更通用,处理更简单高效。
  • 以下是无头节点单链表删除节点的示例代码:
//单链表删除结点
void deleteNode(listNode *node){
    listNode *head, *prev, *current;
    
    if (!head){
        return;    
    }
    
    //无头结点则需要额外做如下处理
    if (head == node){
        head = head->next;
        return;
    }
    
    prev = head;
    current = header->next;
    while (current){
        if (current == node){
            prev->next = current->next;
            delete current;
        } else {
            prev = current;
            current = current->next;
        }
    }
}
  • 以上代码看起来有头结点和没头结点的差别不大,但是实际更复杂情况下的处理会更复杂,会导致初学者理不清,加上头结点能减轻一些复杂情况下的复杂度。

你可能感兴趣的:(数据结构,数据结构)