链表基础知识(二、双向链表头插、尾插、头删、尾删、查找、删除、插入)

这篇具有很好参考价值的文章主要介绍了链表基础知识(二、双向链表头插、尾插、头删、尾删、查找、删除、插入)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

目录

一、双向链表的概念

二、 双向链表的优缺点分析​与对比

 2.1双向链表特点:

2.2双链表的优劣:

2.3循环链表的优劣

2.4 顺序表和双向链表的优缺点分析​

三、带头双向循环链表增删改查实现

3.1SList.c

3.2创建一个新节点、头节点

3.3头插

3.4尾插

3.5头删

3.6尾删

3.7查找

3.8删除

3.9插入

3.10查找

3.11打印链表

3.12销毁链表

四、简化链表,用插入和删除代替其他插入删除

五、SList.h

六、Test.c


书接上文:

链表基础知识(一、单链表、头插、尾插、头删、尾删、查找、删除、插入)-CSDN博客

一、双向链表的概念

双向链表,即一个节点中有两个指针域,一个存放当前节点前一个节点的地址,另一个存放当前节点后一个节点的地址。

(STL中list就是这个结构)

链表基础知识(二、双向链表头插、尾插、头删、尾删、查找、删除、插入),链表,数据结构,算法,c++,c语言,开发语言

双链表的节点:

链表基础知识(二、双向链表头插、尾插、头删、尾删、查找、删除、插入),链表,数据结构,算法,c++,c语言,开发语言

二、 双向链表的优缺点分析​与对比

 2.1双向链表特点:

       1.每次在插入或删除某个节点时, 需要处理四个节点的引用, 而不是两个. 实现起来要困难一些
  2.相对于单向链表, 必然占用内存空间更大一些.
  3.既可以从头遍历到尾, 又可以从尾遍历到头

2.2双链表的优劣:

链表基础知识(二、双向链表头插、尾插、头删、尾删、查找、删除、插入),链表,数据结构,算法,c++,c语言,开发语言

2.3循环链表的优劣

循环表的好处主要包括以下几点:

  • 灵活性:循环链表可以从任何一个节点开始遍历,而且任何节点都可以作为头节点。这种灵活性使得循环链表在处理某些问题时比其他类型的链表更有优势。

  • 简化操作:在循环链表中,插入和删除操作相对简便,不需要对头尾节点

  • 行特殊处理。这种简便性可以提高算法的效率,降低编程的复杂性。

  • 适用于循环问题:循环链表可以实现循环访问,因此特别适用于解决涉及到循环问题的场景。

  • 便于实现队列数据结构:使用循环链表来实现队列数据结构可以简化操作,只需要维护一个尾节点指针即可,因为尾节点的后向节点就是队头节点。

  • 方便操作系统管理和应用程序运行:循环链表在操作系统和应用程序中也有广泛的应用。例如,操作系统可以利用循环链表来管理多个应用程序,通过循环遍历来给每个应用程序分配执行时间。

  • 可用于实现高级数据结构:循环双向链表可以用于实现高级数据结构,例如斐波那契堆(Fibonacci Heap),从而扩展了其在复杂算法和数据结构中的应用范围。

循环链表的缺点主要包括:

  • 内存占用更多:相比单链表,循环链表需要更多的内存空间来存储链接信息。这是因为循环链表中的每个节点都需要指向下一个节点,形成一个闭环,从而增加了内存开销。

  • 代码复杂度提高:循环链表的代码实现相比单链表要复杂一些。在插入、删除节点或遍历链表时,需要特别注意处理边界条件和循环结构,这可能会增加开发和调试的难度。

  • 潜在的死循环风险:如果循环链表中的链接关系出现错误,可能会导致死循环的情况发生。例如,在插入或删除节点时,如果没有正确更新链接关系,就可能导致链表无法正确遍历或陷入无限循环中。

2.4 顺序表和链表的优缺点分析​

链表基础知识(二、双向链表头插、尾插、头删、尾删、查找、删除、插入),链表,数据结构,算法,c++,c语言,开发语言

链表基础知识(二、双向链表头插、尾插、头删、尾删、查找、删除、插入),链表,数据结构,算法,c++,c语言,开发语言

三、带头双向循环链表增删改查实现

结构复杂,一般用在单独存储数据。实际中使用的链表数据结构,都是带头双向循环链表。另外这个结构虽然结构复杂,但是使用代码实现以后会发现结构会带来很多优势,实现反而简单了,后面我们代码实现了就知道了。

