【数据结构与算法】单向链表

【数据结构与算法】单向链表


文章目录

  • 【数据结构与算法】单向链表
  • 前言
  • 一、单向链表初始化
  • 二、单向链表插入与遍历
  • 三、单向链表的删除与清空
  • 四、单向链表返回长度以及销毁
  • 五、完整代码
  • 六、单向链表企业版
  • 总结


前言

本篇文章就单向链表初始化,插入遍历功能,链表删除,清空,返回长度以及销毁。单向链表企业版初始化,插入,遍历,删除和销毁实现。


一、单向链表初始化

单向链表初始化

//结点结构体
struct LinkNode
{
	//数据域
	void* data;
	//指针域
	struct LinkNode* next;

};

//链表结构体
struct LList
{
	//头结点
	struct LinkNode pHeader;
	//链表长度
	int m_size;
};
typedef void* LinkList;

//初始化链表
LinkList init_LinkList()
{
	struct LList* myList = malloc(sizeof(struct LList));

	if (myList == NULL)
	{
		return NULL;
	}
	
	myList->pHeader.data = NULL;
	myList->pHeader.next = NULL;
	myList->m_size = 0;

	return myList;
}

二、单向链表插入与遍历

插入链表
在这里插入图片描述

//插入链表
void insert_LinkList(LinkList list, int pos, void* data)
{
	if (list == NULL)
	{
		return;
	}
	if (data == NULL)
	{
		return;
	}
	//将list还原成 struct LList 数据类型
	struct LList* myList = list;
	if (pos<0 || pos >myList->m_size)
	{
		//无效位置 强制做尾插
		pos = myList->m_size;
	}
	//找到插入节点的前驱节点位置
	struct LinkNode* pCurrent = &myList->pHeader;

	for (int i = 0; i < pos; i++)
	{
		pCurrent = pCurrent->next;
	}
	//pCurrent 要插入节点的前驱
	//创建新节点
	struct LinkNode* newNode = malloc(sizeof(struct LinkNode));
	newNode->data = data;
	newNode->next = NULL;

	//建立节点关系
	newNode->next = pCurrent->next;
	pCurrent->next = newNode;

	//更新链表长度
	myList->m_size++;
}

遍历链表

//遍历链表
void foreach_LinkList(LinkList list, void(*myForeach)(void*))
{
	if (list == NULL)
	{
		return;
	}

	struct LList* mylist = list;

	struct LinkNode* pCurrent = mylist->pHeader.next;

	for (int i = 0; i < mylist->m_size; i++)
	{
		myForeach(pCurrent->data);
		pCurrent = pCurrent->next;
	}
}

测试:

//测试
struct Person
{
	char name[64];
	int age;
};

void myPrintPerson(void* data)
{
	struct Person* p = data;
	printf("姓名:%s, 年龄: %d\n", p->name, p->age);
}

void test01()
{
	//准备数据
	struct Person p1 = { "亚瑟", 18 };
	struct Person p2 = { "妲己", 20 };
	struct Person p3 = { "安琪拉", 19 };
	struct Person p4 = { "凯", 21 };
	struct Person p5 = { "孙悟空", 999 };
	struct Person p6 = { "李白", 999 };
	//初始化链表
	LinkList mylist = init_LinkList();
	
	//插入数据
	insert_LinkList(mylist, 0, &p1);
	insert_LinkList(mylist, 0, &p2);
	insert_LinkList(mylist, -1, &p3);
	insert_LinkList(mylist, 0, &p4);
	insert_LinkList(mylist, 1, &p5);
	insert_LinkList(mylist, 0, &p6);

	//遍历
	foreach_LinkList(mylist, myPrintPerson);

	
}

int main() {

	test01();

	return 0;
}

在这里插入图片描述


三、单向链表的删除与清空

在这里插入图片描述

按位置删除

