【数据结构】单链表---C语言版(全网最最最最细!小白必必必必看!!!有图有真相!)

这篇具有很好参考价值的文章主要介绍了【数据结构】单链表---C语言版(全网最最最最细!小白必必必必看!!!有图有真相!)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

【数据结构】单链表---C语言版(全网最最最最细!小白必必必必看!!!有图有真相!),数据结构与算法,数据结构,链表,c语言,c++,算法


【数据结构】单链表---C语言版(全网最最最最细!小白必必必必看!!!有图有真相!),数据结构与算法,数据结构,链表,c语言,c++,算法

🐸一、前言

终于放假啦!🤩🤩停更了两个月,在假期要把欠下的补回来&有规律的学习!🤓
本篇文章来自《数据结构与算法》 专栏,本篇的内容是单链表的学习,也是数据结构的基础,希望烙铁们可以理解消化哦🥰!!!

🐸二、单链表与顺序表的区别

【数据结构】单链表---C语言版(全网最最最最细!小白必必必必看!!!有图有真相!),数据结构与算法,数据结构,链表,c语言,c++,算法

🐵1.存储形式上的区别

顺序表 在物理上和逻辑上都是连续的
单链表 在物理上是不连续的,在逻辑上是连续的

【数据结构】单链表---C语言版(全网最最最最细!小白必必必必看!!!有图有真相!),数据结构与算法,数据结构,链表,c语言,c++,算法

🐵2.空间上的区别

顺序表一般有固定的空间大小,当空间不够时需要进行扩容,扩容时往往不能准确知道需要扩容的空间大小,很容易会造成空间浪费例如当前容量为100,满了以后增容到200,我们再继续插入了5个数据,后面没有数据插入了,那么就浪费了95个数据空间。

单链表 用一个空间申请一个空间,相比顺序表不那么浪费空间(并不是完全不浪费)

总结在存储数据时,如果知道具体空间大小,就用顺序表进行存储,不知道具体空间大小,就用单链表

🐵3.时间上的区别

1️⃣随机插入、删除元素的时间复杂度:

顺序表时间复杂度为 O(n),因为其空间是连续的,在某个位置插入时,这个位置后面的元素都要往后挪动位置;
单链表时间复杂度为 O(1),只需要改变前驱元素及插入删除元素的指向;

2️⃣查找指定元素,修改指定位置元素的时间复杂度:

顺序表时间复杂度为 O(1),依靠下标直接可以找到指定元素,对其操作;
单链表时间复杂度为 O(n),需要从链表头结点往下遍历;

🐸三、单链表详解

🍎创建单链表

🥰这里先创建三个文件:
1️⃣:SList.h文件用于函数的声明
2️⃣:SList.c文件用于函数的定义
3️⃣:Test.c文件用于测试函数
建立三个文件的目的: 将单链表作为一个项目来进行编写,方便我们的学习与观察。

⭕接口1:定义结构体(SLTNode)

🥰请看代码与注释👇

//自定义类型
typedef int SLTDataType;

//创建单链表
typedef struct SListNode
{
	SLTDataType data;
	struct SListNode* next;
}SLTNode;

⭕接口2:打印(SLTPrint)

🥰请看代码与注释👇

//打印
void SLTPrint(SLTNode* phead)
{
	SLTNode* cur = phead;
	while (cur != NULL)
	{
		printf("%d-> ", cur->data);
		cur = cur->next;
	}
	printf("NULL\n");
}

⭕接口3:释放(SLTDestroy)

🥰请看代码与注释👇

//释放
void SLTDestroy(SLTNode** pphead)
{
	assert(pphead);

	SLTNode* cur = *pphead;
	while (cur)
	{
		SLTNode* next = cur->next;
		free(cur);
		cur = next;
	}
	*pphead = NULL;
}

⭕接口4:创建新结点(BuyLTNode)

🥰请看代码与注释👇

//创建新结点
SLTNode* BuyLTNode(SLTDataType x)
{
	SLTNode* newnode = (SLTNode*)malloc(sizeof(SLTNode));
	if (newnode == NULL)
	{
		perror("mallic fail");
		return;
	}

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

	return newnode;
}

⭕接口5:头插(SLTPushFront)

【数据结构】单链表---C语言版(全网最最最最细!小白必必必必看!!!有图有真相!),数据结构与算法,数据结构,链表,c语言,c++,算法
🥰请看代码与注释👇