3.1SList.c

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


typedef int LTDataType;
//带哨兵位的头节点,第一个节点不存储有效数据,不能存储链表的长度
//typedef char LTDataType;
//typedef double LTDataType;无法存储链表长度


//Slist  双向链表
//DList  单链表
typedef struct ListNode
{
	struct ListNode* next;
	struct ListNode* prev;
	LTDataType data;
}ListNode;

ListNode* ListInit();
void ListDestory(ListNode* phead);
void ListPrint(ListNode* phead);

void ListPushBack(ListNode* phead, LTDataType x);
void ListPushFront(ListNode* phead, LTDataType x);
void ListPopFront(ListNode* phead);
void ListPopBack(ListNode* phead);

ListNode* ListFind(ListNode* phead, LTDataType x);
// pos位置之前插入x
void ListInsert(ListNode* pos, LTDataType x);
// 删除pos位置的值
void ListErase(ListNode* pos);

//bool ListEmpty(ListNode* phead);
//int ListSize(ListNode* phead);//链表的长度

3.2创建一个新节点、头节点

ListNode* BuyListNode(LTDataType x)
//创建一个新节点
{
	ListNode* newnode = malloc(sizeof(ListNode));
	//malloc分配大小,是一个ListNode结构体的大小
	newnode->data = x;//将新节点的data字段设置为参数x的值
	newnode->next = NULL;//给新节点的next存储的地址置空
	newnode->prev = NULL;//给新节点的prev存储的地址置空

	return newnode;
}
ListNode* ListInit()
//创建头节点
{
	ListNode* phead = BuyListNode(0);//phead指向了这个新创建的节点
	phead->next = phead; // 将phead的 next 指向其自身
	phead->prev = phead; // 将phead的 prev 指向其自身

	return phead;//返回phead,即头节点
}

3.3头插

在头节点后插入

链表基础知识(二、双向链表头插、尾插、头删、尾删、查找、删除、插入),链表,数据结构,算法,c++,c语言,开发语言

void ListPushFront(ListNode* phead, LTDataType x)
{
	assert(phead);//此节点不为空

	//顺序不能换
	ListNode* newnode = BuyListNode(x);
	newnode->next = phead->next;//存储phead的next,即下一个节点
	phead->next->prev = newnode;//下一个节点的prev指向newnode

	phead->next = newnode;//下一个节点的next 指向 newnode
	newnode->prev = phead;//newnode的prev 指向 phead
}

3.4尾插

在头节点前插入

链表基础知识(二、双向链表头插、尾插、头删、尾删、查找、删除、插入),链表,数据结构,算法,c++,c语言,开发语言

void ListPushBack(ListNode* phead, LTDataType x)
//x = 0,尾插
{
	assert(phead);//phead不为空
	ListNode* tail = phead->prev;//tail存储phead的prev中的地址,即最后一个节点
	ListNode* newnode = BuyListNode(x);//创建一个新节点
	
	tail->next = newnode;//上一个节点的next指向新节点
	newnode->prev = tail;//新节点的prev指向phead
	newnode->next = phead;//新节点的next指向phead
	phead->prev = newnode;//上一个节点的prev指向新节点
}

3.5头删

在头结点后删除

链表基础知识(二、双向链表头插、尾插、头删、尾删、查找、删除、插入),链表,数据结构,算法,c++,c语言,开发语言

void ListPopFront(ListNode* phead)
{
	assert(phead);//phead不为空
	assert(phead->next != phead);

	ListNode* first = phead->next;//先first存储phead的next中的地址,即phead的下一个节点
	ListNode* second = first->next;//再second存储下一个的节点的next中的地址,即下下个节点
	phead->next = second;//phead的next指向下下一个节点
	second->prev = phead;//下下一个节点的prev指向phead

	free(first);//下一个节点的空间被释放
	first = NULL;//first置空
}

3.6尾删

在头节点前删除

链表基础知识(二、双向链表头插、尾插、头删、尾删、查找、删除、插入),链表,数据结构,算法,c++,c语言,开发语言

void ListPopBack(ListNode* phead)
{
	assert(phead);//此节点不为空
	assert(phead->next != phead);

	ListNode* tail = phead->prev;//先tail存储phead的prev中的地址,即上一个节点
	ListNode* prev = tail->prev;//prev存储上一个节点的prev中的地址,即上上一个节点

	prev->next = phead;//上上个节点的next指向phead
	phead->prev = prev;//phead的prev指向上上个节点

	free(tail);//释放tail存储的空间,即上个节点的空间
	tail = NULL;//tail置空
	
}