//删除链表  按位置
void removeByPos_LinkList(LinkList list, int pos)
{
	if (list == NULL)
	{
		return;
	}
	struct LList* mylist = list;
	if (pos< 0 || pos >mylist->m_size - 1)
	{
		return;
	}

	//找到待删除节点的前驱节点
	struct LinkNode* pCurrent = &mylist->pHeader;
	for (int i = 0; i < pos; i++)
	{
		pCurrent = pCurrent->next;
	}

	//记录待删除的节点
	struct LinkNode* pDel = pCurrent->next;
	//重新建立节点关系
	pCurrent->next = pDel->next;
	free(pDel);
	pDel = NULL;

	//更新链表长度
	mylist->m_size--;
}

按值删除

//按照值删除链表
void removeByValue_LinkList(LinkList list, void* data, int(*myCompare)(void*, void*))
{
	if (list == NULL)
	{
		return;
	}
	if (data == NULL)
	{
		return;
	}
	struct LList* mylist = list;

	//创建两个辅助指针
	struct LinkNode* pPrev = &mylist->pHeader;
	struct LinkNode* pCurrent = pPrev->next;

	for (int i = 0; i < mylist->m_size; i++)
	{
		//pCurrent->data data 将两个指针比较利用回调 交给用户
		if (myCompare(pCurrent->data, data))
		{
			pPrev->next = pCurrent->next;
			free(pCurrent);
			pCurrent = NULL;

			mylist->m_size--;
			break;
		}
		//辅助指针后移
		pPrev = pCurrent;
		pCurrent = pCurrent->next;
	}
}

测试:

//测试
struct Person
{
	char name[64];
	int age;
};

void myPrintPerson(void* data)
{
	struct Person* p = data;
	printf("姓名:%s, 年龄: %d\n", p->name, p->age);
}

int myComparePerson(void* data1, void* data2)
{
	struct Person* p1 = data1;
	struct Person* p2 = data2;

	return strcmp(p1->name, p2->name) == 0 && p1->age == p2->age;
}

void test01()
{
	//准备数据
	struct Person p1 = { "亚瑟", 18 };
	struct Person p2 = { "妲己", 20 };
	struct Person p3 = { "安琪拉", 19 };
	struct Person p4 = { "凯", 21 };
	struct Person p5 = { "孙悟空", 999 };
	struct Person p6 = { "李白", 999 };
	//初始化链表
	LinkList mylist = init_LinkList();
	
	//插入数据
	insert_LinkList(mylist, 0, &p1);
	insert_LinkList(mylist, 0, &p2);
	insert_LinkList(mylist, -1, &p3);
	insert_LinkList(mylist, 0, &p4);
	insert_LinkList(mylist, 1, &p5);
	insert_LinkList(mylist, 0, &p6);

	//遍历
	foreach_LinkList(mylist, myPrintPerson);

	//测试删除
	removeByPos_LinkList(mylist, 4);

	printf("------------------\n");
	foreach_LinkList(mylist, myPrintPerson);
	struct Person p = { "孙悟空", 999 };
	removeByValue_LinkList(mylist, &p, myComparePerson);

	printf("------------------\n");
	foreach_LinkList(mylist, myPrintPerson);

	
}

在这里插入图片描述

清空链表

//清空链表
void clear_LinkList(LinkList list)
{
	if (list == NULL)
	{
		return;
	}
	struct LList* mylist = list;
	struct LinkNode* pCurrent = mylist->pHeader.next;

	for (int i = 0; i < mylist->m_size; i++)
	{
		struct LinkNode* pNext = pCurrent->next;
		free(pCurrent);
		pCurrent = pNext;
	}
	mylist->pHeader.next = NULL;
	mylist->m_size = 0;
}


四、单向链表返回长度以及销毁

返回链表长度

//返回链表长度
int size_LinkList(LinkList list)
{
	if (list == NULL)
	{
		return -1;
	}
	struct LList* mylist = list;

	return mylist->m_size;
}

销毁链表

//销毁链表
void destroy_LinkList(LinkList list)
{
	if (list == NULL)
	{
		return;
	}
	//清空链表
	clear_LinkList(list);
	free(list);
	list = NULL;
}

测试:

//测试
struct Person
{
	char name[64];
	int age;
};

void myPrintPerson(void* data)
{
	struct Person* p = data;
	printf("姓名:%s, 年龄: %d\n", p->name, p->age);
}

