【数据结构】单链表 — 纯C实现单链表

news2024/11/15 18:03:29

在这里插入图片描述


目录

  • 💌前言
  • 一、定义
    • 1.概念
    • 2.特点
    • 3.优点
    • 4.缺点
    • 5.结点定义
  • 接口实现
    • 创建链表结点
      • 创建单个结点
      • 创建链表
      • 打印链表
      • 测试创建功能
    • 尾插尾删
      • 尾部插入
      • 尾部删除
      • 尾插尾删测试
    • 头插头删
      • 头部插入
      • 头部删除
      • 头插头删测试
    • pos位的插入删除
      • 查找pos位置
      • 在pos位置前插入
      • 在pos位置后插入
      • 删除pos位置的数
      • 删除pos位置后的数
      • pos位置上的插入删除测试
    • 销毁链表
  • 代码汇总
    • SLlist.h
    • SLlist.c
    • test.c


💌前言

本文介绍了单链表的定义以及常用结点的实现。


一、定义

1.概念

顺序表最大缺点就是:插入和删除的时候需要移动大量的元素。
而单链表是一种链式存取的数据结构,用一组地址任意的存储单元存放线性表中的数据元素。链表中的数据是以结点来表示的,每个结点的构成:元素(数据元素的映象) + 指针(指示后继元素存储位置),元素就是存储数据的存储单元,指针就是连接每个结点的地址数据。

2.特点

由于分散存储,为了能够体现出数据元素之间的逻辑关系,每个数据元素在存储的同时,要配备一个指针,用于指向它的直接后继元素,即每一个数据元素都指向下一个数据元素(最后一个指向NULL(空))。
链表中每个元素本身由两部分组成:
● 数据域:存放数据。
● 指针域:存放指向后继结点的地址;
链表的第一个结点被称为:头节点

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

3.优点

①.链表是一个动态数据结构,无需给出链表的初始大小。
②.任意位置插入删除时间复杂度为O(1)。
与数组不同,在插入或删除元素后,我们不必移动元素。 在链表中,我们只需要更新节点的下一个指针中存在的地址即可。
③.由于链表的大小可以在运行时增加或减小,因此不会浪费内存。

4.缺点

①.存储密度小,因为每个数据元素,都需要额外存储一个指向下一元素的指针(双链表则需要两个指针)。
②.要访问特定元素,只能从链表头开始,遍历到该元素,时间复杂度为 O ( n) 在特定的数据元素之后插入或删除元素,不涉及到其他元素的移动,因此时间复杂度为 O ( 1) 。 双链表还允许在特定的数据元素之前插入或删除元素。
③.存储空间不连续,数据元素之间使用指针相连,每个数据元素只能访问周围的一个元素(根据单链表还是双链表有所不同)。

5.结点定义

typedef int LinkType; //数据类型
typedef struct SLlist {
	LinkType data;//数据域
	struct SLlist* next;//指针域
}SLlist;

利用typedef修改int类型的名字,下面int的地方全部可以用typedef后的名字代替,便于修改数据类型。
由于每个结点都是两部分,所以结构体内部有两部分:
一部分存储数据,另一部分存储下一个结点的地址。


接口实现

创建链表结点

创建单个结点

创建单个结点是我们实现后面接口的基础。

SLlist* BuySLlist(LinkType x) {
	SLlist* newnode = (SLlist*)malloc(sizeof(SLlist));
	if (newnode == NULL)
	{
		perror("malloc fail");
		exit(-1);
	}
	newnode->data = x;
	newnode->next = NULL;
	return newnode;
}

创建链表

这里我为了测试方便,每个结点的数据内容我并没有使用scanf函数输入,实际使用过程中大家可以在循环里面加入scanf函数。

SLlist* CreateSLlist(LinkType n)
{
	SLlist* phead = NULL, * ptail = NULL;
	int x = 0;
	for (int i = 0; i < n; ++i)
	{
		SLlist* newnode = BuySLlist(i);
		if (phead == NULL)
		{
			ptail = phead = newnode;
		}
		else
		{
			ptail->next = newnode;
			ptail = newnode;
		}
	}
	return phead;
}

