【数据结构】单链表(详解)

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

所属专栏:初始数据结构
博主首页:初阳785
代码托管:chuyang785>
感谢大家的支持,您的点赞和关注是对我最大的支持!!!
博主也会更加的努力,创作出更优质的博文!!
关注我,关注我,关注我,重要的事情说三遍!!!!!!!!

1.前言

前面我们已经用顺序表方式来实现接口函数,但是使用顺序表实现接口函数是有一些缺陷的。

  1. 空间不够了需要增容,增容是要付出代价。
  2. 头部或者中间插入删除数据的时候,需要挪动数据,挪动数据的额时候也是有消耗的。
  3. 避免频繁扩容,我们满了基本上是扩2倍,可能就会导致一定的空间浪费。
  4. 顺序表要求数据从开始位置连续存储那么我们在头部或者中间插入删除数据就需要挪动数据,效率不高。

针对顺序表的缺陷就设计出了单链表。

  1. 按需要申请空间,用不了了就释放空间(更合理的使用了空间)。
  2. 头部或中间插入删除数据,不需要挪动数据。
  3. 不浪费空间。

1.1本章节重点

本章节的重点是熟练掌握二级指针的使用,以及形参和实参之间的关系。

1.2 什么是单链表

所谓链表重在一个链字,顾名思义就是形象认为用一条链子讲各个数据链接起来,顺着条链子就可以找到其他的数据。

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

图像解析:
【数据结构】单链表(详解)
最后是以NULL为结束标志的。

1.3 结构体设计

typedef struct SlistNode
{
	int data;//存放数据
	struct SlistNode* next;//存放下一个数据的地址
}SLTNode;

1.4结构体传参

	SLTNode* plist = NULL;
	SListPushBack(&plist, 1);//先随便那个函数结构当作测试用例
	SListPushBack(&plist, 1);
	SListPushBack(&plist, 2);
	SListPushBack(&plist, 3);
	SListPushBack(&plist, 4);
	SListPushBack(&plist, 5);

注意这里我们传的是plist的地址。而我们的plist同时有时结构体的指针,也就是说我们传过去的是一个二级指针。
至于我们为什么要传二级指针后面我们会讲到。

2. SList.h展示

#define _CRT_SECURE_NO_WARNINGS 1
#pragma once
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>

typedef int SLTDateType;
//定义结构体
typedef struct SlistNode
{
	int data;
	struct SlistNode* next;
}SLTNode;
//打印
void SListPrint(SLTNode* phead);
//尾插
void SListPushBack(SLTNode** pphead, SLTDateType x);
//头插
void  SListPushFront(SLTNode** pphead, SLTDateType x);
//尾删
void SListPopBack(SLTNode** pphead);
//头删
void SListPopFront(SLTNode** pphead);
//查找
SLTNode* SListFind(SLTNode* phead, SLTDateType x);
//给定给位置在pos前面插入
void SListInsert(SLTNode** pphead, SLTNode* pos, SLTDateType x);
//给定一个位置在pos后面插入
void SListInsertAfter(SLTNode** pphead, SLTNode* pos, SLTDateType x);
//给定pos位置删除
void SListErase(SLTNode** pphead, SLTNode* pos);
//给定一个位置删除pos后面的数据
void SListEraseAfter(SLTNode* pos);
//回收空间
void SListDestroy(SLTNode** pphead);

3. SList.c展示

#define _CRT_SECURE_NO_WARNINGS 1
#include "SList.h"

SLTNode* BuyListNode(SLTDateType x)
{
	SLTNode* newnode = (SLTNode*)malloc(sizeof(SLTNode));
	assert(newnode);
	newnode->data = x;
	newnode->next = NULL;

	return newnode;
}