3.7查找

ListNode* ListFind(ListNode* phead, LTDataType x)
{
	assert(phead);//此节点不为空
	ListNode* cur = phead->next;//cur存储phead的next中的地址,即下一个节点
	while (cur != phead)//不是头节点
	{
		if (cur->data == x)//如果是要查找的地址
		{
			return cur;//找到了返回这个地址
		}

		cur = cur->next;//指向下一个节点
	}

	return NULL;//没有找到,返回空
}

3.8删除

链表基础知识(二、双向链表头插、尾插、头删、尾删、查找、删除、插入),链表,数据结构,算法,c++,c语言,开发语言

// 删除pos位置的值
void ListErase(ListNode* pos)
{
	assert(pos);//此节点不为空

	ListNode* prev = pos->prev;//prev存储pos的prev中的地址,即上一个节点
	ListNode* next = pos->next;//next存储pos的next中的地址,即下一个节点
	prev->next = next;//上一个节点的next指向pos的next,即下一个节点
	next->prev = prev;//下一个节点的prev指向pos的prev,即上一个节点
	free(pos);//释放pos所在的空间
}

3.9插入

链表基础知识(二、双向链表头插、尾插、头删、尾删、查找、删除、插入),链表,数据结构,算法,c++,c语言,开发语言

// pos位置之前插入x
void ListInsert(ListNode* pos, LTDataType x)
{
	assert(pos);//此节点不为空
	ListNode* prev = pos->prev;//prev存储pos的prev中的地址,即pos上一个节点
	ListNode* newnode = BuyListNode(x);//创建一个新节点

	// prev newnode pos
	prev->next = newnode;//上一个节点的next指向newnode
	newnode->prev = prev;//新节点的prev指向上一个节点
	newnode->next = pos;//新节点的next指向pos
	pos->prev = newnode;//pos的prev指向newnode
}

3.10查找

ListNode* ListFind(ListNode* phead, LTDataType x)
{
	assert(phead);//此节点不为空
	ListNode* cur = phead->next;//cur存储phead的next中的地址,即下一个节点
	while (cur != phead)//不是头节点
	{
		if (cur->data == x)//如果是要查找的地址
		{
			return cur;//找到了返回这个地址
		}

		cur = cur->next;//指向下一个节点
	}

	return NULL;//没有找到,返回空
}

3.11打印链表

void ListPrint(ListNode* phead)
{
	assert(phead);//此节点不为空

	ListNode* cur = phead->next;//cur存储phead的next中的地址,即下一个节点
	while (cur != phead)//cur不是指向的自己(头节点)
	{								
		printf("%d ", cur->data);
		//打印cur存储的数据,即下一个地址的数据(因为有头节点)
		cur = cur->next;//指向下一个节点
	}
	printf("\n");
}

3.12销毁链表

链表基础知识(二、双向链表头插、尾插、头删、尾删、查找、删除、插入),链表,数据结构,算法,c++,c语言,开发语言

void ListDestory(ListNode* phead)
{
	assert(phead);//phead不为空
	ListNode* cur = phead->next;//cur存储phead的next中的地址,即下一个节点
	while (cur != phead)//cur指向的不是自己
	{
		ListNode* next = cur->next;//next指向下一个节点
		free(cur);//释放cur所在的空间
		cur = next;//cur指向下一个节点
	}

	free(phead);//释放头节点所在的空间
	phead = NULL;//头节点置空

}

四、简化链表,用插入和删除代替其他插入删除

void ListPushBack(ListNode* phead, LTDataType x)
{
	assert(phead);//phead不为空
	ListInsert(phead, x);//可以用插入来表示尾插
}

void ListPushFront(ListNode* phead, LTDataType x)
{
	assert(phead);//此节点不为空
	ListInsert(phead->next, x);//可以用插入来表示头插
}

void ListPopFront(ListNode* phead)
{
	assert(phead);//phead不为空
	ListErase(phead->next);//可以用删除表示头删
}

void ListPopBack(ListNode* phead)
{
	assert(phead);//此节点不为空
	ListErase(phead->prev);//可以用删除表示尾删
}