打印链表

为了测试的结构直观显示,我就先把打印函数写出来。

void PrintSLlist(SLlist* phead) {
	SLlist* cur = phead;
	while (cur != NULL) {         //(1)
		printf("%d->", cur->data);//(2)
		cur = cur->next;          //(3)
	}
	printf("NULL!");              //(4)
}

(1)当指针为空时,结束循环
(2)打印当前指针指向的数据
(3)将当前指针修改为当前指针指针域指向的结点的地址
(4)为了方便测试,打印NULL代表结束

测试创建功能

为了防止错误堆积到最后,我们平时写代码的时候就应该这样。每写出一个函数就可以测试以下。防止最后错误太多,看都不想看了💔💔💔

void Test02()
{
	SLlist* n1 = CreateSLlist(10);
	PrintSLlist(n1);
}
int main()
{
	Test02();
	return 0;
}

在这里插入图片描述
如图,测试正常。

尾插尾删

尾部插入

void SLlistPushBack(SLlist** pphead, LinkType x)
{
	SLlist* newnode = BuySLlist(x);
	if (*pphead == NULL)
	{
		*pphead = newnode;
	}
	else
	{
		SLlist* tail = *pphead;
		// 找尾
		while (tail->next)
		{
			tail = tail->next;
		}
		tail->next = newnode;
	}
}

尾部删除

void SLlistPopBack(SLlist** pphead)
{
	assert(*pphead);
	if ((*pphead)->next == NULL)
	{
		free(*pphead);
		*pphead = NULL;
	}
	else
	{
		SLlist* tail = *pphead;
		while (tail->next->next)
		{
			tail = tail->next;
		}
		free(tail->next);
		tail->next = NULL;
	}
}

尾插尾删测试

//测试尾插函数是否正常
void Test03()
{
	SLlist* n1 = CreateSLlist(5);
	SLlistPushBack(&n1, 10);
	PrintSLlist(n1);
}
//测试尾删函数是否正常
void Test04()
{
	SLlist* n1 = CreateSLlist(5);
	SLlistPopBack(&n1);
	PrintSLlist(n1);
}

测试尾部插入函数

//主函数实现
int main()
{
	Test03();
	return 0;
}

在这里插入图片描述
测试尾部删除函数

//主函数实现
int main()
{
	Test04();
	return 0;
}

在这里插入图片描述

头插头删

头部插入

//头插
void SLlistPushFront(SLlist** pphead, LinkType x)
{
	SLlist* newnode = BuySLlist(x);
	newnode->next = *pphead;
	*pphead = newnode;
}

头部删除

//头删
void SLlistPopFront(SLlist** pphead)
{
	assert(*pphead);
	SLlist* next = (*pphead)->next;
	free(*pphead);
	*pphead = next;
}

头插头删测试

//测试头插函数是否正常
void Test05()
{
	SLlist* n1 = CreateSLlist(5);
	SLlistPushFront(&n1, 30);
	SLlistPushFront(&n1, 40);
	PrintSLlist(n1);
}
//测试头删函数是否正常
void Test06()
{
	SLlist* n1 = CreateSLlist(10);
	SLlistPopFront(&n1);
	SLlistPopFront(&n1);
	PrintSLlist(n1);
}

测试头部插入函数

//主函数实现
int main()
{
	Test05();
	return 0;
}

在这里插入图片描述
测试头部删除函数

//主函数实现
int main()
{
	Test06();
	return 0;
}

在这里插入图片描述

pos位的插入删除

想要在pos位置进行插入删除,我们首先就要明确pos位置在哪里。
同顺序表一样,我们需要先写一个find函数来找到pos位置。

查找pos位置

//单链表查找位置
SLlist* SLTFind(SLlist* phead, LinkType x)
{
	SLlist* cur = phead;
	while (cur)
	{
		if (cur->data == x)
		{
			return cur;
		}

		cur = cur->next;
	}

	return NULL;
}