//打印
void SListPrint(SLTNode* phead)
{
	SLTNode* cur = phead;
	while (cur != NULL)
	{
		printf("%d-> ", cur->data);
		cur = cur->next;
	}
	printf("NULL\n");
}
//尾插
void SListPushBack(SLTNode** pphead, SLTDateType x)
{
	assert(pphead);
	//先开辟一开空间
	SLTNode* newnode = BuyListNode(x);
	//判断当没有数据的时候即:NULL
	if (*pphead == NULL)
	{
		*pphead = newnode;
	}
	else
	{
		SLTNode* tail = *pphead;

		while (tail->next != NULL)
		{
			tail = tail->next;
		}
		tail->next = newnode;
	}
}
//头插
void  SListPushFront(SLTNode** pphead, SLTDateType x)
{
	assert(pphead);

	SLTNode* newnode = BuyListNode(x);
	newnode->next = *pphead;
	*pphead = newnode;

}
//尾删
void SListPopBack(SLTNode** pphead)
{
	assert(pphead);

	assert(*pphead);
	//分情况
	//1.只有一个节点的时候
	if ((*pphead)->next == NULL)
	{
		free(*pphead);
		*pphead = NULL;

	}
	//2.有两个及两个以上的节点的时候
	else
	{
		法一:
		SLTNode* tail = *pphead;
		找到尾节点的前一个
		//SLTNode* prev = NULL;
		找到尾插点
		//while (tail->next != NULL)
		//{
		//	prev = tail;
		//	tail = tail->next;
		//}
		//free(tail);
		//tail = NULL;
		//prev->next = NULL;
		
		//法二:
		while (tail->next->next != NULL)
		{
			tail = tail->next;
		}
		free(tail->next);
		tail->next = NULL;
	}

}
//头删
void SListPopFront(SLTNode** pphead)
{
	assert(pphead);

	assert(*pphead);
	SLTNode* next = (*pphead)->next;
	free(*pphead);
	*pphead = next;

}
//查找
SLTNode* SListFind(SLTNode* phead, SLTDateType x)
{
	int i = 0;
	SLTNode* cur = phead;
	while (cur != NULL)
	{
		if (cur->data == x)
			return cur;
		cur = cur->next;
	}
	return NULL;
}
//给定给位置在pos前面插入
void SListInsert(SLTNode** pphead, SLTNode* pos, SLTDateType x)
{
	assert(pphead);
	assert(pos);

	SLTNode* newnode = BuyListNode(x);

	SLTNode* posPrev = *pphead;
	if (pos == *pphead)
	{
		newnode->next = *pphead;
		*pphead = newnode;
	}
	else
	{
		while (posPrev->next != pos)
		{
			posPrev = posPrev->next;
		}
		posPrev->next = newnode;
		newnode->next = pos;
	}
}
//给定一个位置在pos后面插入
void SListInsertAfter( SLTNode* pos, SLTDateType x)
{
	assert(pos);

	SLTNode* newnode = BuyListNode(x);
	newnode->next = pos->next;
	pos->next = newnode;
}
//给定pos位置删除
void SListErase(SLTNode** pphead, SLTNode* pos)
{
	assert(pphead);
	assert(pos);
	assert(*pphead);

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

void SListEraseAfter(SLTNode* pos)
{
	assert(pos);

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

//回收空间
void SListDestroy(SLTNode** pphead)
{
	assert(pphead);
	//法1:
	//SLTNode* tail = *pphead;
	//SLTNode* front = tail;
	//while (tail != NULL)
	//{
	//	tail = tail->next;
	//	free(front);
	//	front = tail;
	//}
	//free(front);
	//front = NULL;

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

4. 各个接口函数的实现

在进行学习的时候,博主建议小伙伴们结合画图来理解。
画图不仅可以更直观的看出程序是怎么实现的,还可以加深我们对单链表的记忆哦。

4.1 尾插

void SListPushBack(SLTNode** pphead, SLTDateType x)
{
	assert(pphead);
	//SLTNode* newnode = BuyListNode(x);//这里后面分装一个函数来开辟空间
	//先开辟一开空间
	SLTNode* newnode = (SLTNode*)malloc(sizeof(SLTNode));
	assert(newnode);
	newnode->data = x;
	newnode->next = NULL;
	//判断当没有数据的时候即:NULL
	if (*pphead == NULL)
	{
		*pphead = newnode;
	}
	else
	{
		SLTNode* tail = *pphead;

		while (tail->next != NULL)
		{
			tail = tail->next;
		}
		tail->next = newnode;
	}
}

我们要插入数据,第一步肯定是先开一块空间,里面存放数据和NULL,这就用到了我们的动态内存开辟函数malloc,并把我们开辟好的空间的地址叫做newnode(新节点的意思)
接着就是将他们链接在一起。
这里用到了一个if语句判断我们链表是否有数据,如果没有我们就让我们开辟的一个空间作为我们的第一个数据,然后我们记住他第一个数据的地址记作*pphead。
【数据结构】单链表(详解)
而else后面的就是有数据之后就往数据后面插入数据就行了。

现在我们回到刚才的问题:为什么要传二级指针呢?
原因是我们咋插入第一个数据的时候是要改变我们传过来的值的,如果我们只是传plist过来了,我们接受的时候就变成了。
void SListPushBack(SLTNode* pphead, SLTDateType x)
这个时候我们的pphead是形参是实参的临时拷贝,而我们知道改变我们的新参是不能改变实参的,如果要改变实参,就必须通过传地址过来,通过解引用的方法来改变他的值,所以这里如果要想改变plist实参,就必须传plist的地址过来。

4.2 打印

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

这里的化就是比较简单的打印,也不需要传二级指针。

4.3 头插

4.3.1内存开辟函数

我们在讨论头插的时候就会想到,我们的尾插和头插总的讲都是插入数据,都是用先创建一个空间,在将他们一一链接起来,所以我们们就换想到能不能分装一个开辟内存的函数,来实现开辟内存呢?

SLTNode* BuyListNode(SLTDateType x)
{
	//开辟一块空间
	SLTNode* newnode = (SLTNode*)malloc(sizeof(SLTNode));
	assert(newnode);
	newnode->data = x;
	newnode->next = NULL;

	return newnode;
}

这个样的化就可以避免代码累赘了。

4.3.2插入

void  SListPushFront(SLTNode** pphead, SLTDateType x)
{
	assert(pphead);
	//开辟一块空间
	SLTNode* newnode = BuyListNode(x);
	newnode->next = *pphead;
	*pphead = newnode;

}

我们的头插也是比较好理解的。
【数据结构】单链表(详解)

4.4 尾删

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

	assert(*pphead);
	//分情况
	//1.只有一个节点的时候
	if ((*pphead)->next == NULL)
	{
		free(*pphead);
		*pphead = NULL;

	}
	//2.有两个及两个以上的节点的时候
	else
	{
		//法一:
		SLTNode* tail = *pphead;
		//找到尾节点的前一个
		SLTNode* prev = NULL;
		//找到尾插点
		while (tail->next != NULL)
		{
			prev = tail;
			tail = tail->next;
		}
		free(tail);
		tail = NULL;
		prev->next = NULL;
		

		法二:
		//while (tail->next->next != NULL)
		//{
		//	tail = tail->next;
		//}
		//free(tail->next);
		//tail->next = NULL;
	}
}

单链表有一个特点就是他是单向的,你只能找到下一个数据,但是你找不到前一个数据。
这个时候我们就要定义一个新的变量(prev)来记住我们要删除的前一个数据地址。
在定义一个(tail)变量来找到我们的尾节点,找到后free,在是prev->next=NULL;
【数据结构】单链表(详解)
同样的这里也是要判断是否只剩下最后一个数据的情况,因为如果我们只剩下最后一个的化我们的prev=NULL,而prev->next是对NULL解引用,这明显是一个错误,所以我们的分两种情况,第一种是有两个及上的数据,第二个是只有一个数据的时候。

4.5 头删

void SListPopFront(SLTNode** pphead)
{
	assert(pphead);
	assert(*pphead);
	
	SLTNode* next = (*pphead)->next;
	free(*pphead);
	*pphead = next;
}

头删的化就没什么好说的了。
直接就是将我们的 *pphead向前推进,然后free吊前面的。
同时这里也不许要分情况,因为就算只有一个数据了我们最后 *pphead也是指向NULL的。

4.6 查找

SLTNode* SListFind(SLTNode* phead, SLTDateType x)
{
	int i = 0;
	SLTNode* cur = phead;
	while (cur != NULL)
	{
		if (cur->data == x)
			return cur;
		cur = cur->next;
	}
	return NULL;
}

查找到话就是一一遍历。

4.7 给定一个位置在这个位置的前面插入数据

void SListInsert(SLTNode** pphead, SLTNode* pos, SLTDateType x)
{
	assert(pphead);
	assert(pos);
	//开辟一块空间
	SLTNode* newnode = BuyListNode(x);
	//当只有一个数据的时候
	if (pos == *pphead)
	{
		newnode->next = *pphead;
		*pphead = newnode;
	}
	//当有两个及以上的数据的时候
	else
	{
		SLTNode* posPrev = *pphead;
		while (posPrev->next != pos)
		{
			posPrev = posPrev->next;
		}
		posPrev->next = newnode;
		newnode->next = pos;
	}
}

【数据结构】单链表(详解)

这里同样的也是要注意一点就是当只有一个数据的时候
【数据结构】单链表(详解)

4.8 给定一个位置在这个位置的后面插入数据

void SListInsertAfter( SLTNode* pos, SLTDateType x)
{
	assert(pos);

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

如果是在后面插入数据的话就不会像上面那样麻烦了,也不用分情况了,因为如果我们在前面一个位置插入的话那么必定会有一个数据,我们就只要往这个数据后面插入即可。

4.9 给定一个位置删除这个位置的数据

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

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

如果我们想要删除中间的某个数据并且删除后还要将他们链接起来,前面我们说了,单链表是单向的,只能找到后面的数据,找不到前面的数据,这个时候我们就要定义一个变量来记住我们前面数据的地址,然后将他们链接起来。

注意:这里也是要分两种情况的,和上面的给定一个位置在这个位置的前面插入数据是一样的道理。

4.10 给定一个位置在删除这个位置前面的数据

void SListEraseAfter(SLTNode* pos)
{
	assert(pos);

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

这里如果我们是删除pos前面的数据的话我们就不用在找到它前面的地址了,而是直接删除后面的数据,因为我们知道单链表是可以找到后面的数据的。

4.11 释放空间

void SListDestroy(SLTNode** pphead)
{
	assert(pphead);
	//法一:
	//SLTNode* tail = *pphead;
	//SLTNode* front = tail;
	//while (tail != NULL)
	//{
	//	tail = tail->next;
	//	free(front);
	//	front = tail;
	//}
	//free(front);
	//front = NULL;

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

5 text.c展示

最后就是我们的text.c源文件了。
我们所写的以上函数接口都是实现功能的,二我们的主函数的一个作用就是测试我们的接口函数是否是正确的。
这里教大家一个小技巧,就是我们没实现一个接口的时候,我们都用一个函数来测试它的功能,这样的好处是我们可以减少我们在调试的时候用到其他的接口函数,这样不仅可能影响到我们的调试,而且还费时。文章来源地址https://www.toymoban.com/news/detail-423390.html

#define _CRT_SECURE_NO_WARNINGS 1
#include "SList.h"
void TestList1()
{
	SLTNode* plist = NULL;
	SListPushBack(&plist, 1);
	SListPushBack(&plist, 2);
	SListPushBack(&plist, 3);
	SListPushBack(&plist, 4);
	SListPushBack(&plist, 5);

	SListPrint(plist);
}
void TestList2()
{
	SLTNode* plist = NULL;

	SListPushFront(&plist, 1);
	SListPushFront(&plist, 2);
	SListPushFront(&plist, 3);
	SListPushFront(&plist, 4);
	SListPushFront(&plist, 5);

	SListPrint(plist);

}


void TestList3()
{
	SLTNode* plist = NULL;

	SListPushFront(&plist, 1);
	SListPushFront(&plist, 2);
	SListPushFront(&plist, 3);
	SListPushFront(&plist, 4);
	SListPushFront(&plist, 5);

	SListPrint(plist);

	SListPopBack(&plist);
	SListPrint(plist);

	SListPopBack(&plist);
	SListPrint(plist);

	SListPopBack(&plist);
	SListPrint(plist);

	SListPopBack(&plist);
	SListPrint(plist);

	SListPopBack(&plist);
	SListPrint(plist);

	SListPopBack(&plist);

}

void TestList4()
{
	SLTNode* plist = NULL;

	SListPushFront(&plist, 1);
	SListPushFront(&plist, 2);
	SListPushFront(&plist, 3);
	SListPushFront(&plist, 4);
	SListPushFront(&plist, 5);

	SListPopFront(&plist);
	SListPopFront(&plist);
	SListPopFront(&plist);
	SListPopFront(&plist);
	SListPopFront(&plist);

	SListPrint(plist);


}

void TestList5()
{
	SLTNode* plist = NULL;

	SListPushFront(&plist, 1);
	SListPushFront(&plist, 2);
	SListPushFront(&plist, 3);
	SListPushFront(&plist, 4);
	SListPushFront(&plist, 5);


	SLTNode* pos=SListFind(plist, 1);
	int i = 1;
	while (pos)
	{
		printf("第%d个节点:%p->%d\n", i++, pos, pos->data);

		pos= SListFind(pos->next, 1);
	}
}
void TestList6()
{
	SLTNode* plist = NULL;

	SListPushFront(&plist, 1);
	SListPushFront(&plist, 2);
	SListPushFront(&plist, 3);
	SListPushFront(&plist, 4);
	SListPushFront(&plist, 5);

	SLTNode* pos = SListFind(plist, 5);

	SListInsert(&plist, pos, 50);

	SListPrint(plist);

}

void TestList7()
{
	SLTNode* plist = NULL;

	SListPushFront(&plist, 1);
	SListPushFront(&plist, 2);
	SListPushFront(&plist, 3);
	SListPushFront(&plist, 4);
	SListPushFront(&plist, 5);

	SLTNode* pos = SListFind(plist, 1);

	SListInsertAfter(&plist, pos, 50);

	SListPrint(plist);

}

void TestList8()
{
	SLTNode* plist = NULL;

	SListPushFront(&plist, 1);
	SListPushFront(&plist, 2);
	SListPushFront(&plist, 3);
	SListPushFront(&plist, 4);
	SListPushFront(&plist, 5);

	SLTNode* pos = SListFind(plist, 1);
	SListErase(&plist, pos);

	pos = SListFind(plist, 2);
	SListErase(&plist, pos);

	pos = SListFind(plist, 3);
	SListErase(&plist, pos);

	pos = SListFind(plist, 4);
	SListErase(&plist, pos);

	pos = SListFind(plist, 5);
	SListErase(&plist, pos);

	SListPrint(plist);

	SListDestroy(&plist);
}
int main()
{
	//TestList1();
	//TestList2();
	//TestList3();
	//TestList4();
	//TestList5();
	//TestList6();
	//TestList7();
	//TestList8();

	return 0;
}

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

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

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

相关文章

  • 【数据结构】单链表(带图详解)

    概念 :链表是一种 物理存储结构 上 非连续 、 非顺序 的存储结构,但链表在逻辑上是连续的,顺序的,而数据元素的逻辑顺序是通过链表中的指针连接次序实现的。 单链表 (Singly Linked List)是一种常用的数据结构,它由若干个节点组成,每个节点包含两部分: 数据域 和

    2024年02月12日
    浏览(30)
  • [数据结构]链表之单链表(详解)

    在学习 链表 之前,我们已经学习了 顺序表 了 根据 顺序表 的特点,我们可以发现 顺序表 有优点,也有一些缺陷。 所以根据 顺序表 的缺点,链表就横空出世啦~ **概念:链表是一种物理存储结构上非连续、非顺序的存储结构,数据元素的逻辑顺序是通过链表中的指针链接次

    2023年04月08日
    浏览(39)
  • 数据结构学习分享之单链表详解

        💓博主CSDN:杭电码农-NEO💓🎉🎉🎉       ⏩专栏分类:数据结构学习分享(持续更新中🫵)⏪🎉🎉🎉     让我们紧接上一章顺序表的概念,引出链表,我们说顺序表每次增容需要申请新的空间,会产生很多空间碎片,代价比较高,并且我们扩容一般是扩两倍,还是会有一些

    2024年02月02日
    浏览(34)
  • 数据结构入门 — 链表详解_单链表

    数据结构入门 — 单链表详解 * 博客主页链接:https://blog.csdn.net/m0_74014525 关注博主,后期持续更新系列文章 文章末尾有源码 *****感谢观看,希望对你有所帮助***** 第一篇:数据结构入门 — 链表详解_单链表 第二篇:数据结构入门 — 链表详解_双向链表 第三篇:数据结构入门

    2024年02月11日
    浏览(38)
  • 数据结构之单链表详解(C语言手撕)

    ​ 🎉文章简介: 概念:链表是一种物理存储结构上非连续、非顺序的存储结构,数据元素的逻辑顺序是通过链表中的指针链接次序实现的 从图片中可以看出,链表的每个节点都是一个结构体,该结构体中有一个存储数据的变量和一个指向下一节点的结构体指针; 在逻辑上

    2024年03月10日
    浏览(34)
  • 【算法与数据结构】 C语言实现单链表队列详解

    前面我们学习了队列的顺序表的实现,本节将用单链表实现队列。 队列也可以数组和链表的结构实现, 使用链表的结构实现更优一些,因为如果使用数组的结构,出队列在数组头上出数据,效率会比较低 。下面我们先复习一下队列的基本概念: 队列:只允许在一端进行插入

    2024年04月11日
    浏览(43)
  • 数据结构与算法——顺序表(顺序存储结构)及初始化详解

    顺序表 ,全名 顺序存储结构 ,是线性表的一种。通过《什么是线性表》一节的学习我们知道,线性表用于存储逻辑关系为“一对一”的数据,顺序表自然也不例外。 不仅如此,顺序表对数据的物理存储结构也有要求。 顺序表存储数据时,会提前申请一整块足够大小的物理

    2024年02月16日
    浏览(31)
  • 【数据结构与算法】顺序表与链表(单链表和双链表)超详解图示与源码。

                                                       大家好,今天我们来学习数据结构中的顺序表与链表!源码在最后附上 首先我们先来认识一下 顺序表 :                                       **如上图所示:很多人会以为数组就是顺序表,顺序表就是数组,这

    2024年02月21日
    浏览(36)
  • 数据结构:图文详解单链表的各种操作(头插法,尾插法,任意位置插入,删除节点,查询节点,求链表的长度,清空链表)

    目录  一.什么是链表 二.链表的实现 节点的插入 头插法 尾插法 指定位置插入 节点的删除 删除第一次出现的节点 删除所有节点 节点的查找 链表的清空 链表的长度 前言: 在上一篇文章中,我们认识了线性数据结构中的顺序表,而本篇文章则是介绍线性数据结

    2024年02月05日
    浏览(33)
  • 【数据结构】数据结构小试牛刀之单链表

    不讲虚的啦,直接肝! 单链表所要实现的功能罗列如下: 初始化工作我们先初始化一个节点类型,类型中包括了数据域和指针域,数据与中保存着该节点要保存的数据,指针域则保存着链表下一个节点的地址: 然后我们在创建一个函数,用于创建一个新的节点,因为后面我

    2023年04月24日
    浏览(50)

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

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

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

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

二维码1

领取红包

二维码2

领红包