关于链表中头指针和头结点的理解

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

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;
}

注:在Linux kernel中,定义头结点使用宏LIST_HEAD。

  • 50
    点赞
  • 110
    收藏
    觉得还不错? 一键收藏
  • 12
    评论
评论 12
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值