错误总结:无头结点链表的创建(二级指针)
无头结点链表的创建(二级指针)
这是上次关于无头链表的操作的所有操作,这些是通过传链表头指针本身(一级指针)所做的操作(其实忘记写释放链表的操作,这是个大问题,不过这次记住写了)
今天实现了通过传链表头指针的地址(二级指针)来实现创建链表结点
#include <stdio.h>
#include <stdlib.h>
typedef struct node{
int data;
struct node *next;
}NODE;
void show(NODE *phead)//打印链表
{
while(phead != NULL){
printf("%d\t", phead->data);
phead = phead->next;
}
printf("\n");
}
NODE *initNode(NODE *phead, int data)//初始化一个结点
{
phead = (NODE *)malloc(sizeof(NODE));
phead->next = NULL;
phead->data = data;
return phead;
}
void createNode(NODE **phead, int data)//创建链表
{
NODE *tmp = initNode(tmp, data);
NODE **ptmp = phead;
if((*phead) == NULL){
*phead = tmp;
}else{
while((*ptmp)->next != NULL){
ptmp = &(*ptmp)->next;
}
(*ptmp)->next = tmp;
}
}
void destoryLinkList(NODE **phead)//释放链表空间
{
NODE **ptmp = phead;
NODE **tmp = NULL;
while((*ptmp) != NULL){
tmp = ptmp;
ptmp = &(*ptmp)->next;
free(*tmp);
tmp = NULL;
}
*phead = NULL;
}
int main(void)
{
NODE *phead = NULL;
createNode(&phead, 1);
createNode(&phead, 2);
createNode(&phead, 3);
createNode(&phead, 4);
show(phead);
destoryLinkList(&phead);
show(phead);
return 0;
}
打印结果如下:
[root@menwen-linux linklist_code]# ./createLinkList
1 2 3 4
关于错误的总结
起初,在写createNode()函数时当给一个不为空的链表链上初始化的结点时,做了如下操作
while((*ptmp)->next != NULL){
(*ptmp) = (*ptmp)->next;//正确应该是: ptmp = &(*ptmp)->next;
}
如果以这种情况执行代码,最后打印的总是后两个结点,前面的结点全部消失了。
这个循环的意思是,当要添加新结点时,先将指针移动到最后一个位置,然后在链上结点,但是:
首先ptmp是一个二级指针,指向结点的地址的地址。
(*ptmp) = (*ptmp)->next;这种做法根本就不会改变指针ptmp的值,而是修改ptmp指向的值,ptmp指针没有移动到下一个结点,将ptmp->next的结点覆盖前一个结点,造成内存泄漏。
当使用 ptmp = &(*ptmp)->next;时,取ptmp指向的next结点的地址赋值给ptmp,就会改变ptmp的值,从而使其指向下一个结点
在写单链表的传链表头结点指针(一级指针)时,也是这么移动指针,不过是一级指针,指针会正常移动到下一个结点,而在二级指针这则完全行不通。