int myComparePerson(void* data1, void* data2)
{
	struct Person* p1 = data1;
	struct Person* p2 = data2;

	return strcmp(p1->name, p2->name) == 0 && p1->age == p2->age;
}

void test01()
{
	//准备数据
	struct Person p1 = { "亚瑟", 18 };
	struct Person p2 = { "妲己", 20 };
	struct Person p3 = { "安琪拉", 19 };
	struct Person p4 = { "凯", 21 };
	struct Person p5 = { "孙悟空", 999 };
	struct Person p6 = { "李白", 999 };
	//初始化链表
	LinkList mylist = init_LinkList();
	
	//插入数据
	insert_LinkList(mylist, 0, &p1);
	insert_LinkList(mylist, 0, &p2);
	insert_LinkList(mylist, -1, &p3);
	insert_LinkList(mylist, 0, &p4);
	insert_LinkList(mylist, 1, &p5);
	insert_LinkList(mylist, 0, &p6);

	//遍历
	foreach_LinkList(mylist, myPrintPerson);
	printf("链表长度为:%d\n", size_LinkList(mylist));


	//测试删除
	removeByPos_LinkList(mylist, 4);

	printf("------------------\n");
	foreach_LinkList(mylist, myPrintPerson);
	printf("链表长度为:%d\n", size_LinkList(mylist));

	struct Person p = { "孙悟空", 999 };
	removeByValue_LinkList(mylist, &p, myComparePerson);

	printf("------------------\n");
	foreach_LinkList(mylist, myPrintPerson);

	printf("链表长度为:%d\n", size_LinkList(mylist));


	//测试清空
	clear_LinkList(mylist);

	//返回链表长度
	printf("链表长度为:%d\n", size_LinkList(mylist));

	//销毁
	destroy_LinkList(mylist);
	mylist = NULL;

	printf("链表长度为:%d\n", size_LinkList(mylist));

}

在这里插入图片描述


五、完整代码

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

//结点结构体
struct LinkNode
{
	//数据域
	void* data;
	//指针域
	struct LinkNode* next;

};

//链表结构体
struct LList
{
	//头结点
	struct LinkNode pHeader;
	//链表长度
	int m_size;
};
typedef void* LinkList;

//初始化链表
LinkList init_LinkList()
{
	struct LList* myList = malloc(sizeof(struct LList));

	if (myList == NULL)
	{
		return NULL;
	}
	
	myList->pHeader.data = NULL;
	myList->pHeader.next = NULL;
	myList->m_size = 0;

	return myList;
}

//插入链表
void insert_LinkList(LinkList list, int pos, void* data)
{
	if (list == NULL)
	{
		return;
	}
	if (data == NULL)
	{
		return;
	}
	//将list还原成 struct LList 数据类型
	struct LList* myList = list;
	if (pos<0 || pos >myList->m_size)
	{
		//无效位置 强制做尾插
		pos = myList->m_size;
	}
	//找到插入节点的前驱节点位置
	struct LinkNode* pCurrent = &myList->pHeader;

	for (int i = 0; i < pos; i++)
	{
		pCurrent = pCurrent->next;
	}
	//pCurrent 要插入节点的前驱
	//创建新节点
	struct LinkNode* newNode = malloc(sizeof(struct LinkNode));
	newNode->data = data;
	newNode->next = NULL;

	//建立节点关系
	newNode->next = pCurrent->next;
	pCurrent->next = newNode;

	//更新链表长度
	myList->m_size++;
}

//遍历链表
void foreach_LinkList(LinkList list, void(*myForeach)(void*))
{
	if (list == NULL)
	{
		return;
	}

	struct LList* mylist = list;

	struct LinkNode* pCurrent = mylist->pHeader.next;

	for (int i = 0; i < mylist->m_size; i++)
	{
		myForeach(pCurrent->data);
		pCurrent = pCurrent->next;
	}
}