// pos位置之前插入x
void ListInsert(ListNode* pos, LTDataType x)
{
	assert(pos);//此节点不为空
	ListNode* prev = pos->prev;//prev存储pos的prev中的地址,即pos上一个节点
	ListNode* newnode = BuyListNode(x);//创建一个新节点

	// prev newnode pos
	prev->next = newnode;//上一个节点的next指向newnode
	newnode->prev = prev;//新节点的prev指向上一个节点
	newnode->next = pos;//新节点的next指向pos
	pos->prev = newnode;//pos的prev指向newnode
}

// 删除pos位置的值
void ListErase(ListNode* pos)
{
	assert(pos);//此节点不为空

	ListNode* prev = pos->prev;//prev存储pos的prev中的地址,即上一个节点
	ListNode* next = pos->next;//next存储pos的next中的地址,即下一个节点
	prev->next = next;//上一个节点的next指向pos的next,即下一个节点
	next->prev = prev;//下一个节点的prev指向pos的prev,即上一个节点
	free(pos);//释放pos所在的空间
}

五、SList.h

#include"List.h"

ListNode* BuyListNode(LTDataType x)
//创建一个新节点
{
	ListNode* newnode = malloc(sizeof(ListNode));
	//malloc分配大小,是一个ListNode结构体的大小
	newnode->data = x;//将新节点的data字段设置为参数x的值
	newnode->next = NULL;//给新节点的next存储的地址置空
	newnode->prev = NULL;//给新节点的prev存储的地址置空

	return newnode;
}

//void ListInit(ListNode* phead)
初始化了链表的新节点
//{
//	phead = BuyListNode(0);//phead指向了这个新创建的节点
//	phead->next = phead;//将phead的 next 指向其自身
//	phead->prev = phead;//将phead的 prev 指向其自身
//}

ListNode* ListInit()
//创建头节点
{
	ListNode* phead = BuyListNode(0);//phead指向了这个新创建的节点
	phead->next = phead; // 将phead的 next 指向其自身
	phead->prev = phead; // 将phead的 prev 指向其自身

	return phead;//返回phead,即头节点
}


void ListDestory(ListNode* phead)
{
	assert(phead);//phead不为空
	ListNode* cur = phead->next;//cur存储phead的next中的地址,即下一个节点
	while (cur != phead)//cur指向的不是自己
	{
		ListNode* next = cur->next;//next指向下一个节点
		free(cur);//释放cur所在的空间
		cur = next;//cur指向下一个节点
	}

	free(phead);//释放头节点所在的空间
	phead = NULL;//头节点置空

}

void ListPrint(ListNode* phead)
{
	assert(phead);//此节点不为空

	ListNode* cur = phead->next;//cur存储phead的next中的地址,即下一个节点
	while (cur != phead)//cur不是指向的自己(头节点)
	{								
		printf("%d ", cur->data);
		//打印cur存储的数据,即下一个地址的数据(因为有头节点)
		cur = cur->next;//指向下一个节点
	}
	printf("\n");
}


void ListPushBack(ListNode* phead, LTDataType x)
//x = 0,尾插
{
	//assert(phead);//phead不为空
	//ListNode* tail = phead->prev;//tail存储phead的prev中的地址,即最后一个节点
	//ListNode* newnode = BuyListNode(x);//创建一个新节点
	//
	//tail->next = newnode;//上一个节点的next指向新节点
	//newnode->prev = tail;//新节点的prev指向phead
	//newnode->next = phead;//新节点的next指向phead
	//phead->prev = newnode;//上一个节点的prev指向新节点
	ListInsert(phead, x);//可以用插入来表示尾插
}



//void ListPushFront(ListNode* phead, LTDataType x)
x = 0,头插
//{
//	assert(phead);//此节点不为空
//
//	ListNode* first = phead->next;//first存储phead的next中的地址,即下一个节点
//	ListNode* newnode = BuyListNode(x);//在x处创建一个新节点
//
//	// phead newnode first
//	phead->next = newnode;//下一个节点的next指向新节点
//	newnode->prev = phead;//新节点的prev指向此节点
//	newnode->next = first;//新节点的next指向此节点
//	first->prev = newnode;//下一个节点的prev指向新节点
//}

void ListPushFront(ListNode* phead, LTDataType x)
{
	assert(phead);//此节点不为空

	//顺序不能换
	ListNode* newnode = BuyListNode(x);
	newnode->next = phead->next;//存储phead的next,即下一个节点
	phead->next->prev = newnode;//下一个节点的prev指向newnode

	phead->next = newnode;//下一个节点的next 指向 newnode
	newnode->prev = phead;//newnode的prev 指向 phead
	//ListInsert(phead->next, x);//可以用插入来表示头插
}

