单链表各种接口的实现(C)

【单链表接口实现-C语言】 单链表接口实现-C语言 阅读详情

顺序表的优缺点

顺序表的问题

  1. 头部和中部的插入删除效率都不行,O(N)O(N)O(N)
  2. 空间不够了,扩容有一定消耗(尤其是异地扩容)开新空间,拷贝数据,释放旧空间
  3. 扩容逻辑,可能还存在空间浪费
    1. 多扩,浪费空间
    2. 少扩,频繁扩容
      顺序表的优点
  4. 尾插尾删足够快
  5. 下标的随机访问和修改
    链表:按需申请释放

单链表

初始化

![[Pasted image 20240913213459.png]]

typedef int SLTDataType;
struct SListNode
{
	SLTDataType data;
	struct SListNode* next;
};

typedef struct SListNode SLTNode;

或

typedef int SLTDataType;
typedef struct SListNode
{
	SLTDataType data;
	struct SListNode* next;
}SLTNode;
  • SLTNode,节点
  • data,数据域
  • next,指针域,是一个结构体指针,不能是数据类型的指针,否则不能指向下一个节点
打印单链表
void PrintList(SLTNode* phead)
{
	SLTNode* cur = phead;
	while (cur != NULL)
	{
		printf("%d->", cur->data);
		cur = cur->next;
	}
	
	printf("NULL\n");
}
  • phead存的是第一个节点的地址
  • 把第一个节点赋值给cur,cur指向第一个节点
  • 当cur不为空,访问cur
  • cur->next,取结构体里的值,存的是下一个节点的地址
  • 把cur->next赋给cur,cur指向下一个节点
  • 以此循环,直到cur指向NULL
  • 实际上cur没有动,只是值一直在变化而已
    ![[Pasted image 20240913221329.png]]
  1. 最开始将phead赋给cur
    ![[Pasted image 20240913221504.png]]
  2. cur不为NULL时,将cur->next,也就是下一个节点的地址赋给cur,cur指向下一个节点
    ![[Pasted image 20240913221615.png]]
  3. 直到cur指向NULL,结束
    ![[Pasted image 20240913221703.png]]
构建链表
int main()
{
	SLTNode* n1 = (SLTNode*)malloc(sizeof(SLTNode));
	n1->data = 10;
	
	SLTNode* n2 = (SLTNode*)malloc(sizeof(SLTNode));
	n2->data = 20;
	
	SLTNode* n3 = (SLTNode*)malloc(sizeof(SLTNode));
	n3->data = 30;
	
	n1->next = n2;
	n2->next = n3;
	n3->next = NULL;
	
	PrintSList(n1);
	
	return 0;
}
创建节点
SLTNode* BuySListNode(SLTDataType x)
{
	SLTNode* newnode = (SLTNode*)malloc(sizeof(SLTNode));
	if (newnode == NULL)
	{
		perror ("malloc fail");
		exit(-1);
	}

	newnode->data = x;
	newnode->next = NULL;

	return newnode;
}
  • sizeof里是节点的类型,不是SLTDataType
  • 检查新malloc的节点地址是否为空
  • 初始化新节点
尾插
void SLTPushBack(SLTNode** pphead, SLTDataType x)
{
	assert(pphead);

	SLTNode* newnode = BuySListNode(x);

	if (*pphead == NULL)
	{
		//改变的是结构体指针,要用二级指针
		*pphead = newnode;
	}
	else
	{
		SLTNode* tail = *pphead;
		while (tail->next != NULL)
		{
			tail = tail->next;
		}

		//改变的是结构体,用结构体的指针即可
		tail->next = newnode;
	}
}

先创建一个节点
如果单链表没有节点,为第一次插入

  • 将newnode赋给*pphead,也就是把newnode的地址给*pphead,*pphead指向newnode。
    ![[Pasted image 20240914220033.png]]
    由于这里要修改的phead是结构体指针,在函数中要修改实参需要通过指针的指针也就是二级指针,再解引用来修改。
    *pphead就是phead
    当单链表中已经有节点
  1. 将*pphead头节点赋给tail,也就是把第一个节点的地址赋给tail,tail指向第一个节点
    ![[Pasted image 20240914214023.png]]
  2. 将tail->next赋给tail,也就是下一个节点的地址赋给tail,tail指向下一个节点
    ![[Pasted image 20240914214123.png]]
  3. 一直循环,直到tail->next指向NULL停止,也就是tail指向NULL的前一个节点
    ![[Pasted image 20240914214222.png]]
  4. 将newnode赋给tail->next,将next指向的NULL,改为指向newnode
    ![[Pasted image 20240914214348.png]]