//删除链表  按位置
void removeByPos_LinkList(LinkList list, int pos)
{
	if (list == NULL)
	{
		return;
	}
	struct LList* mylist = list;
	if (pos< 0 || pos >mylist->m_size - 1)
	{
		return;
	}

	//找到待删除节点的前驱节点
	struct LinkNode* pCurrent = &mylist->pHeader;
	for (int i = 0; i < pos; i++)
	{
		pCurrent = pCurrent->next;
	}

	//记录待删除的节点
	struct LinkNode* pDel = pCurrent->next;
	//重新建立节点关系
	pCurrent->next = pDel->next;
	free(pDel);
	pDel = NULL;

	//更新链表长度
	mylist->m_size--;
}

//按照值删除链表
void removeByValue_LinkList(LinkList list, void* data, int(*myCompare)(void*, void*))
{
	if (list == NULL)
	{
		return;
	}
	if (data == NULL)
	{
		return;
	}
	struct LList* mylist = list;

	//创建两个辅助指针
	struct LinkNode* pPrev = &mylist->pHeader;
	struct LinkNode* pCurrent = pPrev->next;

	for (int i = 0; i < mylist->m_size; i++)
	{
		//pCurrent->data data 将两个指针比较利用回调 交给用户
		if (myCompare(pCurrent->data, data))
		{
			pPrev->next = pCurrent->next;
			free(pCurrent);
			pCurrent = NULL;

			mylist->m_size--;
			break;
		}
		//辅助指针后移
		pPrev = pCurrent;
		pCurrent = pCurrent->next;

	}

}

//清空链表
void clear_LinkList(LinkList list)
{
	if (list == NULL)
	{
		return;
	}
	struct LList* mylist = list;
	struct LinkNode* pCurrent = mylist->pHeader.next;

	for (int i = 0; i < mylist->m_size; i++)
	{
		struct LinkNode* pNext = pCurrent->next;
		free(pCurrent);
		pCurrent = pNext;
	}
	mylist->pHeader.next = NULL;
	mylist->m_size = 0;
}

//返回链表长度
int size_LinkList(LinkList list)
{
	if (list == NULL)
	{
		return -1;
	}
	struct LList* mylist = list;

	return mylist->m_size;
}

//销毁链表
void destroy_LinkList(LinkList list)
{
	if (list == NULL)
	{
		return;
	}
	//清空链表
	clear_LinkList(list);
	free(list);
	list = NULL;
}




//测试
struct Person
{
	char name[64];
	int age;
};

void myPrintPerson(void* data)
{
	struct Person* p = data;
	printf("姓名:%s, 年龄: %d\n", p->name, p->age);
}

int myComparePerson(void* data1, void* data2)
{
	struct Person* p1 = data1;
	struct Person* p2 = data2;

	return strcmp(p1->name, p2->name) == 0 && p1->age == p2->age;
}

void test01()
{
	//准备数据
	struct Person p1 = { "亚瑟", 18 };
	struct Person p2 = { "妲己", 20 };
	struct Person p3 = { "安琪拉", 19 };
	struct Person p4 = { "凯", 21 };
	struct Person p5 = { "孙悟空", 999 };
	struct Person p6 = { "李白", 999 };
	//初始化链表
	LinkList mylist = init_LinkList();
	
	//插入数据
	insert_LinkList(mylist, 0, &p1);
	insert_LinkList(mylist, 0, &p2);
	insert_LinkList(mylist, -1, &p3);
	insert_LinkList(mylist, 0, &p4);
	insert_LinkList(mylist, 1, &p5);
	insert_LinkList(mylist, 0, &p6);

	//遍历
	foreach_LinkList(mylist, myPrintPerson);
	printf("链表长度为:%d\n", size_LinkList(mylist));


	//测试删除
	removeByPos_LinkList(mylist, 4);

	printf("------------------\n");
	foreach_LinkList(mylist, myPrintPerson);
	printf("链表长度为:%d\n", size_LinkList(mylist));

	struct Person p = { "孙悟空", 999 };
	removeByValue_LinkList(mylist, &p, myComparePerson);

	printf("------------------\n");
	foreach_LinkList(mylist, myPrintPerson);

	printf("链表长度为:%d\n", size_LinkList(mylist));


	//测试清空
	clear_LinkList(mylist);

	//返回链表长度
	printf("链表长度为:%d\n", size_LinkList(mylist));

	//销毁
	destroy_LinkList(mylist);
	mylist = NULL;

	printf("链表长度为:%d\n", size_LinkList(mylist));

}