在pos位置前插入

//在pos位置前插入
void SLTInsert(SLlist** pphead, SLlist* pos, LinkType x)
{
	assert(pos);
	if (*pphead == pos)
	{
		SLlistPushFront(pphead, x);
	}
	else
	{
		SLlist* prev = *pphead;
		while (prev->next != pos)
		{
			prev = prev->next;
		}

		SLlist* newnode = BuySLlist(x);
		prev->next = newnode;
		newnode->next = pos;
	}
}

在pos位置后插入

//在pos位置后插入
void SLTInsertAfter(SLlist* pos, LinkType x)
{
	assert(pos);
	SLlist* newnode = BuySLlist(x);
	newnode->next = pos->next;
	pos->next = newnode;
}

删除pos位置的数

//删除pos位置的函数
void SLTErase(SLlist** pphead, SLlist* pos)
{
	assert(pos);
	assert(*pphead);
	if (pos == *pphead)
	{
		SLlistPopFront(pphead);
	}
	else
	{
		SLlist* prev = *pphead;
		while (prev->next != pos)
		{
			prev = prev->next;
		}

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

删除pos位置后的数

//删除pos位置后的函数
void SLTEraseAfter(SLlist* pos)
{
	assert(pos);
	if (pos->next == NULL)
	{
		return;
	}
	else
	{
		SLlist* nextNode = pos->next;
		pos->next = nextNode->next;
		free(nextNode);
	}
}

pos位置上的插入删除测试

//测试在pos位置后插入函数是否正常
void Test07()
{
	SLlist* n1 = CreateSLlist(10);
	SLlist* p = SLTFind(n1, 3);
	SLTInsertAfter(p, 30);
	PrintSLlist(n1);
}
//测试在pos位置前插入函数是否正常
void Test08()
{
	SLlist* n1 = CreateSLlist(10);
	SLlist* p = SLTFind(n1, 3);
	SLTInsertAfter(p, 30);
	SLTInsert(&n1, p, 90);
	PrintSLlist(n1);
}
//测试删除pos位置后函数是否正常
void Test09()
{
	SLlist* n1 = CreateSLlist(10);
	SLlist* p = SLTFind(n1, 3);
	SLTInsertAfter(p, 30);
	SLTInsert(&n1, p, 90);
	PrintSLlist(n1);
	printf("\n");
	SLTEraseAfter(p);
	PrintSLlist(n1);
}
//测试删除pos位置函数是否正常
void Test10()
{
	SLlist* n1 = CreateSLlist(10);
	SLlist* p = SLTFind(n1, 3);
	SLTInsertAfter(p, 30);
	SLTInsert(&n1, p, 90);
	PrintSLlist(n1);
	printf("\n");
	SLlist* p2 = SLTFind(n1, 90);
	SLTErase(&n1, p2);
	PrintSLlist(n1);
}

和上面的测试一样,想测试那个,就把test函数修改为对于的函数。

//主函数实现
int main()
{
	Test10();
	return 0;
}

在这里插入图片描述

销毁链表

通过循环,使用free函数释放每一个空间即可。

void SLTDestroy(SLlist** pphead)
{
	SLlist* cur = *pphead;
	while (cur)
	{
		SLlist* next = cur->next;
		free(cur);
		cur = next;
	}

	*pphead = NULL;
}

代码汇总

SLlist.h用来声明函数
SLlist.c用来定义函数
test.c 用来测试函数

SLlist.h

#pragma once
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
typedef int LinkType; //数据类型
typedef struct SLlist {
	LinkType data;//数据域
	struct SLlist* next;//指针域
}SLlist;
//创建单个结点
SLlist* BuySLlist(LinkType x);
//创建链表
SLlist* CreateSLlist(LinkType n);
//打印链表
void PrintSLlist(SLlist* phead);
//尾插
void SLlistPushBack(SLlist** pphead, LinkType x);
//尾删
void SLlistPopBack(SLlist** pphead);
//头插
void SLlistPushFront(SLlist** pphead, LinkType x);
//头删
void SLlistPopFront(SLlist** pphead);
//查找
SLlist* SLTFind(SLlist* phead, LinkType x);
//在pos位置后插入
void SLTInsertAfter(SLlist* pos, LinkType x);
//在pos位置前插入
void SLTInsert(SLlist** pphead, SLlist* pos, LinkType x);
//删除pos位置后的数据
void SLTEraseAfter(SLlist* pos);
//删除pos位置的数据
void SLTErase(SLlist** pphead, SLlist* pos);
//销毁单链表
void SLTDestroy(SLlist** pphead);

SLlist.c

#include"SLlist.h"
//创建单个结点
SLlist* BuySLlist(LinkType x) {
	SLlist* newnode = (SLlist*)malloc(sizeof(SLlist));
	if (newnode == NULL)
	{
		perror("malloc fail");
		exit(-1);
	}
	newnode->data = x;
	newnode->next = NULL;
	return newnode;
}
//创建链表
SLlist* CreateSLlist(LinkType n)
{
	SLlist* phead = NULL, * ptail = NULL;
	int x = 0;
	for (int i = 0; i < n; ++i)
	{
		SLlist* newnode = BuySLlist(i);
		if (phead == NULL)
		{
			ptail = phead = newnode;
		}
		else
		{
			ptail->next = newnode;
			ptail = newnode;
		}
	}
	return phead;
}
//打印链表
void PrintSLlist(SLlist* phead) {
	SLlist* cur = phead;
	while (cur != NULL) {
		printf("%d->", cur->data);
		cur = cur->next;
	}
	printf("NULL!");
}
// 尾插
void SLlistPushBack(SLlist** pphead, LinkType x)
{
	SLlist* newnode = BuySLlist(x);
	if (*pphead == NULL)
	{
		*pphead = newnode;
	}
	else
	{
		SLlist* tail = *pphead;
		// 找尾
		while (tail->next)
		{
			tail = tail->next;
		}
		tail->next = newnode;
	}
}
//尾删
void SLlistPopBack(SLlist** pphead)
{
	assert(*pphead);
	if ((*pphead)->next == NULL)
	{
		free(*pphead);
		*pphead = NULL;
	}
	else
	{
		SLlist* tail = *pphead;
		while (tail->next->next)
		{
			tail = tail->next;
		}
		free(tail->next);
		tail->next = NULL;
	}
}
//头插
void SLlistPushFront(SLlist** pphead, LinkType x)
{
	SLlist* newnode = BuySLlist(x);
	newnode->next = *pphead;
	*pphead = newnode;
}
//头删
void SLlistPopFront(SLlist** pphead)
{
	assert(*pphead);
	SLlist* next = (*pphead)->next;
	free(*pphead);
	*pphead = next;
}
//单链表查找位置
SLlist* SLTFind(SLlist* phead, LinkType x)
{
	SLlist* cur = phead;
	while (cur)
	{
		if (cur->data == x)
		{
			return cur;
		}

		cur = cur->next;
	}

	return NULL;
}
//在pos位置后插入
void SLTInsertAfter(SLlist* pos, LinkType x)
{
	assert(pos);
	SLlist* newnode = BuySLlist(x);
	newnode->next = pos->next;
	pos->next = newnode;
}
//在pos位置前插入
void SLTInsert(SLlist** pphead, SLlist* pos, LinkType x)
{
	assert(pos);
	if (*pphead == pos)
	{
		SLlistPushFront(pphead, x);
	}
	else
	{
		SLlist* prev = *pphead;
		while (prev->next != pos)
		{
			prev = prev->next;
		}

		SLlist* newnode = BuySLlist(x);
		prev->next = newnode;
		newnode->next = pos;
	}
}
//删除pos位置后的函数
void SLTEraseAfter(SLlist* pos)
{
	assert(pos);
	if (pos->next == NULL)
	{
		return;
	}
	else
	{
		SLlist* nextNode = pos->next;
		pos->next = nextNode->next;
		free(nextNode);
	}
}
//删除pos位置的函数
void SLTErase(SLlist** pphead, SLlist* pos)
{
	assert(pos);
	assert(*pphead);
	if (pos == *pphead)
	{
		SLlistPopFront(pphead);
	}
	else
	{
		SLlist* prev = *pphead;
		while (prev->next != pos)
		{
			prev = prev->next;
		}

		prev->next = pos->next;
		free(pos);
	}
}
//销毁单链表
void SLTDestroy(SLlist** pphead)
{
	SLlist* cur = *pphead;
	while (cur)
	{
		SLlist* next = cur->next;
		free(cur);
		cur = next;
	}

	*pphead = NULL;
}

test.c

#include"SLlist.h"
//测试创建结点函数是否正常
void Test01()
{
	SLlist* n1 = BuySLlist(1);
	PrintSLlist(n1);
}
//测试创建链表函数是否正常
void Test02()
{
	SLlist* n1 = CreateSLlist(10);
	PrintSLlist(n1);
}
//测试尾插函数是否正常
void Test03()
{
	SLlist* n1 = CreateSLlist(5);
	SLlistPushBack(&n1, 10);
	PrintSLlist(n1);
}
//测试尾删函数是否正常
void Test04()
{
	SLlist* n1 = CreateSLlist(5);
	SLlistPopBack(&n1);
	PrintSLlist(n1);
}
//测试头插函数是否正常
void Test05()
{
	SLlist* n1 = CreateSLlist(5);
	SLlistPushFront(&n1, 30);
	SLlistPushFront(&n1, 40);
	PrintSLlist(n1);
}
//测试头删函数是否正常
void Test06()
{
	SLlist* n1 = CreateSLlist(10);
	SLlistPopFront(&n1);
	SLlistPopFront(&n1);
	PrintSLlist(n1);
}
//测试在pos位置后插入函数是否正常
void Test07()
{
	SLlist* n1 = CreateSLlist(10);
	SLlist* p = SLTFind(n1, 3);
	SLTInsertAfter(p, 30);
	PrintSLlist(n1);
}
//测试在pos位置前插入函数是否正常
void Test08()
{
	SLlist* n1 = CreateSLlist(10);
	SLlist* p = SLTFind(n1, 3);
	SLTInsertAfter(p, 30);
	SLTInsert(&n1, p, 90);
	PrintSLlist(n1);
}
//测试删除pos位置后函数是否正常
void Test09()
{
	SLlist* n1 = CreateSLlist(10);
	SLlist* p = SLTFind(n1, 3);
	SLTInsertAfter(p, 30);
	SLTInsert(&n1, p, 90);
	PrintSLlist(n1);
	printf("\n");
	SLTEraseAfter(p);
	PrintSLlist(n1);
}
//测试删除pos位置函数是否正常
void Test10()
{
	SLlist* n1 = CreateSLlist(10);
	SLlist* p = SLTFind(n1, 3);
	SLTInsertAfter(p, 30);
	SLTInsert(&n1, p, 90);
	PrintSLlist(n1);
	printf("\n");
	SLlist* p2 = SLTFind(n1, 90);
	SLTErase(&n1, p2);
	PrintSLlist(n1);
}
//测试销毁函数是否正常
void Test11()
{
	SLlist* n1 = CreateSLlist(10);
	SLTDestroy(&n1);
	PrintSLlist(n1);
}
//主函数实现
int main()
{
	Test10();
	return 0;
}

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

CUDA和Compute Capability

Compute Capability 参考 指示GPU硬件能够支持的特性&#xff0c;可以被应用参考哪些特性可以运行。 这里能够找到不同Compute Capability对应的硬件特性。比如我的笔记本搭载了一块Geforce830m&#xff0c;Compute Capability为5.0&#xff0c;硬件特性为 另外有关技术细节比…

面试官问我HTTP,我真的是

面试官&#xff1a;今天要不来聊聊HTTP吧&#xff1f; 候选者&#xff1a;嗯&#xff0c;HTTP「协议」是客户端和服务器「交互」的一种通迅的格式 候选者&#xff1a;所谓的「协议」实际上就是双方约定好的「格式」&#xff0c;让双方都能看得懂的东西而已 候选者&#xff1…

2023-01-02 Echarts学习笔记(一) 基础概念和应用示例:折线图

文章目录0.什么是Echarts?1.常见使用场景2.使用Echarts的基本步骤3.应用示例:做一个折线图4.参考资料0.什么是Echarts? ECharts.js是 百度出品的一个开源 Javascript 数据可视化库 一个使用 JavaScript 实现的开源可视化库&#xff0c; 可以流畅的运行在 PC 和移动设备上&a…

【数据结构】二叉树递归算法代码总结

文章目录一、内容介绍二、算法总结2.1 二叉树结构2.2 完整代码2.3 输出结果三、Reference四、总结一、内容介绍 上一年备考数据结构中自己整理并验证过的二叉树递归算法。包括&#xff1a; 1、二叉树的创建&#xff1b; 2、二叉树的先、中、后序的递归遍历&#xff1b; 3、输出…

[项目说明]-基于人工智能博弈树,极大极小(Minimax)搜索算法并使用Alpha-Beta剪枝算法优化实现的可人机博弈的AI智能五子棋游戏。

个人选题项目 基于人工智能博弈树&#xff0c;极大极小(Minimax)搜索算法并使用Alpha-Beta剪枝算法优化实现的可人机博弈的AI智能五子棋游戏。 设计目标及主要内容 本系统是根据传统五子棋游戏的功能编写&#xff0c;其功能实现了基于AI人工智能算法实现智能的人机对弈五子棋…

Java jdk安装及环境配置

Java环境安装一、 jdk和jre的安装1、安装目录创建java文件夹2、java文件夹内创建jdk和jre3、解压下载好的jdk安装包二、环境变量的配置一、 jdk和jre的安装 首先下载jdk 1、安装目录创建java文件夹 2、java文件夹内创建jdk和jre 3、解压下载好的jdk安装包 双击运行解压的jdk …

Kali Linux中shutdown指令的用法3-2

2.4 屏蔽重启指令 -h参数表示屏蔽重启指令&#xff0c;使用如图6所示的指令&#xff0c;可以屏蔽reboot指令&#xff0c;该指令的作用为关闭&#xff08;poweroff&#xff09;系统。 图6 屏蔽重启指令 从图6中可以看出&#xff0c;-h屏蔽了--reboot。 需要注意的是&#xff…

关于OLTP 和OLAP 干货知识分享

OLTP 和 OLAP 这两个概念在十来年前、十几年前BI这个词还不是那么普及的时候&#xff0c;还经常放在一起做比较&#xff0c;现在已经很少再单独拿出来做对比了&#xff0c;但也总还是有人会问到&#xff0c;我在这里大概讲下两个概念的差别和联系。 什么是OLTP OLTP 英文全称…

81.Zabbix之Window服务器agent监控

Zabbix版本:6.2.3 1.官网上下载对应的agent Download Zabbix agents 我们下载Zabbix agent 2 2.配置Zabbix agent2 下载完成后,将压缩包复制到服务器,然后放在移至C盘目录下(其他目录也是可以的),然后进行解压。 3.修改配置文件 用文本编辑软件打开zabbix_agent2.c…

DC-4靶场练习

今天抽时间做了下DC-4的实验&#xff0c;整理了实验步骤&#xff0c;并提炼总结方法论。内网存活主机扫描命令nmap -sP 192.168.101.0/24 arp-scan -l以上IP地址使用排除法,最后得出192.168.101.79是靶机地址。探测目标开放的端口推荐masscannmap快速扫描&#xff1a;masscan -…

【谷粒商城基础篇】整合SpringCloud、SpringCloud alibaba

谷粒商城笔记合集 分布式基础篇分布式高级篇高可用集群篇简介&环境搭建项目简介与分布式概念&#xff08;第一、二章&#xff09;基础环境搭建&#xff08;第三章&#xff09;整合SpringCloud整合SpringCloud、SpringCloud alibaba&#xff08;第四、五章&#xff09;前端知…

【ACWING】【4645选数异或】

给定一个长度为 n 的数列 A1,A2,,An 和一个非负整数 x&#xff0c;给定 m 次查询&#xff0c;每次询问能否从某个区间 [l,r] 中选择两个数使得他们的异或等于 x。 输入格式 输入的第一行包含三个整数 n,m,x。 第二行包含 n 个整数 A1,A2,,An。 接下来 m 行&#xff0c;每行包含…

单片机基础之初识串口

目录 一、初识串口 1、串口基本知识 2、串口的特点 3、了解下全双工和半双工的区别 二、关于串口的电器标准和协议 1、RS-232 2、RS-422 3、RS-485 三、关于串口的电平 1、RS232 电平 2、TTL电平 四、串口通信 1、串口接线方式 2、串口编程要素 3、波特率 4、编…

【练习】day02(未完成版)

努力经营当下直至未来明朗&#xff01; 文章目录一、选择二、编程1. 全排列2. 全排列II答案1. 选择2. 编程普通小孩也要热爱生活&#xff01; 一、选择 此代码片段输出正确的值是&#xff08; &#xff09; public class CharToString {public static void main(String[] ar…

Flink窗口的生命周期

&#x1f34a;在 Apache Flink 中&#xff0c;窗口是对数据流中的一个固定数量的元素或者一段时间内的元素进行分组的一种抽象概念。窗口有自己的生命周期&#xff0c;即从窗口的开始到窗口的结束。 &#x1f34a;窗口的开始和结束可以是以下几种情况之一&#xff1a; 按数据…

WALLET 通证减半:早期用户分配将降至 4%

WALLET 通证即将满 1 年&#xff0c;这意味着根据 Ambire 钱包白皮书&#xff0c;它的年度早期用户供应量将削减至 4%&#xff0c;随着应用率的增长&#xff0c;通货膨胀率将大幅降低。 WALLET 一周年 根据官方消息&#xff0c;WALLET 通证的生成&#xff08;token generation …

差分矩阵(二维)

题目&#xff1a; 输入一个 n行 m列的整数矩阵&#xff0c;再输入 q个操作&#xff0c;每个操作包含五个整数 x1,y1,x2,y2,c其中 (x1,y1)(x1,y1) 和 (x2,y2) 表示一个子矩阵的左上角坐标和右下角坐标。 每个操作都要将选中的子矩阵中的每个元素的值加上 c。 请你将进行完所有…

React Native 路由篇 react-navigation

1.我这边使用的是react-navigation&#xff0c;参照官网安装完启动&#xff0c;执行 npm install react-navigation/native。在安卓模拟器会报这个错误“invariant violation: requirenativecomponent: “rncsafeareaprovider” was not found in the uimanager”&#xff0c;其…

Java网络编程

一、IO模型 IO模型就是说用什么样的通道进行数据的发送和接收&#xff0c;Java共支持3种网络编程IO模式&#xff1a; BIONIOAIO 1.BIO 1.1基本介绍 Blocking I/O&#xff0c;同步阻塞&#xff08;传统阻塞型&#xff09;&#xff0c;服务器实现模式为一个连接一个线程&…

CSS初级教程(轮廓)【第五天】

CSS初级教程【第五天】【1】CSS 框模型【2】CSS 轮廓【3】CSS 轮廓宽度【4】CSS 轮廓颜色【5】CSS 轮廓简写【6】CSS 轮廓偏移【7】所有 CSS 轮廓属性CSS上回学习链接 CSS初级教程 颜色【第一天】 CSS初级教程 背景【第二天】 CSS初级教程 边框【第三天】 CSS初级教程 边距、高…