尾插完成

  • 改变结构体,要用结构体指针
  • 改变结构体指针,要用结构体指针的指针
头插
void SLTPushFront(SLTNode** pphead, SLTDataType x)
{
	assert(pphead);
	SLTNode* newnode = BuySListnode(x);

	newnode->next = *pphead;
	*pphead = newnode;
}
  • newnode是一个结构体
  • *pphead是结构体指针,用结构体指针可以访问这个结构体的数据,也可以通过next找到下一个节点的地址
  1. 将phead赋给newnode->next,新节点的next指向phead
    ![[Pasted image 20240913232032.png]]
    phead存的是第一个节点的地址,等同于
    ![[Pasted image 20240913232203.png]]
  2. 将newnode赋给phead,phead指向newnode,也就是第一个节点
    ![[Pasted image 20240913232240.png]]

完成头插

尾删

不能直接删去最后一个节点,也得把前一个节点的next指向空,否则会造成野指针

void SLTPopBack(SLTNode** pphead)
{
	assert(pphead);
	assert(*pphead);

	if ((*pphead)->next == NULL)
	{
		free(*pphead);
		*pphead = NULL;
	}
	else
	{
		SLTNode* tailPrev = NULL;
		SLTNode* tail = *pphead;
		while (tail->next)
		{
			tailPrev = tail;
			tail = tail->next;
		}

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

如果phead直接是NULL
有可能是调用错误,用assert报错提醒。

当删到最后一个节点时
此时phead指向第一个节点,next指向下一个节点,指向NULL,表示链表只剩最后一个节点
![[Pasted image 20240914222135.png]]
直接free掉phead指针,将phead置为空

链表中还有其他节点时
用tail指针遍历,找最后一个节点
这里如果用一个tail指针,删除掉最后一个节点之后,前一个节点的next指针没有改变,所以需要两个指针跑
再设置一个tailPrev指针,每次tail往下遍历之前,把tail赋给tailPrev,也就是让tailPrev指向当前自己,自己再往后遍历

  1. phead赋给tail,tail指向第一个节点;将tailPrev初始化为NULL
    ![[Pasted image 20240914224531.png]]
  2. 两个指针开始往后遍历,当tail->next指向空结束
    ![[Pasted image 20240914225152.png]]
  3. free掉tail指针,将tailPrev->next置为空
    ![[Pasted image 20240914225227.png]]
    尾删完成

第二种写法

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

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

使用一个tail节点,用tail->next->next找到最后一个节点指向的空,这样tail->next指向的就是最后一个节点,free掉最后一个节点也就是tail->next,然后将tail->next,也就是最后一个节点的上一个节点置为空
![[Pasted image 20240914231339.png]]

头删
void SLTPopFront(SLTNode** pphead)
{
	assert(pphead);
	assert(*pphead);


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

头删不需要找尾,找到下一个即可
一个节点和多个节点不需要分开讨论,都是将第一个节点删去,链接下一个,无非是一个节点的情况下一个节点是空而已,逻辑是一样的
先断言,phead如果是空,就报错,暴力检查

  1. 将phead->next,也就是第二个节点的地址赋给newhead,newhead指向第二个节点
    ![[Pasted image 20240915090509.png]]
  2. 释放掉phead
    ![[Pasted image 20240915090533.png]]
  3. 将newhead赋给phead,phead指向第二个节点
    ![[Pasted image 20240915090601.png]]
查找

查找只需要遍历链表即可,并不会修改头指针,因此不需要传二级指针

SLTNode* SLTFind(SLTNode* phead, SLTDataType x);
{
	SLTNode* cur = phead;
	while (cur)
	{
		if (cur->data == x)
		{
			return cur;
		}

		cur = cur->next;
	}

	return NULL;
}

创建一个cur指针遍历链表

  1. 将phead赋给cur,cur指向第一个节点
    ![[Pasted image 20240915093541.png]]
  2. 将cur->next赋给cur,cur指向下一个节点,一直循环直到cur指向NULL;如果找到x。就直接返回cur
  3. 如果没有找到x,cur指向空遍历完毕后,就返回NULL
    查找还可以用作修改,用查找函数查找到目标data,然后用pos将返回值接收,再修改pos
    如果返回空的话,链表不会有变化
pos之前插入x

在pos位置之前插入一个值,pos可以是任意位置
pos有可能是头插,需要修改头节点,用二级指针
其余情况需要找到pos位置的前一个,来修改next,单链表中只能从头节点开始遍历整个链表

void SLTInsert(SLTNode** pphead, SLTNode* pos, SLTDataType x)
{
	assert(pphead);
	assert(pos);

	if (pos == *pphead)
	{
		SLTPushFront(pphead, x);
	}
	else
	{
		SLTNode* prev = *pphead;
		while (prev->next != pos)
		{
			prev = prev->next;
		}
		SLTNode* newnode = BuySListNode(x);
		prev->next = newnode;
		newnode->next = pos;
	}
}

当pos就是头节点,就相当于头插,直接复用之前的函数
当pos为后续节点

  1. 创建一个prev指针,遍历链表来找pos的前一个节点,假如pos是3
    ![[Pasted image 20240915100351.png]]
  2. 创建一个newnode节点,将newnode赋给prev->next,也就是prev->next存newnode的地址,指向newnode
    ![[Pasted image 20240915100529.png]]
  3. 将pos赋值给newnode->next,newnode->next指向pos
    ![[Pasted image 20240915100626.png]]
pos之后插入x

不可能是头插,pos是第一个节点,就是往第一个节点后面插入

void SLTInsertAfter(SLTNode** pphead, SLTNode* pos, SLTDataType x)
{
	assert(pphead);
	assert(pos);

	SLTNode* newnode = BuySListNode(x);
	newnode->next = pos->next;
	pos->next = newnode;
}

如果pos是NULL,则有可能是传错了,直接报错
复用之前的函数,创建一个节点

  1. 将pos->next赋给newnode->next,newnode->next指向pos的下一个节点
    ![[Pasted image 20240915102238.png]]
  2. 将newnode赋给pos->next,pos->next指向newnode,pos的下一个节点变为newnode
    ![[Pasted image 20240915102325.png]]
删除pos位置

需要找pos前一个节点来断开连接
头删需要处理,因为没有前一个节点
不需要特别处理尾删

void SLTErase(SLTNode** pphead, SLTNode* pos)
{
	assert(pphead);
	assert(pos);

	if (pos == *pphead)
	{
		SLTPopFront(pphead);
	}
	else
	{
		SLTNode* prev = *pphead;
		while (prev->next != pos)
		{
			prev = prev->next;
		}
		prev->next = pos->next;
		free(pos);
	}
}
  1. 假如pos是2,通过prev找到pos的上一个节点
    ![[Pasted image 20240915103351.png]]
  2. 将pos->next赋给prev->next,prev->next指向pos的下一个节点
    ![[Pasted image 20240915103501.png]]
    最后不需要将pos指针置空,因为函数返回以后,pos就是野指针
删除pos后一个位置

pos可以是任意节点
不能删除头节点
当pos是最后一个节点,没有意义

void SLTEraseAfter(SLTNode** pphead, SLTNode* pos)
{
	assert(pphead);
	assert(pos);
	assert(pos->next);

	SLTNode* posNext = pos->next;
	pos->next = posNext->next;
	free(posNext);
	posNext = NULL;
}

通过断言检查上述两种情况

  1. 通过posNext节点存pos的下一个节点
    ![[Pasted image 20240915104223.png]]
  2. 将posNext->next赋给pos->next,pos->next指向posNext的下一个节点,将posNext断开连接
    ![[Pasted image 20240915104341.png]]
  3. 直接free掉posNext节点,可以置空

声明定义分离实现

#pragma once
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>

typedef int SLTDataType;

typedef struct SListNode
{
	SLTDataType data;
	struct SListNode* next;
}SLTNode;

void SLTPrint(SLTNode* phead);

SLTNode* BuySListNode(SLTDataType x);

void SLTPushBack(SLTNode** pphead, SLTDataType x);
void SLTPushFront(SLTNode** pphead, SLTDataType x);
void SLTPopBack(SLTNode** pphead);
void SLTPopFront(SLTNode** pphead);
SLTNode* SLTFind(SLTNode* phead, SLTDataType x);
//在pos之前插入x
void SLTInsert(SLTNode** pphead, SLTNode* pos, SLTDataType x);
//在pos之后插入x
void SLTInsertAfter(SLTNode** pphead, SLTNode* pos, SLTDataType x);
//删除pos位置
void SLTErase(SLTNode** pphead, SLTNode* pos);
//删除pos的后一个位置
void SLTEraseAfter(SLTNode** pphead, SLTNode* pos);

#include"SList.h"

void SLTPrint(SLTNode* phead)
{
	SLTNode* cur = phead;
	while (cur)
	{
		printf("%d->", cur->data);
		cur = cur->next;
	}

	printf("NULL\n");
}

SLTNode* BuySListNode(SLTDataType x)
{
	SLTNode* newnode = (SLTNode*)malloc(sizeof(SLTNode));
	if (newnode == NULL)
	{
		perror ("malloc fail");
		exit(-1);
	}

	newnode->data = x;
	newnode->next = NULL;

	return newnode;
}

void SLTPushBack(SLTNode** pphead, SLTDataType x)
{
	SLTNode* newnode = BuySListNode(x);

	if (*pphead == NULL)
	{
		//改变的是结构体指针,要用二级指针
		*pphead = newnode;
	}
	else
	{
		SLTNode* tail = *pphead;
		while (tail->next != NULL)
		{
			tail = tail->next;
		}

		//改变的是结构体,用结构体的指针即可
		tail->next = newnode;
	}
}

void SLTPushFront(SLTNode** pphead, SLTDataType x)
{
	SLTNode* newnode = BuySListnode(x);

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

void SLTPopBack(SLTNode** pphead)
{
	assert(*pphead);

	if ((*pphead)->next == NULL)
	{
		free(*pphead);
		*pphead = NULL;
	}
	else
	{
		SLTNode* tailPrev = NULL;
		SLTNode* tail = *pphead;
		while (tail->next)
		{
			tailPrev = tail;
			tail = tail->next;
		}

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

void SLTPopFront(SLTNode** pphead)
{
	assert(*pphead);


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

SLTNode* SLTFind(SLTNode* phead, SLTDataType x);
{
	SLTNode* cur = phead;
	while (cur)
	{
		if (cur->data == x)
		{
			return cur;
		}

		cur = cur->next;
	}

	return NULL;
}

void SLTInsert(SLTNode** pphead, SLTNode* pos, SLTDataType x)
{
	assert(pos);

	if (pos == *pphead)
	{
		SLTPushFront(pphead, x);
	}
	else
	{
		SLTNode* prev = *pphead;
		while (prev->next != pos)
		{
			prev = prev->next;
		}
		SLTNode* newnode = BuySListNode(x);
		prev->next = newnode;
		newnode->next = pos;
	}
}

void SLTInsertAfter(SLTNode** pphead, SLTNode* pos, SLTDataType x)
{
	assert(pos);

	SLTNode* newnode = BuySListNode(x);
	newnode->next = pos->next;
	pos->next = newnode;
}

void SLTErase(SLTNode** pphead, SLTNode* pos)
{
	assert(pos);

	if (pos == *pphead)
	{
		SLTPopFront(pphead);
	}
	else
	{
		SLTNode* prev = *pphead;
		while (prev->next != pos)
		{
			prev = prev->next;
		}
		prev->next = pos->next;
		free(pos);
	}
}

void SLTEraseAfter(SLTNode** pphead, SLTNode* pos)
{
	assert(pos);
	assert(pos->next);

	SLTNode* posNext = pos->next;
	pos->next = posNext->next;
	free(posNext);
	posNext = NULL;
}
#include"SList.h"

void TestSList1()
{
	int n;
	printf("请输入链表的长度:");
	scanf("%d", &n);
	printf("\n请依次输入每个节点的值");
	SLTNode* plist = NULL;

	for (size_t i = 0; i < n; i++)
	{
		int val;
		scanf("%d", &val);
		SLTNode* newnode = BuySListNode(val);

		//头插
		newnode->next = plist;
		plist = newnode;
	
		if (plist == NULL)
		{
			plist = newnode;
		}
		else
		{
			plist->next;
		}
	}
	SLTPrint(plist);
}
算法精解_C语言 链表_单链表(接口定义+类型实现) 链表可以说是一种最为基础的数据结构。链表由一组元素以一种特定的顺序组合或链接而成,在维护数据的集合时很有用。这一点同我们常用的数组很相似。然而,链表在很多情况下比数组更有优势。特别是在执行插入和删除操作时链表拥有更高的效率。链表需要动态的开辟存储空间,也就是存储空间是在程序运行时分配的。由于在很多应用中数据的大小在编译时并不能确定,因此这种动态分配空间的特性也是链表的一个优点。 阅读详情

相关推荐

昆仑通态屏幕制作(连载1)---接触篇

写在开始 背景:最近出了做QT、LORA和4G,还做了一个屏幕。以前做了一个迪文的串口屏幕,发现网上的教程很多,所以连载就不更新了,并且迪文屏幕的设置什么的比较简单,应该从网上都能找到对应的教程。而现在用的昆仑通态的屏幕属于嵌入式屏幕,至于为啥叫嵌入式,也不是很明白,反正就是需要用这个屏幕,嵌入式不嵌入式不重要了。重要的是能用,并且能实现串口屏幕不能实现的功能。所以选定昆仑通态的一款屏幕。 文章语言:我比较习惯用比较糙的语言介绍做的东西,有时候不太准备,但是为了方便理解,还请大家谅解。用...

weixin_45426095的博客 6736

【C语言零基础入门篇 - 15】:单链表

链表是数据结构中线性表的一种,其中的每个元素实际上是一个单独的结构体对象,而所有对象都通过每个元素中的指针链接在一起。什么是结点:链表中每个结构体对象叫做结点。什么是首元结点:其中第一个数据结点。什么是头结点:如果第一个结点不用于存储数据,只用于代表链表的起始点,则这个结点称为链表的头结点。

Oh_Python的博客 159

【软件使用】Calibre部分提参的实战技巧与常见问题解析

本文深入解析Calibre部分提参(Partial Extraction)的实战技巧与常见问题,涵盖PEX、hcell和xcell文件的高级应用。通过实际案例展示如何提升电路仿真效率,解决时钟信号失真等复杂问题,并提供版图设计中的防坑指南,助力芯片设计工程师优化工作流程。

weixin_28717431的博客 162

单链表实现(C++实现)

感想 链表这玩意儿呢,我jio得吧其实就是会者不难难者不会,还记得大一刚刚学链表的时候极度痛苦,搞了好几天才能勉强编出来,昨天老师布置让用c++写一个单链表,刚开始还有点犹豫怕写不出来,没想到竟是信手拈来hhh。 源码 #include <iostream> using namespace std; class node { public:u int value; node* ne...

ccql's Blog 3111

从数据集到产品:聊聊Room-to-Room (R2R) 如何影响扫地机器人、AR导航的未来

本文探讨了Room-to-Room (R2R) 数据集如何推动视觉与语言导航(VLN)技术的发展,并重塑扫地机器人和AR导航的未来。通过分析R2R基于Matterport3D的设计及其在真实场景中的应用,揭示了其在提升智能导航精度和自然语言交互能力方面的潜力。文章还讨论了从实验室到产品化的关键技术挑战与解决方案。

weixin_29084231的博客 139

eVTOL热管理:从电动车到飞行器的技术跃迁与工程挑战

热管理系统是保障各类电动设备安全、高效运行的核心技术,其基本原理是通过冷却、加热和温度控制,确保电池、电机等关键部件在最佳工况下工作。在新能源汽车领域,热管理技术已相对成熟,但面对eVTOL(电动垂直起降飞行器)这一新兴领域,其设计逻辑需从二维地面转向三维空域,应对环境温度剧烈变化、重量约束极端严苛等全新挑战。eVTOL的热管理不仅是简单的技术移植,更涉及对电池瞬时高功率散热、乘员舱快速温控及多热源耦合等复杂工程问题的系统性解决,直接关系到飞行安全与商业航程。本文聚焦于**环境温度**和**有效载荷**等关

weixin_42521276的博客 613

【队列(单链表式)接口实现-C语言】

【队列(单链表式)接口实现-C语言】

Kakakawhi的博客 538

使用 MATLAB/Simulink 构建一个多时间尺度下的微电网经济运行优化策略模型

本文介绍了基于Simulink的多能互补微电网系统建模方法,重点关注多时间尺度下的经济运行优化策略。内容包括:系统背景与目标、微电网结构设计(光伏、风电、储能、柴油发电机等模块)、多时间尺度能量管理架构(日前优化、日内滚动优化、实时控制)的实现步骤,以及仿真运行与结果分析。教程详细说明了如何在Simulink中调用优化算法,设置仿真参数,并提供了进阶研究方向和资源推荐。该模型为研究微电网的经济运行和智能调度提供了完整的仿真平台解决方案。

amy_mhd的博客 171

用C语言模拟实现单链表接口函数

创建一个头文件(SList.h),两个源文件(SList.c和test.c) 上图包含了以下3个操作1.库函数的头文件的包含:2.给链表节点的数据域的数据类型重命名 为什么要重命名呢? 这是为了以后如果改变了SL结构体中数据存储的类型时,不用到处改函数参数等地方的数据类型,只要改typedef后的int 为对应要改成的数据类型就可以。3.链表节点结构体定义因为打印链表不会改变头指针,所以传输一级头指针 【方框的上方框为数据域,下方框为指针域】先动态内存申请一个节点的空间 如果链表为空,就让新的节点成为第一个

2301_80058734的博客 1786

Vue3+Openlayers教程导航页【目录】

欢迎来到 Vue3+Openlayers 系列教程,这里是我在 优快云 编写的所有 Vue3+Openlayers 系列相关文章的索引页,适合初学者到进阶用户系统阅读。👀 更多教程正在持续更新中,欢迎关注我,一起探索 Openlayers 的强大魅力!

小彭的博客 1263

30天入门 SAP BTP 开发系列之三:了解 SAP BTP Global Account 的概念

90天之后 Trial 账号会被删除,该账号在 SAP BTP 上创建的内容会被清空,不过我们可以再创建一个新的 Tria 账号。本文简单介绍了 SAP BTP 里 Global Account 的概念,下一篇文章我会介绍 SAP BTP 控制台里和 Global Account 相关的一些操作。,创建 SAP BTP 的 Trial,在可选 Region 列表里,在两个可选项中二选一,选择了。或订阅合同时,SAP BTP 会在后台为其生成一个对应的。在企业拥抱云原生架构的过程中,SAP BTP 的。

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 999

【C数据结构】单链表接口函数逻辑解析与代码实现(含详细代码注释)

在顺序表中我们了解了顺序表的概念与如何创建一个顺序表与它的接口函数完成增删查改的功能。本文将继续介绍线性存储的内容,对单链表的概念进行了相关阐述并且给出了它的接口函数的C语言实现 单链表及其接口函数顺序表的一些缺点:什么是单链表?链表的优点:链表的缺点:单链表的实现 顺序表的一些缺点: 在顺序表阶段,我们了解到顺序表在内存中是一块连续存储的空间,元素与元素之间紧挨存放。不用经过太多思考,我们就可以发现顺序表在实际应用中的一些缺点: 为了能动态的进行存储,那么就需要创建一个动态链表进行数据存储。 为了避免频

weixin_43607192的博客 769

vue2学习笔记2-老规矩,从Hello World开始,了解Vue实例和模板

想要把“Hello,World”放置在页面上,首先需要准备一个HTML的块级元素div,来承接内容。

l_q_l的专栏 1258

数据结构——单链表接口实现(C语言)

单链表的接口实现一、链表的概念及结构1.1 概念1.2 结构二、链表的接口实现2.1 链表的存储三级目录 一、链表的概念及结构 1.1 概念 链表是一种物理结构上非连续、非顺序的存储结构,数据元素的逻辑顺序是通过链表中的指针链接次序实现的。 1.2 结构 二、链表的接口实现 2.1 链表的存储 三级目录 ...

2599

efm32 入门.pdf

本PDF共计22页,介绍的是操作驱动API,下载与否自己斟酌。

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

【C语言数据结构】单链表详解(从单链表的概念理解到接口实现)

和当时实现顺序表一样,我们还是把链表中要存放的参数类型在头文件中重命名,之后定义变量的时候就用这个新名称。指针的类型也是一个结构体,指向下一个完整且独立的节点。/*对存放的数据类型进行重命名,想修改类型只需修改一处*//*存放的数据*//*结构体类型的指针,指向存放下一个数据的空间,可以为NULL*/}SListNode;/*声明节点*/链表的功能与顺序表差不多,无非就是各种增删查改,我们来在头文件中声明一下实现各个功能的函数。// 动态申请一个节点// 单链表打印// 单链表尾插。

谁在夜里看海.的博客 1408

ssm框架搭建

这个是一个在idea上成功跑起来的ssm框架项目,保存在这里方便以后使用直接下载

【C语言】超详细的单链表实现及接口执行逻辑解析~

在上两篇博文中,我写了顺序表及以顺序表为底层结构实现通讯录项目的相关内容,这都是线性表的一种,本文将详细介绍另一种线性表数据结构——链表。本文中有超多画图讲解,请你一定不要错过哟!

careathers的博客 392

老版QQ原生表情gif动态

这是老版的QQ表情,不过全是动态的的,Windows照片查看器是不会动的,可以右击用浏览器打开查看,再说一遍是老版的,只是分享给宁愿用老版也要动态的人。

C语言单链表的实现(增删改查和一些其他接口)

文章目录1.链表的概念2.头文件3.单链表的创建4.初始化单链表5.插入5.1头插5.2尾插6.查找7.删除7.1头删7.2尾删7.3删除数据8.修改9.功能性接口9.1打印单链表数据9.2获取有效数据个数9.3销毁9.4判空 1.链表的概念 概念:链表是一种物理存储结构上非连续、非顺序的存储结构,数据元素的逻辑顺序是通过链表中的指针链接次序实现的 。单链表的结构如下: 2.头文件 #include <stdio.h> #include <stdlib.h> 3.单链表的创建

weixin_45137562的博客 550

C语言单链表核心操作全解析:初始化、销毁与常用接口实现

数据域(存储数据)和指针域(存储下一个节点的地址)。代码定义如下(通用模板):💡 说明:typedef的作用是简化类型名,后续定义链表指针时,用LinkList即可替代struct ListNode*,代码更简洁。本文核心讲解了C语言单链表的初始化(带头节点)和销毁(避免内存泄漏)操作,搭配尾插、头插、遍历等辅助接口,形成了完整的链表操作闭环。新手学习时,建议重点理解二级指针的使用场景和内存释放的逻辑,多动手运行代码,观察链表节点的地址变化,就能快速掌握。如果有疑问,欢迎在评论区交流~ 👇。

zzy200762的博客 785

单链表(C语言)

SLTNode;

lhnxkwj的博客 679

「数据结构 链表篇 1-1」单链表(C语言)

单链表代码+详解,C语言实现

look_outs的博客 816

单链表--C语言版(从0开始,超详细解析,小白一看就会)_单链表c语言(1)

​。

2401_84976491的博客 588

【数据结构与算法】使用单链表实现队列:原理、步骤与应用

数据部分指向下一个元素的指针next登录后复制// 链式结构:表示队列}QNode;1.2.3.4.5.6.7.指向队首元素的指针phead指向队尾元素的指针ptail队列的元素个数size登录后复制// 队列的结构int size;}Queue;1.2.3.4.5.6.7.将队列的首尾指针封装成一个结构体,可以方便函数调用,统一接口另外使用一个整型变量记录元素个数,利于其他函数功能实现。

jiaworld的博客 934

单链表接口函数的实现(增删查改)

void SLTInsert(SLTNODE** phead, SLTNODE* pos, DataType x)//待定位置之前的插入。void SLTErase(SLTNODE** phead, SLTNODE* pos)//删除待定节点。void SLTPushFront(SLTNODE** phead, DataType x)//头插。SLTNODE* SLTFind(SLTNODE* phead, DataType x)//查找。

码达拉的博客 937

C语言 零基础帮你快速了解【单链表结构】—— 通讯录项目

本篇博客将介绍如何使用C语言和单链表数据结构来实现一个简单而功能强大的通讯录管理系统。通过这个项目,我们将学习如何在C语言中利用数据结构来组织和管理大量的联系人信息,以及如何实现基本的增加、删除、查找和修改功能。

m0_74951730的博客 997

【数据结构】—C语言实现单链表(超详细!)

这是作者对于单链表学习历程的记录,C语言做到了单链表的实现!很详细,细节都很到位!

B1ue还在专注 5494
上一篇: 数学建模竞赛论文写作方法
下一篇: 带头双向循环链表各种接口的实现(C)
ChoSeitaku
博客等级 码龄5年 3452粉丝 557原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值