数据结构(链表)(2)

数据结构(链表)(2)

  • 由于链表这部分的内容, 比较难讲, 所以打算分4节给大家讲完, 这节呢主要就是实现4个最主要的函数:
  • 也就是尾部插入, 头部插入, 尾部删除和头部删除. 链表这部分, 说难不难, 说简单不简单, 对于刚刚开始接触链表的同学可能得多看几遍, 结合我的图解, 还有文字讲解, 好好的想一想还是能理解的.
  • 咱们最开始实现的是一个“无头, 单向, 非循环 ”的简单链表, 别的形式的链表会在最后和大家讲解.
  • 那么就开始今天的硬菜了, 实现链表尾部插入数据的这个功能. 不过在实现这个功能之前得写个简单的功能函数. 因为咱们链表的节点空间是得要动态开辟的, 因为各种插入都要用到这个功能, 那么就先写一个创建新节点的这么一个功能的函数.
//动态申请一个节点
SLTNode* BuySListNode(SLDatatype x)
{
	//动态开辟一个节点的结构体空间
	SLTNode* newnode = (SLTNode*)malloc(sizeof(SLTNode));
	//判断有没有创建成功
	if (newnode == NULL)
	{
		perror("malloc failed");
		exit(-1);
	}
	//创建成功之后就赋值
	newnode->data = x;
	newnode->next = NULL;
	//返回结构体指针
	return newnode;
}
  • 这个函数的名字大家随便怎么取都可以, 不过呢, 大部分都是这么叫的, 大家按照我这样写也可以. 在上一节也着重讲了链表节点的一个结构, 不熟悉的可以再看看上一节. 下面也补充一下等会我们会用到的打印函数, 主要是拿来测试用的. 这个函数的具体讲解也在上一节有详细的说明了.
//循环遍历打印链表
void PrintSList(SLTNode* phead)
{
	//把头结点的值赋给临时变量cur,不要用phead来遍历,
	//因为等会可能还会用到phead,结果被改了,就不好弄了.
	SLTNode* cur = phead;

	while (cur != NULL)
	{
		printf("%d->", cur->data);
		cur = cur->next;
	}

	printf("NULL\n");
}
  • OK, 那就开始实现尾插功能这个函数了, 我先画图给大家讲讲.

请添加图片描述
请添加图片描述
请添加图片描述
请添加图片描述
请添加图片描述

  • 所以尾部插入的代码如下: (两种情况结合起来就是下面这样, 因为虽然要传的参数不同, 但是二级指针可以通过解引用变成一级指针, 所以不影响. )
void SLTPushBack(SLTNode** pphead, SLTDataType x) {
	assert(pphead);

	SLTNode* newnode = SLTBuyNode(x);

	//链表为空,新节点作为phead
	if (*pphead == NULL) {
		*pphead = newnode;
		return;
	}
	//链表不为空,找尾节点
	SLTNode* ptail = *pphead;
	while (ptail->next)
	{
		ptail = ptail->next;
	}
	//ptail就是尾节点
	ptail->next = newnode;
}
  • 那么接下来就是头部插入数据了, 代码直接如下:
void SLTPushFront(SLTNode** pphead, SLTDataType x)
{
	SLTNode* newnode = BuySListNode(x);

	newnode->next = *pphead;
	*pphead = newnode;
}

请添加图片描述

  • 接下来是尾部删除数据的代码:
void SLTPopBack(SLTNode** pphead)
{
	// 1、判空,空的时候就不能删除,因为没有节点可以删除
	assert(*pphead);

	// 2、一个节点
	if ((*pphead)->next == NULL)
	{
		free(*pphead);
		*pphead = NULL;
	}
    // 3、一个以上节点
	else
	{
		//两种方法,这个方法和下面那个方法都可以
        //SLTNode* tailPrev = NULL;
		//SLTNode* tail = *pphead;
		//while (tail->next)
		//{
		//	tailPrev = tail;
		//	tail = tail->next;
		//}

		//free(tail);
		tail = NULL;
		//tailPrev->next = NULL;

		SLTNode* tail = *pphead;
		while (tail->next->next)
		{
			tail = tail->next;
		}

		free(tail->next);
		tail->next = NULL;
	}
}

请添加图片描述

请添加图片描述

  • 最后就是头部删除的代码:
void SLTPopFront(SLTNode** pphead)
{
	// 空
	assert(*pphead);

	// 非空
	SLTNode* newhead = (*pphead)->next;
	free(*pphead);
	*pphead = newhead;
}

请添加图片描述

  • 17
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值