void ListPopFront(ListNode* phead)
{
	assert(phead);//phead不为空
	assert(phead->next != phead);

	ListNode* first = phead->next;//先first存储phead的next中的地址,即phead的下一个节点
	ListNode* second = first->next;//再second存储下一个的节点的next中的地址,即下下个节点
	phead->next = second;//phead的next指向下下一个节点
	second->prev = phead;//下下一个节点的prev指向phead

	free(first);//下一个节点的空间被释放
	first = NULL;//first置空

	//ListErase(phead->next);//可以用删除表示头删
}

void ListPopBack(ListNode* phead)
{
	assert(phead);//此节点不为空
	/*assert(phead->next != phead);

	ListNode* tail = phead->prev;//先tail存储phead的prev中的地址,即上一个节点
	ListNode* prev = tail->prev;//prev存储上一个节点的prev中的地址,即上上一个节点

	prev->next = phead;//上上个节点的next指向phead
	phead->prev = prev;//phead的prev指向上上个节点

	free(tail);//释放tail存储的空间,即上个节点的空间
	tail = NULL;//tail置空
	*/

	ListErase(phead->prev);//可以用删除表示尾删
}

ListNode* ListFind(ListNode* phead, LTDataType x)
{
	assert(phead);//此节点不为空
	ListNode* cur = phead->next;//cur存储phead的next中的地址,即下一个节点
	while (cur != phead)//不是头节点
	{
		if (cur->data == x)//如果是要查找的地址
		{
			return cur;//找到了返回这个地址
		}

		cur = cur->next;//指向下一个节点
	}

	return NULL;//没有找到,返回空
}

// pos位置之前插入x
void ListInsert(ListNode* pos, LTDataType x)
{
	assert(pos);//此节点不为空
	ListNode* prev = pos->prev;//prev存储pos的prev中的地址,即pos上一个节点
	ListNode* newnode = BuyListNode(x);//创建一个新节点

	// prev newnode pos
	prev->next = newnode;//上一个节点的next指向newnode
	newnode->prev = prev;//新节点的prev指向上一个节点
	newnode->next = pos;//新节点的next指向pos
	pos->prev = newnode;//pos的prev指向newnode
}

// 删除pos位置的值
void ListErase(ListNode* pos)
{
	assert(pos);//此节点不为空

	ListNode* prev = pos->prev;//prev存储pos的prev中的地址,即上一个节点
	ListNode* next = pos->next;//next存储pos的next中的地址,即下一个节点
	prev->next = next;//上一个节点的next指向pos的next,即下一个节点
	next->prev = prev;//下一个节点的prev指向pos的prev,即上一个节点
	free(pos);//释放pos所在的空间
}

六、Test.c

#include"List.h"

void TestList1()
{
	ListNode* plist = ListInit();//plist为头节点
	ListPushBack(plist, 1);
	ListPushBack(plist, 2);
	ListPushBack(plist, 3);
	ListPushBack(plist, 4);
	ListPrint(plist);

	ListPushFront(plist, 0);
	ListPushBack(plist, -1);
	ListPrint(plist);

	/*ListPopFront(plist);
	ListPopFront(plist);
	ListPopFront(plist);
	ListPrint(plist);

	ListPopBack(plist);
	ListPrint(plist);

	ListDestory(plist);*/

}

int main()
{
	TestList1();

	return 0;
}

链表基础知识(二、双向链表头插、尾插、头删、尾删、查找、删除、插入),链表,数据结构,算法,c++,c语言,开发语言

今天就先到这了!!!

链表基础知识(二、双向链表头插、尾插、头删、尾删、查找、删除、插入),链表,数据结构,算法,c++,c语言,开发语言

看到这里了还不给博主扣个:
⛳️ 点赞☀️收藏 ⭐️ 关注!

你们的点赞就是博主更新最大的动力!
有问题可以评论或者私信呢秒回哦。文章来源地址https://www.toymoban.com/news/detail-761814.html

到了这里,关于链表基础知识(二、双向链表头插、尾插、头删、尾删、查找、删除、插入)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

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

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

