1.带头链表和不带头链表的区别
所谓的带头链表就是在第一个有效节点(首元节点)之前增加多一个头节点的链表,多出的这个头节点也叫做哨兵节点。哨兵节点和链表中的其它节点的区别是其数据域一般不存储数据或者只存储链表长度等信息。加入哨兵节点的目的是为了让链表第一个有效节点和最后一个有效节点的插入和删除操作和其它的节点一样。
如下图所示,头结点也就是我们的哨兵节点。其数据域一般不存放数据,指针域指向链表第一个有效节点。
带头链表为空时,其仍然包含一个哨兵节点。而不带头链表为空时,则只剩下一个头指针,不包含任何节点。
注:头节点和第一个节点的区别是,第一个节点一般指的是链表中第一个有效节点,头节点的next指针指向第一个节点。
2.头指针和头节点的关系
在链表中,头指针是指指向链表第一个结点的指针,若链表有头结点,则头指针就是指向链表头结点的指针。
下图是带头链表的头节点和头指针的示意图:
在C语言中,用结构体表示节点,如下:
struct Node
{
int data;
struct Node next;
};
然后可以用如下代码声明一个头指针和头节点:
struct Node *head = NULL; //这里只是声明了一个头指针
head = (struct Node *)malloc(sizeof(struct Node)); //这里声明一个节点并赋值给头指针
head->next = NULL; //到这里说明这个节点是头节点,不存储有用数据
关于头指针,有如下几点说明:
- 无论链表是否为空,头指针均不为空,头指针是链表的必要元素。
- 头指针具有标识作用,因此头指针的名字一般也是链表的名字。
- 链表中可以没有头结点,但不能没有头指针。
关于头节点,有如下几点说明:
- 头结点是为了操作的统一与方便而设立的,放在第一个元素结点之前,其数据域一般无意义(当然有些情况下也可存放链表的长度、用做监视哨等等)。
- 有了头结点后,对在第一个元素结点前插入结点和删除第一个结点,其操作与对其它结点的操作统一了。
- 首元结点也就是第一个元素的结点,它是头结点后边的第一个结点。
- 头结点不是链表所必需的。
注:1和2两个问题及其图片参考了这篇文章:http://www.nowamagic.net/librarys/veda/detail/1805