//头插
void SLTPushFront(SLTNode** pphead, SLTDataType x)
{ 
	assert(pphead);   //链表为空,pphead也不为空,因为他是头指针plist的地址
	                  // *pphead 不能断言,链表为空,也需要能插入
	SLTNode* newnode = BuyLTNode(x);

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

⭕接口6:尾插(SLTPushBack)

🚨主要思想就是 找尾,要注意尾插有两种情况:空链表和非空链表
很多烙铁容易找错,这里要找的是尾结点,而不是
尾结点(tail):next为空的
【数据结构】单链表---C语言版(全网最最最最细!小白必必必必看!!!有图有真相!),数据结构与算法,数据结构,链表,c语言,c++,算法
🥰请看代码与注释👇

//尾插
void SLTPushBack(SLTNode** pphead, SLTDataType x)
{
	assert(pphead);
	SLTNode* newnode = BuyLTNode(x);

	//1.空链表
	//2.非空链表
	if (*pphead == NULL)
	{
		*pphead = newnode;    //改变的结构体的指针plist(用结构体指针的地址)
	}
	else
	{
		SLTNode* tail = *pphead;
		while (tail->next != NULL)
		{
			tail = tail->next;
		}
	                           
		tail->next = newnode;    //改变的结构体尾结点
	}
}

⭕接口7:头删(SLTPopFront)

🚨要注意头删有三种情况:1.没有结点(空链表)、2.一个结点、3.多个结点
链表为空不能头删,所以要进行assert断言
【数据结构】单链表---C语言版(全网最最最最细!小白必必必必看!!!有图有真相!),数据结构与算法,数据结构,链表,c语言,c++,算法
🥰请看代码与注释👇

//头删
void SLTPopFront(SLTNode** pphead)
{
	//没有结点(空链表)
	assert(*pphead);  //链表为空,不能头删
	assert(pphead);
	
	//一个结点
	if ((*pphead)->next == NULL)
	{
		free(*pphead);
		*pphead = NULL;
	}
	//多个结点
	else
	{
		SLTNode* cur = *pphead;
		*pphead = cur->next;
		free(cur);
	}
}

可以有更简洁高效的写法👇
🥰请看代码与注释👇

//头删
void SLTPopFront(SLTNode** pphead)
{
	//没有结点(空链表)
	assert(*pphead);
	assert(pphead);

	//一个结点
	//多个结点
	SLTNode* cur = *pphead;
	*pphead = (*pphead)->next;
	free(cur);
}

⭕接口8:尾删(SLTPopBack)

🚨要注意尾删同样有三种情况:1.没有结点(空链表)、2.一个结点、3.多个结点
链表为空不能尾删,所以要进行assert断言
【数据结构】单链表---C语言版(全网最最最最细!小白必必必必看!!!有图有真相!),数据结构与算法,数据结构,链表,c语言,c++,算法
🥰请看代码与注释👇

//尾删
void SLTPopBack(SLTNode** pphead)
{
	//没有结点(空链表)
	assert(*pphead);
	assert(pphead);

	//一个结点
	if ((*pphead)->next == NULL)
	{
		free(*pphead);
		*pphead = NULL;
	}
	//多个结点
	else
	{
		SLTNode* tail = *pphead;
		//找尾
		while (tail->next->next)
		{
			tail = tail->next;
		}
		free(tail->next);
		tail->next = NULL;
	}
}

⭕接口9:查找(SLTFind)

通过遍历进行查找,通常与修改结合联系使用
🥰请看代码与注释👇

//查找
SLTNode* SLTFind(SLTNode* phead, SLTDataType x)
{
	assert(phead);

	SLTNode* cur = phead;
	while (cur)
	{
		if (cur->data == x)
		{
			return cur;
		}
		else
		{
			cur = cur->next;
		}
	}

	return NULL;
}

⭕接口10:修改(SLTModify)

🥰请看代码与注释👇

//修改
void SLTModify(SLTNode* phead, SLTNode* pos, SLTDataType x)
{
	assert(phead);
	assert(pos);
	pos->data = x;
}

⭕接口11:在pos位置之前插入数据(SLTInsert)

🥰请看代码与注释👇

//在pos位置之前插入数据
void SLTInsert(SLTNode** pphead, SLTNode* pos, SLTDataType x)
{
	assert(pphead);
	assert(pos);  //防止给的位置为 空

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

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

⭕接口12:在pos位置之后插入数据(SLTInsertAfter)

🥰请看代码与注释👇

//在pos位置之后插入数据
void SLTInsertAfter(SLTNode* pos, SLTDataType x)
{
	assert(pos);  //防止给的位置为 空
	
	SLTNode* newnode = BuyLTNode(x);
	newnode->next = pos->next;
	pos->next = newnode;
}

⭕接口13:删除pos位置的值(SLTErase)

【数据结构】单链表---C语言版(全网最最最最细!小白必必必必看!!!有图有真相!),数据结构与算法,数据结构,链表,c语言,c++,算法

🥰请看代码与注释👇

//删除pos位置的值
void SLTErase(SLTNode** pphead, SLTNode* pos)
{
	assert(pphead);
	assert(pos);  //防止给的位置为 空

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

		prev->next = pos->next;
		free(pos);
	}
}

⭕接口14:删除pos位置之后的值(SLTEraseAfter)

【数据结构】单链表---C语言版(全网最最最最细!小白必必必必看!!!有图有真相!),数据结构与算法,数据结构,链表,c语言,c++,算法

🥰请看代码与注释👇

//删除pos位置之后的值
void SLTEraseAfter(SLTNode* pos)
{
	assert(pos);
	assert(pos->next);

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

🐸四、完整代码

🥝SList.h

#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);
//释放
void SLTDestroy(SLTNode** pphead);
//创建新结点
SLTNode* BuyLTNode(SLTDataType x);
//头插
void SLTPushFront(SLTNode** pphead, SLTDataType x);
//尾插
void SLTPushBack(SLTNode** pphead, SLTDataType x);
//头删
void SLTPopFront(SLTNode** pphead);
//尾删
void SLTPopBack(SLTNode** pphead);
//查找
SLTNode* SLTFind(SLTNode* phead, SLTDataType x);
//修改
void SLTModify(SLTNode* phead, SLTNode* pos, SLTDataType x);
//在pos位置之前插入数据
void SLTInsert(SLTNode** pphead, SLTNode* pos, SLTDataType x);
//在pos位置之后插入数据
void SLTInsertAfter(SLTNode* pos, SLTDataType x);
//删除pos位置的值
void SLTErase(SLTNode** pphead, SLTNode* pos);
//删除pos位置之后的值
void SLTEraseAfter(SLTNode* pos);

🥝SList.c

#include"SList.h"

//打印
void SLTPrint(SLTNode* phead)
{
	SLTNode* cur = phead;
	while (cur != NULL)
	{
		printf("%d-> ", cur->data);
		cur = cur->next;
	}
	printf("NULL\n");
}

//释放
void SLTDestroy(SLTNode** pphead)
{
	assert(pphead);

	SLTNode* cur = *pphead;
	while (cur)
	{
		SLTNode* next = cur->next;
		free(cur);
		cur = next;
	}
	*pphead = NULL;
}

//创建新结点
SLTNode* BuyLTNode(SLTDataType x)
{
	SLTNode* newnode = (SLTNode*)malloc(sizeof(SLTNode));
	if (newnode == NULL)
	{
		perror("mallic fail");
		return;
	}

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

	return newnode;
}

//头插
void SLTPushFront(SLTNode** pphead, SLTDataType x)
{ 
	assert(pphead);   //链表为空,pphead也不为空,因为他是头指针plist的地址
	                  // *pphead 不能断言,链表为空,也需要能插入
	SLTNode* newnode = BuyLTNode(x);

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

//尾插
void SLTPushBack(SLTNode** pphead, SLTDataType x)
{
	assert(pphead);
	SLTNode* newnode = BuyLTNode(x);

	//1.空链表
	//2.非空链表
	if (*pphead == NULL)
	{
		*pphead = newnode;    //改变的结构体的指针plist(用结构体指针的地址)
	}
	else
	{
		SLTNode* tail = *pphead;
		while (tail->next != NULL)
		{
			tail = tail->next;
		}
	                           
		tail->next = newnode;    //改变的结构体尾结点
	}
}

//头删
void SLTPopFront(SLTNode** pphead)
{
	//没有结点(空链表)
	assert(*pphead);  //链表为空,不能头删
	assert(pphead);
	
	//一个结点
	if ((*pphead)->next == NULL)
	{
		free(*pphead);
		*pphead = NULL;
	}
	//多个结点
	else
	{
		SLTNode* cur = *pphead;
		*pphead = cur->next;
		free(cur);
	}
}

//头删
//void SLTPopFront(SLTNode** pphead)
//{
//	//没有结点(空链表)
//	assert(*pphead);
//	assert(pphead);
//
//	//一个结点
//	//多个结点
//	SLTNode* cur = *pphead;
//	*pphead = (*pphead)->next;
//	free(cur);
//}

//尾删
void SLTPopBack(SLTNode** pphead)
{
	//没有结点(空链表)
	assert(*pphead);
	assert(pphead);

	//一个结点
	if ((*pphead)->next == NULL)
	{
		free(*pphead);
		*pphead = NULL;
	}
	//多个结点
	else
	{
		SLTNode* tail = *pphead;
		//找尾
		while (tail->next->next)
		{
			tail = tail->next;
		}
		free(tail->next);
		tail->next = NULL;
	}
}

//查找
SLTNode* SLTFind(SLTNode* phead, SLTDataType x)
{
	assert(phead);

	SLTNode* cur = phead;
	while (cur)
	{
		if (cur->data == x)
		{
			return cur;
		}
		else
		{
			cur = cur->next;
		}
	}

	return NULL;
}

//修改
void SLTModify(SLTNode* phead, SLTNode* pos, SLTDataType x)
{
	assert(phead);
	assert(pos);
	pos->data = x;
}

//在pos位置之前插入数据
void SLTInsert(SLTNode** pphead, SLTNode* pos, SLTDataType x)
{
	assert(pphead);
	assert(pos);  //防止给的位置为 空

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

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

//在pos位置之后插入数据
void SLTInsertAfter(SLTNode* pos, SLTDataType x)
{
	assert(pos);  //防止给的位置为 空
	
	SLTNode* newnode = BuyLTNode(x);
	newnode->next = pos->next;
	pos->next = newnode;
}

//删除pos位置的值
void SLTErase(SLTNode** pphead, SLTNode* pos)
{
	assert(pphead);
	assert(pos);  //防止给的位置为 空

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

		prev->next = pos->next;
		free(pos);
	}
}

//删除pos位置之后的值
void SLTEraseAfter(SLTNode* pos)
{
	assert(pos);
	assert(pos->next);

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

🥝Test.c

#include"SList.h"

//头插测试
void TestSList01()
{
	SLTNode* plist = NULL;
	SLTPushFront(&plist, 1);
	SLTPushFront(&plist, 2);
	SLTPushFront(&plist, 3);
	SLTPushFront(&plist, 4);

	SLTPrint(plist);

	SLTDestroy(&plist);
}

//尾插测试
void TestSList02()
{
	SLTNode* plist = NULL;
	SLTPushFront(&plist, 1);
	SLTPushFront(&plist, 2);
	SLTPushFront(&plist, 3);
	SLTPushFront(&plist, 4);

	SLTPushBack(&plist, 5);
	SLTPushBack(&plist, 6);
	SLTPushBack(&plist, 7);

	SLTPrint(plist);

	SLTDestroy(&plist);
}

//头删测试
void TestSList03()
{
	SLTNode* plist = NULL;
	SLTPushFront(&plist, 1);
	SLTPushFront(&plist, 2);
	SLTPushFront(&plist, 3);
	SLTPushFront(&plist, 4);
	SLTPrint(plist);

	SLTPopFront(&plist);
	SLTPrint(plist);
	SLTPopFront(&plist);
	SLTPrint(plist);
	SLTPopFront(&plist);
	SLTPrint(plist);
	SLTPopFront(&plist);
	SLTPrint(plist);

	SLTDestroy(&plist);
}

//尾删测试
void TestSList04()
{
	SLTNode* plist = NULL;
	SLTPushFront(&plist, 1);
	SLTPushFront(&plist, 2);
	SLTPushFront(&plist, 3);
	SLTPushFront(&plist, 4);
	SLTPrint(plist);

	SLTPopBack(&plist);
	SLTPrint(plist);
	SLTPopBack(&plist);
	SLTPrint(plist);
	SLTPopBack(&plist);
	SLTPrint(plist);
	SLTPopBack(&plist);
	SLTPrint(plist);

	SLTDestroy(&plist);
}

//查找修改测试
void TestSList05()
{
	SLTNode* plist = NULL;
	SLTPushFront(&plist, 1);
	SLTPushFront(&plist, 2);
	SLTPushFront(&plist, 3);
	SLTPushFront(&plist, 4);
	SLTPrint(plist);

	SLTNode* pos = SLTFind(plist, 3);
	if (pos)
	{
		SLTModify(plist, pos, 8);
	}

	SLTPrint(plist);
	SLTDestroy(&plist);
	
}

//在pos位置之前插入数据测试
void TestSList06()
{
	SLTNode* plist = NULL;
	SLTPushFront(&plist, 1);
	SLTPushFront(&plist, 2);
	SLTPushFront(&plist, 3);
	SLTPushFront(&plist, 4);
	SLTPrint(plist);

	SLTNode* pos = SLTFind(plist, 3);
	if (pos)
	{
		SLTInsert(&plist, pos, 30);
	}

	SLTPrint(plist);
	SLTDestroy(&plist);
}

//在pos位置之后插入数据测试
void TestSList07()
{
	SLTNode* plist = NULL;
	SLTPushFront(&plist, 1);
	SLTPushFront(&plist, 2);
	SLTPushFront(&plist, 3);
	SLTPushFront(&plist, 4);
	SLTPrint(plist);

	SLTNode* pos = SLTFind(plist, 2);
	if (pos)
	{
		SLTInsertAfter(pos, 20);
	}

	SLTPrint(plist);
	SLTDestroy(&plist);
}


//删除pos位置的值测试
void TestSList08()
{
	SLTNode* plist = NULL;
	SLTPushFront(&plist, 1);
	SLTPushFront(&plist, 2);
	SLTPushFront(&plist, 3);
	SLTPushFront(&plist, 4);
	SLTPrint(plist);

	SLTNode* pos = SLTFind(plist, 3);
	if (pos)
	{
		SLTErase(&plist,pos);
	}

	SLTPrint(plist);
	SLTDestroy(&plist);
}

//删除pos位置之后的值测试
void TestSList09()
{
	SLTNode* plist = NULL;
	SLTPushFront(&plist, 1);
	SLTPushFront(&plist, 2);
	SLTPushFront(&plist, 3);
	SLTPushFront(&plist, 4);
	SLTPrint(plist);

	SLTNode* pos = SLTFind(plist, 2);
	if (pos)
	{
		SLTEraseAfter(pos);
	}

	SLTPrint(plist);
	SLTDestroy(&plist);
}

int main()
{
	//TestSList01();
	//TestSList02();
	//TestSList03();
	//TestSList04();
	//TestSList05();
	//TestSList06();
	//TestSList07();
	//TestSList08();
	//TestSList09();

	return 0;
}

😍这期内容些许复杂,需要慢慢理解消化哦!

总结🥰
以上就是 【数据结构】单链表—C语言版 的全部内容啦🥳🥳🥳🥳
本文章所在【数据结构与算法】专栏,感兴趣的烙铁可以订阅本专栏哦🥳🥳🥳
前途很远,也很暗,但是不要怕,不怕的人面前才有路。💕💕💕
小的会继续学习,继续努力带来更好的作品😊😊😊
创作写文不易,还多请各位大佬uu们多多支持哦🥰🥰🥰

【数据结构】单链表---C语言版(全网最最最最细!小白必必必必看!!!有图有真相!),数据结构与算法,数据结构,链表,c语言,c++,算法文章来源地址https://www.toymoban.com/news/detail-554744.html

到了这里,关于【数据结构】单链表---C语言版(全网最最最最细!小白必必必必看!!!有图有真相!)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包赞助服务器费用

相关文章

  • 【数据结构】——单链表超详细介绍(独家介绍,小白必看!!!)

    【数据结构】——单链表超详细介绍(独家介绍,小白必看!!!)

    被滑走别滑走 ,我这 一万字 的文章,写的真的很痛苦的,希望能得到 一点点支持 !!! 重点内容 和 易错点 都用 彩笔 标注了,干货满满,耐心看完,我真的真的有在 认真更新o(╥﹏╥)o 上一篇文章介绍完顺序表后,我们就要开始学习链表了,链表的种类有很多,比如说

    2024年02月02日
    浏览(26)
  • 数据结构——单链表(C语言)

    数据结构——单链表(C语言)

    在这⼀条⼗分漫长的路上,我⾛过阳关⼤道,也⾛过独⽊⼩桥。路旁有深⼭⼤泽,也有平坡宜⼈;有杏花春⾬,也有塞北秋风;有⼭重⽔复,也有柳暗花明;有迷途知返,也有绝处逢⽣。——《⼋⼗述怀》 目录 一 . 什么是链表? 二 . 实现单链表 (1)创建相关源文件和头文

    2024年02月08日
    浏览(59)
  • 单链表(数据结构)(C语言)

    单链表(数据结构)(C语言)

    这里特指无哨兵位单向非循环链表 目录 背景 概念 单链表的实现 前景提示 单链表的结构体定义 单链表的打印 关于为什么不断言phead 关于单链表的逻辑结构和物理结构 单链表的尾插 关于为什么要用到二级指针 关于尾插的本质 关于找尾整个过程的解释 关于为什么打印单链表

    2023年04月22日
    浏览(13)
  • 【C语言】数据结构-单链表

    主页:114514的代码大冒险 qq:2188956112(欢迎小伙伴呀hi✿(。◕ᴗ◕。)✿ ) Gitee:庄嘉豪 (zhuang-jiahaoxxx) - Gitee.com 文章目录 目录 文章目录 前言(链表的优势) 一、单链表是什么 二、单链表操作的具体代码实现 1.准备工作 2.打印链表 2.尾插(在链表末端添加数据) 3、头插(

    2024年02月02日
    浏览(12)
  • C语言:数据结构(单链表)

    C语言:数据结构(单链表)

    概念:链表是一种 物理存储结构上非连续 、非顺序的存储结构,数据元素的 逻辑顺序 是通过链表的 指针链接 次序实现的。 链表的结构跟火车车厢相似,淡季时车次的车厢会相应减少,旺季时车次的车厢会额外增加几节。只需要将火车里的某节车厢去掉/加上,不会影响其

    2024年04月26日
    浏览(13)
  • 单链表—C语言实现数据结构

    单链表—C语言实现数据结构

    本期带大家一起用C语言实现单链表🌈🌈🌈 链表是一种物理存储单元上非连续、非顺序的存储结构,数据元素的逻辑顺序是通过链表中的指针链接次序实现的;简单来说,线性表的链式存储结构生成的表,称作“链表”。 每个元素本身由两部分组成: 1、本身的信息,称为

    2024年02月07日
    浏览(39)
  • C语言:数据结构之单链表(四)

    C语言:数据结构之单链表(四)

    本篇谈一谈单链表的 改 ,具体操作就是找到他,然后修改元素即可,上一篇有相关代码,可以参考。 改函数代码如下: main函数如下:(修改第6,8,3位) 结果如下:   至此,单链表的增删改查就谈完了,只需理解它的本质是干什么,代码就很好写了。 总结:①改比较简单,

    2024年02月16日
    浏览(9)
  • C语言:数据结构之单链表(二)

    C语言:数据结构之单链表(二)

    上一篇随笔谈了谈单链表是什么东西,然后进行了初始化,这篇随笔就开始对其进行操作了,首先是增,删,改,查的增。 增,顾名思义就是要增加新的元素,单链表是链式的,那就要考虑怎么去加新元素,有三种,从头部添加,从尾部添加,从中间添加。先说说从尾部添加

    2024年02月12日
    浏览(10)
  • C语言:数据结构之单链表(一)

    C语言:数据结构之单链表(一)

    当初刚开始学单链表学的是一头雾水,简直就是彻头彻尾灾难,一塌糊涂,过段时间后经过自己的重新认真思考再结合小练习明白了它是怎么个回事儿。 1、首先从它的逻辑上入手,对他有大体认知。 简单来说就是一个一个有方向小块儿连在一起,好像疫情期间大家排队做核

    2024年02月12日
    浏览(12)
  • C语言:数据结构之单链表(三)

    C语言:数据结构之单链表(三)

    上篇谈了谈尾插法和头插法,这篇谈谈中间插入元素和删除。 1、中间插入元素 既然谈到了要从中间插入那就得确定插入的位置是否合法了,我总不能链表总长为5,但是插入的位置是60,这就不对了。所以得先确定这个链表的长度为多少。这个比较简单,就是在寻找尾部的过

    2024年02月13日
    浏览(12)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包