相关文章

  • 链表基础知识详解(非常详细简单易懂)

          链表作为 C 语言中一种基础的数据结构,在平时写程序的时候用的并不多,但在操作系统里面使用的非常多。不管是RTOS还是Linux等使用非常广泛,所以必须要搞懂链表,链表分为单向链表和双向链表,单向链表很少用,使用最多的还是双向链表。单向链表懂了双向链表

    2024年02月03日
    浏览(40)
  • DS作业0-C语言基础知识复习(含指针与链表)

    判断题: 1.直接访问就是直接利用变量的地址直接进行访问。T 2.可以用一个指针变量指向一个函数,然后通过该指针变量调用此函数。T 3.int (*p)[4]它表示p是一个指针数组,它包含4个指针变量元素。F (是int类型数组,里面有4个指针变量元素) 4.结构体变量可以作数组元素。

    2024年02月04日
    浏览(45)
  • 【数据结构】单链表——单链表的定义及基本操作的实现(头插、尾插、头删、尾删、任意位置的插入与删除)

    🧑‍💻作者: @情话0.0 📝专栏:《数据结构》 👦个人简介:一名双非编程菜鸟,在这里分享自己的编程学习笔记,欢迎大家的指正与点赞,谢谢!   顺序表可以随时存取表中的任意一个元素,它的存储位置可以用一个简单直观的公式表示,但是插入和删除操作需要移动

    2024年02月19日
    浏览(205)
  • 探索树形数据结构,通识树、森林与二叉树的基础知识(专有名词),进一步利用顺序表和链表表示、遍历和线索树形结构

      结点之间有分支,具有层次关系 树的定义 : 树 (tree)是n(n≥0)个有限集。 若n = 0,则称为空树; 若n 0,则它满足如下两个条件: 有且仅有一个特定的称为根(Root)的结点; 其余结点可分为m(m≥0)个互不相交的有限集T1,T2,T3,.....,Tm,其中每一个集合本身又是一棵树,并称为根的

    2024年02月01日
    浏览(53)
  • 算法竞赛基础:C++双向链表的结构和实现(普通链表、List、静态链表)

    本文将会介绍在算法竞赛中双向链表的几种使用方式,适合有一定基础的人阅读。 一般来说,普通的链表结构是这样的: next指针指向下一个链表,这样的结构只能够支持单向查询。 双向链表,顾名思义,就是可以支持双向的访问和查询。 也就是这样的: 这种链表为访问前

    2024年01月24日
    浏览(42)
  • 如何给新链表的tail尾结点尾插?

    没有哨兵卫:  有哨兵卫:

    2024年02月09日
    浏览(34)
  • 数据结构:链表基础OJ练习+带头双向循环链表的实现

    目录 一.leetcode剑指 Offer II 027. 回文链表 1.问题描述 2.问题分析与求解 (1) 快慢指针法定位链表的中间节点 (2) 将链表后半部分进行反转 附:递归法反转链表 (3) 双指针法判断链表是否回文 二.带头双向循环链表的实现 1.头文件 2.节点内存申请接口和链表初始化接口 3.链表的打

    2024年02月02日
    浏览(51)
  • 【STM32】基础知识 第五课 C 语言基础知识

    stdint.h 是从 C99 中引进的一个标准 C 库的文件. 路径: “D:MDK5.34ARMARMCCinclude” 运算符 含义 运算符 含义 按位与 ~ 按位取反 | 按位或 左移 ^ 按位异或 右移 按位与: num1 运算符 num2 结果 0 0 0 1 0 0 0 1 0 1 1 1 按位或: num1 运算符 num2 结果 0 | 0 0 1 | 0 1 0 | 1 1 1 | 1 1 按位异或: num1 运算符

    2024年02月13日
    浏览(74)
  • 数字电路基础知识系列(六)之LC滤波器的基础知识

    LC滤波器,是指将电感(L)与电容器 ©进行组合设计构成的滤波电路,可去除或通过特定频率的无源器件。电容器具有隔直流通交流,且交流频率越高越容易通过的特性。而电感则具有隔交流通直流,且交流频率越高越不易通过的特性。因此,电容器和电感是特性完全相反的被

    2024年02月03日
    浏览(89)
  • Unity | Shader基础知识(第九集:shader常用单词基础知识速成)

    目录 一、顶点(Vertex)和法线(Normal) 二、UV信息 三、 基础数据种类 1 基础数据种类 2 基础数据数组 3 基础数据数组的赋值 4 对数据数组的调用 四、 基础矩阵 1 基础矩阵种类  2 对矩阵数组的调用 2.1对一个数据的调用  2.2对多个数据的调用  2.3对数据的赋值 五、基础纹理种

    2024年02月01日
    浏览(73)

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

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

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

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

二维码1

领取红包

二维码2

领红包