链表的学习

学习目标:链表的初识

可以写出简单的链表

学习内容:

链表的代码实现
链表中删除特定结点

学习产出:

总的代码,看不懂可以先跳过(结构体需要看一下)
后面又拆开的解释

//写一个链表
struct content
{
	int value;
	struct content *next;
};

struct content* creat(int a[], int n)
{
	struct content* list = (struct content*)malloc(sizeof(struct content));
	if (list == NULL)
		return NULL;
	struct content * p = list;//这里的p是需要移动的
	for (int i = 0;i < n;i++)
	{
		struct content* tem = (struct content*)malloc(sizeof(struct content));
		tem->value = a[i];
		p->next = tem;
		p = tem;
	}
	p->next = NULL;
	return list;
}

void visit(struct content *m)
{
	for (struct content*p = m->next;p;p = p->next)
	{
		printf("%d ", p->value);
	}
	printf("\n");
}

//写一个删除链表的函数
int delet(struct content* m,int n)
{
	struct content *p = m;
	for (;p;p = p->next)
	{
		if (p->next->value == n)
			break;
	}
	if (p->next != NULL)
	{
		struct content* tem = p ->next;//需要释放的空间
		p->next = p->next->next;
		free(tem);
	}

}

int main()
{
	int data[10] = { 1,2,3,4,5,6,7,8,9,10 };
	struct content* list = creat(data, 10);
	visit(list);
	delet(list, 5);
	visit(list);
	return 0;
}

链表的形象表示

在这里插入图片描述

链表的将结构体进行串联,需要掌握结构体的使用,结构指针的使用

实现方式:结构体中有一个该结构体的指针,用来指向下一个需要链接的结点,直至结束。

相比于数组:链表不用担心栈溢出等问题,内存分配更加合理

扩展介绍malloc函数

在这里插入图片描述

解释一些代码

struct content* creat(int a[], int n)
{
	struct content* list = (struct content*)malloc(sizeof(struct content));
	if (list == NULL)
		return NULL;
	struct content * p = list;//这里的p是需要移动的
	for (int i = 0;i < n;i++)
	{
		struct content* tem = (struct content*)malloc(sizeof(struct content));
		tem->value = a[i];
		p->next = tem;
		p = tem;
	}
	p->next = NULL;
	return list;
}

第一行:创建了一个返回类型是结构体指针的函数
第一行:用malloc函数为结构体指针申请一个空间
关于*p:这是一个需要移动的变量,初始时指向第一个结构体的地址
关于for:创建临时变量tem
关于tem:开辟新的结构体空间,在老的结构体里存储起来,将老和新链接起来
*P与tem:p不断移动,移动到tem上
结束for: p->next = NULL;的原因,最后一个结构体内的指针放空,代表结束

解释一些代码

void visit(struct content *m)
{
	for (struct content*p = m->next;p;p = p->next)
	{
		printf("%d ", p->value);
	}
	printf("\n");
}

for循环内部的解释

因为我们创建的链表的第一个表头是空的,所以for循环内部
struct content*p = m->next
将地址初始化直接指向第二个地址了

中间的条件放p,是因为,最后一个地址为NULL,为假,会跳出循环。
最后p = p->next,这里是对p进行操作,使他向后面移动

解释一些代码

int delet(struct content* m,int n)
{
	struct content *p = m;
	for (;p;p = p->next)
	{
		if (p->next->value == n)
			break;
	}
	if (p->next != NULL)
	{
		struct content* tem = p ->next;//需要释放的空间
		p->next = p->next->next;
		free(tem);
	}

}

for循环括号里已经在上面解释过,不再赘述

该函数的参数,第二个int n 为我们要删除的元素

为什么要使用for循环,因为我们需要找到需要删除元素的位置

if(for循环里的if)语句里的条件为什么要那么复杂,因为该链表是单向的,我们需要保留删除元素的前趋的地址。目的是改变前趋里指针变量的地址

为什么要创建 tem 这个临时变量

因为我们需要释放删除元素的空间

p->next = p->next->next; 这行代码可以看作将删除元素的前趋中保存的指针跳到后继的地址,实现了删除的目的

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值