P9 链表 清空链表|销毁链表

目录

前言 

01销毁链表 

02 清空链表

测试代码


前言 

                            

🎬 个人主页:@ChenPi

🐻推荐专栏1: 《C++_@ChenPi的博客-CSDN博客》✨✨✨ 

🔥 推荐专栏2: 《Linux C应用编程(概念类)_@ChenPi的博客-CSDN博客》✨✨✨

📝推荐专栏3: ​​​​​​《 链表_@ChenPi的博客-CSDN博客》 ✨✨✨
🍉本篇简介  :  链表清空链表|销毁链表

✨ 只有我努力了 才有机会接触成功✨

链表是一种常见的基础数据结构,结构体指针在这里得到了充分的利用。链表可以动态的进行存储分配,也就是说,链表是一个功能极为强大的数组,他可以在节点中定义多种数据类型,还可以根据需要随意增添,删除,插入节点。链表都有一个头指针,一般以head来表示,存放的是一个地址。链表中的节点分为两类,头结点和一般节点,头结点是没有数据域的。链表中每个节点都分为两部分,一个数据域,一个是指针域。说到这里你应该就明白了,链表就如同车链子一样,head指向第一个元素:第一个元素又指向第二个元素;……,直到最后一个元素,该元素不再指向其它元素,它称为“表尾”,它的地址部分放一个“NULL”(表示“空地址”),链表到此结束。

作为有强大功能的链表,对他的操作当然有许多,比如:

  1. 链表的创建
  2. 链表的链表的遍历打印数据
  3. 链表里面的结构体数据的修改
  4. 链表节点的删除
  5. 链表插入新节点
  6. 链表的数据排序
  7. 链表的反序
  8. 清空链表的元素
  9. 求链表的长度等


在前面几章,我们学习了

  1. 链表的创建
  2. 链表的链表的遍历打印数据
  3. 链表里面的结构体数据的修改
  4. 求链表的长度等
  5. 还有链表结尾插入数据节点,非指定节点
  6. 链表指定节点后方插入数据
  7.  链表头的前方插入数据
  8. 删除链表节点

今天我们学清空链表和销毁链表

单链表的销毁与清空

  1. 销毁:连同头结点一起释放
  2. 清空:保留头结点;置头结点的指针域为NULL

01销毁链表 

销毁链表就是将链表在堆中构造的节点全部销毁,反正内存泄漏

我们首先 要定义一个函数destroyList,然后又一个参数,参数为一个结构体指针,用于传入链表的头节点,然后返回值也是一个结构体指针,不过链表销毁后,链表的头节点也就是个空指针了

销毁链表的函数大致就是长这样了

编译测试一下,我们先将链表清空在拿去打印试一下

没有问题,链表已经被清空了,链表的头指向了NULL 

02 清空链表

 

链表的清空就是保留头结点,然后让他节点的next = NULL就可以,代码上如上,但是有一点,链表是清空了,但是节点的内存是否完全释放,这个我确实不清楚了,不过我debug查看内存的时候,p最后的指向是指向NULL,最后释放

这里我不是特别懂,如果有大佬会的话可以个我将一下,谢谢

编译测试一下,没有问题,链表是被清剩下一个头节点了

测试代码

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

struct Link
{
	int data;
	struct Link *next;
};

/*打印链表数据*/
void PrintLink(struct Link *head)
{
	if(NULL == head)
	{
		puts("ERROR 空链表");
		return;
	}
	struct Link *prev = head;
	while (NULL != prev) 
	{
		printf("%d  ", prev->data);
		prev = prev->next;
	}
	printf("\n");
}

/*获取链表的节点数*/
int GetLinkNum(struct Link *head)
{
	struct Link *prev = head;
	int count = 0;
	while (prev != NULL)
	{
		count++;
		prev = prev->next;
	}
	return count;
}

struct Link *getHead(int data)
{
	struct Link* head = (struct Link*)malloc(sizeof(struct Link));
	head->data = data;
	head->next = NULL;
	return head;
}

/* 链表头插入数据,不指定位置*/
struct Link* frontInsertDataLink(struct Link *head, int data)
{
	struct Link *prev = head;
	struct Link *newLink = (struct Link *)malloc(sizeof(struct Link));
	newLink->data = data;
	newLink->next = prev;
	return newLink;
}

struct Link *frontInsertNodeDataLink(struct Link *head,int NodeIndex,int data)
{
	struct Link *prev = head;
	int cnt = 1;
	if(NodeIndex > GetLinkNum(prev)||(NodeIndex<0))
	{
		printf("ERROR: Link index out of range");
		return NULL;
	}
	else if (NodeIndex == 1)
	{
		prev = frontInsertDataLink(prev,data);
		return prev;
	}
	while (NULL != prev->next)
	{
		if(cnt == NodeIndex-1)
		{
			struct Link *newLink = (struct Link *)malloc(sizeof(struct Link));
			newLink->data = data;
			newLink->next = prev->next;
			prev->next = newLink;
			return head;
		}
		cnt++;
		prev = prev->next;
	}
	return NULL;
}


struct Link * deleteHeadLinkNode(struct Link *head,int NodeIndex)
{
	struct Link *prev = head;   //保存头节点的地址
	int cnt = 1;
	if(NodeIndex > GetLinkNum(prev)||(NodeIndex<0))   //判断是否越界
	{
		printf("ERROR: Link index out of range");
		return NULL;
	}


	if(1 == NodeIndex)   //如果要删除头节点
	{
		head = head->next;
		free(prev);
		return head;
	}

	struct Link *prior = NULL;   //遍历时用来保留前一个节点的状态
	while (NULL != prev)   //判断是不是最后一个节点
	{
		prior = prev;//用来保留前一个节点的状态
		prev = prev->next;   //走向下一个节点,也就是循环增量

		if(cnt == NodeIndex-1)  //找到需要删除的节点
		{
			if(NULL == prev->next)    //1.如果找到的是尾节点
			{
				prior->next = NULL;       //原来尾节点的前一个为节点变成了新尾节点
				free(prev);        //释放原来尾节点的内存
				return head;
			}
			else    //如果找到的是普通节点
			{
				prior->next = prev->next;   //要删除的节点的前一个节点和后一个节点相连
				free(prev);
				return head;
			}
		}
		cnt++;
	}
	return NULL;   //没找到对应节点,操作失败,返回NULL
}

//销毁链表
struct Link* destroyList(struct Link *head) 
{
	struct  Link *p = head;
	while (p != NULL)
	{
		head = head->next;
		free(p);
		p = head;
	}
	return head;
}

//清空链表
void clearList(struct Link *head) 
{
	struct Link *p;
	while (head->next) {
		p = head->next;
		head->next = p->next;
		free(p);
	}
	p = NULL;
	free(p);
}

int main()
{
	struct Link *head = getHead(3);
	head = frontInsertDataLink(head, 5); 
	head = frontInsertDataLink(head, 2); 
	PrintLink(head);
	head = frontInsertNodeDataLink(head, 1,4);
	PrintLink(head);
	head = deleteHeadLinkNode(head,2);
	PrintLink(head);
	head = destroyList(head);
	//head = destroyList(head);
	PrintLink(head);
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

@ChenPi

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值