1、使用pTemp保存头节点的指针域(第二个节点的首地址),
2、删除(free)头节点,
3、再将pTemp传给新的pHead进而指向新的头节点。
/*
*copyright(c) 2018,HH
*All rights reserved.
*作 者:HH
*完成日期:2020年3月19日
*版本号:v1.0
*
*问题描述:生成一条包含5个节点的单向链表,然后从头部开始依次删除,直至删除全部节点
*输入描述:
*程序输出:
*备注:
思考如何
*1)获取链表中指定元素的位置;
*2)获取单链表中结点个数;
*3)链表插入or删除
*4)两个链表的合并
*5)链表倒置
*6)遍历链表
*/
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
typedef struct
{
char name[32];
void *next;
}Node;
//创建一条链表,拥有N个节点,尾插法
Node * CreateList(int N)
{
Node *pHead = NULL;//始终指向第一个节点的首地址,没有节点存在时为NULL
Node *pTail = NULL;//始终指向最后一个节点的首地址,没有节点存在时为NULL
for (size_t i = 0; i < N; i++)
{
Node * pNode = (Node *)malloc(sizeof(Node));//节点生成公式!!!!!pNode为指向所生成的节点的指针
sprintf(pNode->name, "学生%d", i+1);//把格式化的数据写入某个字符串缓冲区
pNode->next = NULL;
if (pHead == NULL)//如果是第一个节点
{
pHead = pNode;
}
else
{
pTail->next = pNode;
}
pTail = pNode;
}
return pHead;//返回链表头结点的指针
}
//打印一条链表
void PrintList(Node *pHead)
{
while (pHead!=NULL)
{
printf("%s ", pHead->name);
pHead = pHead->next;//pHead的改变不影响实参,因为是参数的拷贝
}
printf("\n");
}
//删除链表的头节点
Node * DeleteHead(Node *pHead)
{
if (pHead == NULL) return NULL;//最后一个节点被删除时,返回NULL
Node *pTemp = pHead->next; //pTemp指向第二个节点,便于下一步新的pHead
printf("释放内存前,pHead的值: %p , pHead->next的值: %p\n",pHead, pHead->next);
free(pHead); //释放头结点的内存
if (pTemp == NULL) return NULL;//最后一个节点被删除时pTemp==NULL,pTemp->next会报错!!!因此进行限制
printf("释放内存后,pTemp的值: %p , pTemp->next的值: %p\n",pTemp, pTemp->next);
//此刻,pHead指向的内存已经释放, 内存中的next已经是无效值了
pHead = pTemp;//通过pTemp,让头结点指针指向第二个节点
return pHead;
}
int main()
{
Node *pHead= CreateList(5);//生成链表
PrintList(pHead);//打印链表
pHead = DeleteHead(pHead);//删除第一个节点
PrintList(pHead);//打印链表
pHead = DeleteHead(pHead);//删除第一个节点
PrintList(pHead);//打印链表
pHead = DeleteHead(pHead);//删除第一个节点
PrintList(pHead);//打印链表
pHead = DeleteHead(pHead);//删除第一个节点
PrintList(pHead);//打印链表
pHead = DeleteHead(pHead);//删除第一个节点
PrintList(pHead);//打印链表
pHead = DeleteHead(pHead);//删除第一个节点
PrintList(pHead);//打印链表
return 0;
}