含表头的单链表

单链表的基本结构单元就是结构体变量,链表的意义在于将结构体通过指针的形式连接起来,即每一个结构体的指针指向下一个结构体

基本元素——结构体

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

创建表头表示整个链表

//1 创建一个表头表示整个链表
struct Node *createlisthead()
{
	//链表的基本结构单元就是结构体变量
	//结构体指针指向结构体变量
	//1 赋值结构体变量的地址
	//2 动态内存申请
	struct Node *listhead = (struct Node*)malloc(sizeof(struct Node));
	//差异化处理,表头不使用数据
	listhead->next = NULL;
	return listhead;

}

创建节点

每一次创建节点的时候,把数据传到函数中,创建一个结构体,并把数据储存起来,指针指向空指针

//2 创建节点,为插入做准备
struct Node* createnewnode(int data)
{
	struct Node *newnode = (struct Node*)malloc(sizeof(struct Node));
	newnode->data = data;
	newnode->next = NULL;
	return newnode;
}

表头/表尾/特定位置插入

新的节点指向头节点后面的一个节点,头节点指向新的节点

//3 (表头)链表的插入
void insertnodebyhead(struct Node*headnode, int data)
{
	struct Node*newnode = createnewnode(data);
	newnode->next = headnode->next;
	headnode->next = newnode;

}

表尾方式的插入重点在于通过空指针的判断方式找到表尾

//4 表尾插入
void insertnodebytail(struct Node*headnode,int data)
{
	struct Node*newnode = createnewnode(data);
	//找到表尾
	struct Node*tailnode = headnode;
	while (tailnode->next != NULL)
	{
		tailnode = tailnode->next;
	}
	tailnode->next = newnode;

}

1 通过传入结构体中的数据来找到指定位置
2 期间需要判断判读链表是否为空的情况
3 当找到最后一个节点时依然没有此数据,则表示没有此信息
4 找到后直接通过新节点指向后面的节点,前面的节点指向新节点即可

//5 在特定的位置(前面)插入
void insertnodebyappoint1(struct Node*headnode, int data, int posdata)
{
	struct Node*posnodefront = headnode;
	struct Node*posnode = headnode->next;
	if (posnode == NULL)
	{
		printf("链表为空");
		return;
	}
	else
	{
		while (posnode->data != posdata)
		{
			posnodefront = posnode;
			posnode = posnodefront->next;
			if (posnode == NULL)
			{
				printf("未找到相关信息");
				return;
			}
		}
		struct Node*newnode = createnewnode(data);
		newnode->next = posnode;
		posnodefront->next = newnode;
	}
}

//5 在特定的位置(后面)插入
void insertnodebyappoint2(struct Node*headnode, int data, int posdata)
{
	
	struct Node*posnode = headnode;
	struct Node*posnodeback = headnode->next;
	if (posnode == NULL)
	{
		printf("链表为空");
		return;
	}
	else
	{
		while (posnode->data != posdata)
		{
			posnode = posnodeback;
			posnodeback = posnode->next;
			if (posnode == NULL)
			{
				printf("未找到相关信息");
				return;
			}
		}
		struct Node*newnode = createnewnode(data);

		newnode->next = posnodeback;
		posnode->next = newnode;
	}
}

表头/表尾/特定位置删除

由于结构体变量的内存是动态申请的,所以当删除一个节点时,要释放该节点指向空间,并使指针指向空指针,这样做是为了防止内存泄漏
表头法删除删除的是头节点后面的一个节点,所以我们只需让第二个节点指向第三个节点(方便下一步),头节点指第三个节点即可

//6 表头法删除
void deletenodebyhead(struct Node*headnode)
{
	struct Node*deletenode = headnode->next;
	headnode->next = deletenode->next;
	free(deletenode);
	deletenode = NULL;//释放一段空间时使指针指向空指针,从而不会指向野指针,防止内存泄漏
}

表尾删除的重点在于必须使倒数第二个节点指向空指针,所以还要再创建一个节点最终指向倒数第二个节点,

//7 表尾删除
void deletenodebytail(struct Node*headnode)
{
	struct Node*tailnode = headnode;
	struct Node* tailnodefront = NULL;
	while (tailnode->next != NULL)
	{
		tailnodefront = tailnode;
		tailnode = tailnode->next;

	}
	free(tailnode);
	tailnode = NULL;
	tailnodefront->next = NULL;

}

通过数据找到特定的节点,同时另建一个节点指向前一个节点,按照前面的方法找到特点节点后,只需让前一个节点指向特定节点的下一个节点

//8 指定位置删除
void deletenodebyappoint(struct Node*headnode, int posdata)
{
	struct Node*posnodefront = headnode;
	struct Node*posnode = headnode->next;
	if (posnode == NULL)
	{
		printf("链表为空");
		return;
	}
	else
	{
		while (posnode->data != posdata)
		{
			posnodefront = posnode;
			posnode = posnodefront->next;
			if (posnode == NULL)
			{
				printf("未找到相关信息");
				return;
			}
		}
		posnodefront->next = posnode->next;
		free(posnode);
		posnode = NULL;
	}

}

打印链表

我们需要创建一个移动指针指向第二个节点,从第二个节点开始打印,指针本身即可作为判断条件,打印完一个数据后向后移动,指向下一个节点

//打印链表
void printflist(struct Node*headnode)
{
	
	struct Node*pmove = headnode->next;//从第二个节点开始打印
	while (pmove)
	{
		printf("%d\t", pmove->data);
		pmove = pmove->next;
	}
	printf("\n");
}

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

不可触碰的殇

前途似海,来日方长

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

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

打赏作者

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

抵扣说明:

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

余额充值