int main() {

	test01();

	return 0;
}

六、单向链表企业版

完整代码

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

//节点结构体
struct LinkNode
{
	//只维护指针域
	struct LinkNode* next;
};

//链表结构体
struct LList
{
	struct LinkNode pHeader;
	int m_Size;

};

typedef void* LinkList;

//初始化链表
LinkList init_LinkList()
{
	struct LList* myList = malloc(sizeof(struct LList));

	if (myList == NULL)
	{
		return NULL;
	}

	myList->pHeader.next = NULL;
	myList->m_Size = 0;
}


//插入
void  insert_LinkList(LinkList list, int pos, void* data)
{
	if (list == NULL)
	{
		return;
	}
	if (data == NULL)
	{
		return;
	}

	struct LList* myList = list;
	if (pos <0 || pos >myList->m_Size - 1)
	{
		//无效位置进行尾插
		pos = myList->m_Size;
	}

	//用户数据的前4个字节 由我们来使用
	struct LinkNode* myNode = data;

	//找插入节点的前驱节点
	struct LinkNode* pCurrent = &myList->pHeader;

	for (int i = 0; i < pos; i++)
	{
		pCurrent = pCurrent->next;
	}
	//pCurrent是前驱节点位置

	//更新指针指向
	myNode->next = pCurrent->next;
	pCurrent->next = myNode;

	//更新链表长度
	myList->m_Size++;
}

//遍历链表
void foreach_LinkList(LinkList list, void(*myForeach)(void*))
{
	if (list == NULL)
	{
		return;
	}
	struct LList* myList = list;
	struct LinkNode* myNode = myList->pHeader.next;

	for (int i = 0; i < myList->m_Size; i++)
	{
		myForeach(myNode);
		myNode = myNode->next;
	}
}

//删除节点 按位置删除
void removeByPos_LinktList(LinkList list, int pos)
{
	if (list == NULL)
	{
		return;
	}
	struct LList* mylist = list;

	if (pos< 0 || pos>mylist->m_Size - 1)
	{
		return;
	}

	//找待删除节点的前驱节点
	struct LinkNode* pCurrent = &mylist->pHeader; 
	for (int i = 0; i < pos; i++)
	{
		pCurrent = pCurrent->next;
	}

	//记录待删除结点
	struct LinkNode* pDel = pCurrent->next;

	//更改指针指向
	pCurrent->next = pDel->next;

	//free(pDel); //数据是用户管理开辟的,用户管理释放

	//更新长度
	mylist->m_Size--;
}

//销毁链表
void destroy_LinkList(LinkList list)
{
	if (list == NULL)
	{
		return;
	}
	free(list);
	list = NULL;
}




//测试
struct Person
{
	void* node;
	char name[64];
	int age;
};

void myPrintPerson(void* data)
{
	struct Person* p = data;
	printf("姓名: %s 年龄: %d \n", p->name, p->age);
}


void test01()
{
	//初始化链表
	LinkList mylist = init_LinkList();
	
	//创建数据
	struct Person p1 = { NULL,"aaa", 10 };
	struct Person p2 = { NULL,"bbb", 20 };
	struct Person p3 = { NULL,"ccc", 30 };
	struct Person p4 = { NULL,"ddd", 40 };
	struct Person p5 = { NULL,"eee", 50 };

	//插入节点
	insert_LinkList(mylist, 0, &p1);
	insert_LinkList(mylist, 0, &p2);
	insert_LinkList(mylist, 1, &p3);
	insert_LinkList(mylist, -1, &p4);
	insert_LinkList(mylist, 0, &p5);

	//遍历链表
	// eee bbb  ccc aaa ddd
	foreach_LinkList(mylist, myPrintPerson);

	//删除 aaa
	removeByPos_LinktList(mylist, 3);
	printf("-----------------------\n");
	foreach_LinkList(mylist, myPrintPerson);

	//销毁数组
	destroy_LinkList(mylist);
	mylist = NULL;

}


