秋木叶 发表于 2017-12-28 11:28:05

头指针 与 头结点

线性表使用顺序(数组)存储时有个弊端,那就是在插入和删除时需要大量的移动数据,这显示是非常消耗时间的,所以可以采用链式存储,即有一个指针域(单链表),来记录下个结点的存储位置(地址),这样在插入和删除结点时只需要修改指针域即可,从而大量减少移动数据所消耗的时间。来看链表的定义:
struct node {
        int data;
        struct node *next;
};

其中有两个元素,data为数据域,用于存储数据,next为指针域,用于存储下个结点的位置(地址)。那么什么是头指针呢?我们把指向第一个结点的指针称为头指针,那么每次访问链表时都可以从这个头指针依次遍历链表中的每个元素,例如:
struct node first;
struct node *head = &first;

这个head指针就是头指针。
这个头指针的意义在于,在访问链表时,总要知道链表存储在什么位置(从何处开始访问),由于链表的特性(next指针),知道了头指针,那么整个链表的元素都能够被访问,也就是说头指针是必须存在的。示例如下:
#include <stdio.h>

struct node {
    int data;
    struct node *next;
};

int main(void)
{
    struct node *head, first, second;

    head = &first;
    first.data = 1;
    first.next = &second;
      
    second.data = 2;
    second.next = NULL;
      
    while (head) {
      printf("%d\n", head->data);
      head = head->next;
    }
    return 0;
}

需要着重注意的是while那部分(通过头指针遍历完整个链表)。

那么什么又是头结点呢?很多时候,会在链表的头部附加一个结点,该结点的数据域可以不存储任何信息,这个结点称为头结点,
头结点的指针域指向第一个结点,例如:
struct node head, first;
head.next = &first;

那么这里的头指针又是谁呢,不在是指向第一个结点的指针,而是指向头结点的指针,例如:
struct node *root = &head;

即root指针才是头指针。示例如下:
#include <stdio.h>

struct node {
    int data;
    struct node *next;
};

int main(void)
{
    struct node *root, head, first, second;
      
    root = &head;
    root->data = 0;
    root->next = &first;
      
    first.data = 1;
    first.next = &second;
      
    second.data = 2;
    second.next = NULL;
      
    while (root) {
      printf("%d\n", root->data);
      root = root->next;
    }
      
    return 0;
}

秋木叶 发表于 2017-12-28 11:32:59

补充一下:头结点和头指针的作用
0、头指针是链表的入口.
1、头结点防止单链表是空的而设的.当链表为空的时候,带头结点的头指针就指向头结点.如果当链表为空的时候,单链表没有带头结点,那么它的头指针就为NULL.
2、头结点是为了方便单链表的特殊操作,插入在表头或者删除第一个结点.这样就保持了单链表操作的统一性!
3、单链表加上头结点之后,无论单链表是否为空,头指针始终指向头结点,因此空表和非空表的处理也统一了,方便了单链表的操作,也减少了程序的复杂性和出现bug的机会。
4、对单链表的多数操作应明确对哪个结点以及该结点的前驱。不带头结点的链表对首元结点、中间结点分别处理等;而带头结点的链表因为有头结点,首元结点、中间结点的操作相同 ,从而减少分支,使算法变得简单 ,流程清晰。对单链表进行插入、删除操作时,如果在首元结点之前插入或删除的是首元结点,不带头结点的单链表需改变头指针的值,在C 算法的函数形参表中头指针一般使用指针的指针(在C+ +中使用引用 &);而带头结点的单链表不需改变头指针的值,函数参数表中头结点使用指针变量即可。
页: [1]
查看完整版本: 头指针 与 头结点