数据结构 - c语言链表操作

目录

前言:

链表的概念:

顺序表和链表的优缺点:

链表的结构与定义

接口函数

详解接口函数的实现

        创建新节点(BuySListNode)

        打印(SListPrint)

1、尾插(SListPushBack)

2、头插(SListPushFront)

3、尾删(SListPopBack)

4、头删(SListPopFront )

5、查找(SListFind)

6、指定位置前插(SListInsert)

7、删除指定位置节点(SListEarse)

8、指定位置后插(SListInsertAfter)

9、删除指定位置之后的节点(SListEraseAfter)

10、销毁(SListDestroy)

完整代码

SList.h:头文件以及函数申明

SList.c:接口实现

OJ练习巩固


前言:

链表的概念:

链表是一种物理存储结构上非连续、非顺序的存储结构,数据元素的逻辑顺序是通过链表
中的指针链接次序实现的。

简单的说,就是一些结构体相互关联起来,而关联的手段就是指针,通过存储下一个结构体的地址,就能挨个访问存在结构体里的数据。

顺序表和链表的优缺点:

顺序表:

顺序表的优点:

  1. 支持随机访问,有些算法需要结构随机访问,比如二分查找和优化的快排等。
  2. 数据是按顺序存放的,空间利用率高。
  3. 通过下标直接访问,存取速度高效。

顺序表的缺陷:

  1. 空间不够了就需要扩容,扩容是存在消耗的。
  2. 头部或者中间位置的插入或删除,需要挪动,挪动数据时也是存在消耗的。
  3. 避免频繁扩容,一次一般都是按倍数去扩容(2倍适中),可能存在一定空间的浪费现象。

链表:

链表的优点:

  1. 按需申请空间,不用就释放空间( 链表可以更合理地使用空间)。
  2. 头部或者中间位置的插入和删除,不需要挪动数据。
  3. 不存在空间浪费。

链表的缺陷:

  1. 每一个数据,都要存一个指针去链接后面的数据节点。
  2. 不支持随机访问(用下标直接访问第 i 个),必须得走 O(N) 。

顺序表详情:数据结构 - 顺序表基本操作(简单易懂)

(建议先阅读顺序表,更好理解链表)

链表的结构与定义

typedef int SLTDataType;

typedef struct SListNode
{
	SLTDataType data; // val
	struct SListNode* next; // 存储下一个节点的地址
}SListNode, SLN;

        解读:在顺序表章节讲过,为了方便后续使用我们将类型 typedef 一下。首先创建结构体,因为叫单链表(SingleListNode),所以我们将它取为 SListNode。结构体有两个变量,data 是用来存放节点的数据的变量,而 next 是用来指向后继节点指针的变量。

链表结构图:

        便于更形象方便地理解而想象出来的(比如这个箭头其实不存在),事实上在内存中是分散存储的,其中唯一联系就是指针,若指向某块链表的指针搞丢了,那么这块结构体以及其后接的结构体就再也找不到了

接口函数

void SListPrint(SListNode* phead);
void SListPushBack(SListNode** pphead, SLTDataType x);
void SListPushFront(SListNode** pphead, SLTDataType x);
void SListPopBack(SListNode** pphead);
void SListPopFront(SListNode** pphead);
SListNode* SListFind(SListNode* phead, SLTDataType x);

// 在pos位置之前插入
void SListInsert(SListNode** pphead, SListNode* pos, SLTDataType x);
// 删除pos 位置
void SListErase(SListNode** pphead, SListNode* pos);

// 在pos之后插入
void SListInsertAfter(SListNode* pos, SLTDataType x);
// 删除pos位置后面的值
void SListEraseAfter(SListNode* pos);

void SListDestroy(SListNode** pphead);

详解接口函数的实现

创建新节点(BuySListNode)

SListNode* BuySListNode(SLTDataType x)
{
	SListNode* newnode = (SListNode*)malloc(sizeof(SListNode));
	if (newnode == NULL)
	{
		printf("malloc fail\n");
		exit(-1);
	}
	else
	{
		newnode->data = x;
		newnode->next = NULL;
	}

	return newnode;
}

考虑到创建新节点要经常用,为了方便复用,我们把它写成函数 

打印(SListPrint)

void SListPrint(SListNode* phead)
{
	SListNode* cur = phead;
	while (cur != NULL)
	{
		printf("%d->", cur->data);
		cur = cur->next;
	}
	printf("NULL\n");
}

        我们想实现

评论 16
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

NO.-LL

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

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

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

打赏作者

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

抵扣说明:

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

余额充值