对于一个链表来说 头指针是必须的 头结点是可有可无的
不过头结点为链表的插入实现了统一化
在一个没有头结点的链表里面,我们要插入一个结点我们要传的是头指针的地址,因为我们在插入第一个结点的时候要改变头指针 (想改表一个东西就要传它的地址,我们现在要改变的是这个指针 所以要传的是这个指针的地址,这里考虑的后插 所以只有第一次会改变头指针)、、
没有头结点的链表 头指针初始化是这样的
void init(list **head)
{
*head = NULL;
}
void insert_list(list **L,int new_value)
{
list *new;
new = (list *)malloc(sizeof(list));
if(new == NULL )
{
printf("error\n");
exit(1);
}
if( *L == NULL )
{
new->value = new_value;
new->next = NULL;
*L = new; // 这个时候需要改变头指针,这也是我们为什么传指针的地址(二维指针)的原因
}
else
{
list *temp = *L; // 之后我们只需要改变结点里面的值,所以只需要用到结点的地址 对L进行降维操作
while( temp->next != NULL )
{
temp = temp->next;
}
new->value = new_value;
new->next = NULL;
temp->next = new;
}
}
int main()
{
list *head;
init(&head);
insert_list(&head);
}
下面写一个有头结点的链表
有头节点的链表初始化的时候已经申请了一个链表节点的空间作为头指针,这个节点本身没有太大意义 它的数据段是不存放我们想要输入的数据的 下面我们来初始化一个有头结点的链表
int main()
{
list *head; / /这是一个头指针
head = creat_list(); //初始化
}
list *creat_list()
{
list *head ;
head = (list *)malloc(sizeof(list));
if(head == NULL)
{
printf("error");
exit(1);
}
head->next = NULL;
return head;
}
因为我们已经为头指针赋了一个地址(头结点的地址),不要问为什么要插入一个不用的结点,这个只是为了之后插入节点时不需要改变头指针的,实现插入的统一化。我们在之后的插入都不会改变头指针,因为我们插到头结点的后面的,所以我们后面插入的时候直接传head(结构体指针)就可以了 不需要传&head;
void insert_list(list *head,int new_value)
{
list *new;
while(head->next != NULL)
{
head = head->next;
}
new = (list *)malloc(sizeof(list))
if(new ==NULL)
{
printf("error\n");
exit(1);
}
new->value = new_value;
new->next = NULL;
head->next = new;
}
因为定义了一个头结点 这里面是不存放有效数字的 所以我们遍历打印的时候 要从head->next开始打印 判断这个表是不是空判断的也是判断head->next是否为NULL
http://www.nowamagic.net/librarys/veda/detail/1805 结构之美:单链表的头结点与头指针