int main() {
	test01();


	return 0;
}

总结

到这里这篇文章的内容就结束了,谢谢大家的观看,如果有好的建议可以留言喔,谢谢大家啦!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/873319.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Windows terminal使用说明

1 terminal基本介绍 1 下载 从微软商店上下载的方式网速比较慢&#xff0c;一种直接的方式是直接用命令行运行命令 winget install --idMicrosoft.WindowsTerminal -e# Window Terminal 安装以及使用(2021最新) 2 ssh配置 # 使用Windows Terminal进行SSH登录 1 通过label…

如何做好网络安全

随着互联网技术的飞速发展&#xff0c;网站已成为企业对外展示、交流和服务的重要窗口。然而&#xff0c;随之而来的网站安全问题也日益凸显&#xff0c;给企业的业务发展和用户数据安全带来了巨大威胁。因此&#xff0c;高度重视网站安全已成为网络安全的首要任务。今天我们就…

三相直流无刷电机(BLDC)控制算法实现:BLDC有感启动算法思路分析

一枚从事路径规划算法、运动控制算法、BLDC/FOC电机控制算法、工控、物联网工程师&#xff0c;爱吃土豆。如有需要技术交流或者需要方案帮助、需求&#xff1a;以下为联系方式—V 方案1&#xff1a;通过霍尔传感器IO中断触发换相 1.1 整体执行思路 霍尔传感器U、V、W三相通…

2024国赛数学建模A题B题C题D题E题思路资料模型

开始在本帖实时更新2024国赛数学建模赛题思路代码&#xff0c;文章末尾获取&#xff01; 持续更新参考思路

FPGA编译与部署方法全方位介绍

FPGA编译与部署是FPGA开发中的核心环节&#xff0c;涉及从代码编写、调试到将设计部署到FPGA硬件的全过程。这个流程需要经过创建项目、编写FPGA VI、模拟调试、编译生成比特流文件&#xff0c;最后将设计部署到硬件上运行。编译的特点在于并行执行能力、定制化硬件实现以及复杂…

string字符会调用new分配堆内存吗

gcc的string默认大小是32个字节&#xff0c;字符串小于等于15直接保存在栈上&#xff0c;超过之后才会使用new分配。

『功能项目』战士的平A特效【35】

我们打开上一篇34武器的切换实例的项目&#xff0c; 本章要做的事情是在战士的每次按A键时在指定位置生成一个平A特效 首先将之前下载的技能拖拽至场景中 完全解压缩后重命名为AEffect 拖拽至预制体文件夹 进入主角动画的战士动画层级 双击第一次攻击 选择Animation 创建事件 …

七. 部署YOLOv8检测器-affine-transformation

目录 前言0. 简述1. 案例运行2. 补充说明3. 代码分析3.1 main.cpp3.2 preprocess.cu 结语下载链接参考 前言 自动驾驶之心推出的 《CUDA与TensorRT部署实战课程》&#xff0c;链接。记录下个人学习笔记&#xff0c;仅供自己参考 本次课程我们来学习课程第七章—部署YOLOv8检测器…

python文件自动化(4)

接上节课内容&#xff0c;在开始正式移动文件到目标文件夹之前&#xff0c;我们需要再思考一个问题。在代码运行之前&#xff0c;阿文的下载文件夹里已经存在一些分类文件夹了&#xff0c;比如图例中“PDF文件”这个文件夹就是已经存在的。这样的话&#xff0c;在程序运行时&am…

SprinBoot+Vue校园数字化图书馆系统的设计与实现

目录 1 项目介绍2 项目截图3 核心代码3.1 Controller3.2 Service3.3 Dao3.4 application.yml3.5 SpringbootApplication3.5 Vue 4 数据库表设计5 文档参考6 计算机毕设选题推荐7 源码获取 1 项目介绍 博主个人介绍&#xff1a;CSDN认证博客专家&#xff0c;CSDN平台Java领域优质…

FreeRTOS任务调度(抢占式、协作式、时间片轮转)

