具体操作:
1、封装一个生成链表的函数(createlist),一个遍历并打印链表的函数(printlist),一个删除链表最后节点的函数(deletelist需要判断是否只剩1个节点);
2、生成一个包含5个节点的单向链表;
3、调用5次删除节点的函数,完成删除,其中第五次由于只剩一个节点无法删除。
关键点:
1)找到倒数第二个节点{pTemp->next->next=NULL时,确定了最后一个节点,使得pHead=pTemp,而pTemp->nex(在移位前)则是倒数第二的节点},
2)将最后一个节点所占用的内存(堆内存)释放掉;pTemp = pTemp->next操作使得节点发生移位,之后再free(pTemp->next)
3)将新的最后一个节点(之前的倒数第二个节点)的指针域置为NULL(移位后的pTemp->next=NULL);
/*
*copyright(c) 2018,HH
*All rights reserved.
*作 者:HH
*完成日期:2020年3月7日
*版本号:v1.0
*
*问题描述:生成一条包含5个节点的单向链表,然后从尾部开始依次删除,直至剩下头部节点
*输入描述:学生C
*程序输出:学生A、学生C、学生C;。
*备注:
思考如何
*1)获取链表中指定元素的位置;
*2)获取单链表中结点个数;
*3)链表插入or删除
*4)两个链表的合并
*5)链表倒置
*6)遍历链表
*/
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
struct Node
{
char name[32];
Node *next;
};
//创建一条链表,拥有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 * DeleteTail(Node *pHead)
{
//需要判断这个链表是否只有一个节点,不存在倒数第二个节点
if (pHead->next == NULL)
{
printf("当前链表只有一个节点\n");
free(pHead);//删完后,这条链表一个节点也没有了
return NULL;
}
Node *pTemp = pHead;
//需要获取尾部节点的前一个节点指针(因为我们要把前一个节点的next设置为NULL)
while (pTemp->next->next!=NULL) //获取倒数第二个节点的指针
{
//当前节点下一个节点的指针域不是NULL时,移位到下一个节点!!!
pTemp = pTemp->next;//pTemp的改变不影响实参
}
printf("当前节点是:%s \n", pTemp->name);
//删除最后一个节点的内存!!!
free(pTemp->next);
//将倒数第二个的next置为NULL,让倒数第二个变成尾节点!!!
pTemp->next = NULL;
return pHead;
}
int main()
{
Node *pHead= CreateList(5);//生成链表
PrintList(pHead);//打印链表
pHead = DeleteTail(pHead);//删除最后一个节点
PrintList(pHead);//打印链表
pHead = DeleteTail(pHead);//删除最后一个节点
PrintList(pHead);//打印链表
pHead = DeleteTail(pHead);//删除最后一个节点
PrintList(pHead);//打印链表
pHead = DeleteTail(pHead);//删除最后一个节点
PrintList(pHead);//打印链表
//接受新的pHead
pHead =DeleteTail(pHead);//删除最后一个节点
PrintList(pHead);//打印链表
return 0;
}