任务调度 文章目录 任务调度前言一、协作式二、时间片轮转三、抢占式总结 前言 FreeRTOS 是一个开源的实时操作系统&#xff0c;它支持多种调度策略&#xff0c;包括协作式&#xff08;cooperative&#xff09;和抢占式&#xff08;preemptive&#xff09;调度。 一、协作式 …

堆排序Java

思路 这个代码还不错 https://blog.csdn.net/weixin_51609435/article/details/122982075 就是从下往上进行调整 1. 如何将数组映射成树 对于下面这颗树&#xff0c;原来的数组是&#xff1a; 好&#xff0c;如果调整的话&#xff0c;我们第一个应该调整的是最下边&#x…

压缩文件隐写

1、伪加密 &#xff08;1&#xff09;zip伪加密 考点&#xff1a;winhex打开压缩包&#xff1b;搜索504b0102(注意不是文件头部&#xff1b;zip文件头部伪504b0304);从50开始&#xff0c;往后面数第9&#xff0c;10个字符为加密字符&#xff0c;将其设置为0000即可变为无加密状…

JAVAEE初阶第七节(中)——物理原理与TCP_IP

系列文章目录 JAVAEE初阶第七节&#xff08;中&#xff09;——物理原理与TCP_IP 文章目录 系列文章目录JAVAEE初阶第七节&#xff08;中&#xff09;——物理原理与TCP_IP 一.应用层重点协议&#xff09;1. DNS2 .NAT3. NAT IP转换过程 4 .NAPT5. NAT技术的缺陷6. HTTP/HTTPS…

野火霸天虎V2学习记录

文章目录 嵌入式开发常识汇总1、嵌入式Linux和stm32之间的区别和联系2、stm32程序下载方式3、Keil5安装芯片包4、芯片封装种类5、STM32命名6、数据手册和参考手册7、什么是寄存器、寄存器映射和内存映射8、芯片引脚顺序9、stm32芯片里有什么10、存储器空间的划分11、如何理解寄…

如何部署Vue+Springboot项目

很多同学在项目上线的部署遇到困难&#xff0c;不懂得怎么部署项目&#xff0c;本文将会带大家手把手从前端部署、java部署来教会大家。 如果项目涉及到了docker相关中间件的环境配置&#xff0c;请参看&#xff1a;https://blog.csdn.net/weixin_73195042/article/details/13…

C#发送正文带图片带附件的邮件

1&#xff0c;开启服务&#xff0c;获取授权码。以QQ邮箱为例&#xff1a; 点击管理服务&#xff0c;进入账号与安全页面 2&#xff0c;相关设置参数&#xff0c;以QQ邮箱为例&#xff1a; 登录时&#xff0c;请在第三方客户端的密码输入框里面填入授权码进行验证。&#xff0…

解决 Ant Design Vue Upload 组件在苹果手机上只能拍照无法选择相册的问题

最近上线发现了这个问题&#xff0c;看别的文档改了很多属性也不行&#xff0c;发现element组件就可以&#xff0c;对比之后就知道问题所在。 原因&#xff1a; 默认情况下&#xff0c;iOS 设备会将 <input type"file"> 的 capture 属性设置为 true&#xff0…

[数据集][目标检测]电动车头盔佩戴检测数据集VOC+YOLO格式4235张5类别

数据集格式&#xff1a;Pascal VOC格式YOLO格式(不包含分割路径的txt文件&#xff0c;仅仅包含jpg图片以及对应的VOC格式xml文件和yolo格式txt文件) 图片数量(jpg文件个数)&#xff1a;4235 标注数量(xml文件个数)&#xff1a;4235 标注数量(txt文件个数)&#xff1a;4235 标注…

python 正则表达式“.*”和“.*? ”的区别

“.*”和“.*? ”的区别 点号表示任意非换行符的字符&#xff0c;星号表示匹配它前面的字符0次或者任意多次。所以“.*”表示匹配一串任意长度的字符串任意次。这个时候必须在“.*”的前后加其他的符号来限定范围&#xff0c;否则得到的结果就是原来的整个字符串。 “.*? &…