数据结构(ing)
学习内容
指针
指针的定义:
指针是一种变量,它的值为另一个变量的地址,即内存地址。
指针在内存中也是要占据位置的。
指针类型:
指针的值用来存储内存地址,指针的类型表示该地址所指向的数据类型并告诉编译器如何解释该指针所指向的内存中的数据。
指针的初始化:
指针的赋值是运用&这个操作符完成的,用于产生操作数的内存地址。
指针的运用(取值):
运用单目操作符*来取出指针所指向的内存块的值
int a = 921; int* b = &a; // b取得a在内存中的起始位置 int c = *b; // 得到b指向的内存块的值printf("a在内存中的起始地址为 %p \n", (void*)b);printf("b指针在内存中所指向的值为 %d \n", c);
练习:
*&a = 25
理解:
&a表示取a的起始地址,*(&a)表示取(&a)所指向的内存块的值
所以其实这个意思就是a=25
线性表
概念
定义:
具有相同特性的数据元素的一个有限序列,由n (n >= 0) 个数据元素(结点)a1、a2、a3.....an组成的有限序列。包括起始节点、终端节点、数据元素......
存储结构:
1.顺序存储结构:
把逻辑上相邻的数据元素存储在物理上相邻的存储单元中的存储结构
2.链式存储结构:
结点在存储器中的位置是任意的,即逻辑上相邻的数据元素在物理上不一定相邻。访问时只能通过头指针进入链表。
顺序存储结构(顺序表)
优点:以物理位置相邻表示逻辑关系,任一元素均可随机存取,存储密度大。
缺点:在插入、删除某一元素时,需要移动大量元素,浪费存储空间,属于静态存储形式,数据元素的个数不能自由扩充。
特点: 地址连续、依次存放、随机存取 、类型相同
存储表示
逻辑结构:(a1,a2,a3,...... an)
存储结构:
顺序表的定义
顺序表的数组下标是从0开始的
数组静态分配
#define N 100typedef struct {int e;
} Node;typedef struct { Node element[N]; //静态分配数组int length; //存储顺序表的长度
} SqList;
数组动态分配
typedef struct {int e;
} Node;typedef struct { Node *element; //动态分配数组int length; //存储顺序表的长度
} SqList;
顺序表的基本操作
初始化线性表
// 线性表的初始化
bool InitList_Sq(SqList &L, int n)
{// 分配内存L.element = (Node*)malloc(sizeof(Node)*n); if (!L.element) return false; //分配失败L.length = 0; // 初始化空表长度为0return true; // 初始化成功
}
销毁线性表
// 销毁线性表
void DestroyList(SqList &L)
{if (L.element) delete L.element; // 释放存储空间
}
清空线性表
// 清空线性表
void ClearList(SqList &L)
{L.length = 0; //将线性表的长度置为0
}
求线性表的长度
// 求线性表的长度
int GetLength(SqList L)
{return L.length;
}
判断线性表是否为空
// 判断线性表是否为空
bool IsEmpty(SqList L)
{if (L.length == 0) return true;else return false;
}
顺序表取值
// 顺序表的取值(根据位置获取元素)
bool GetElement(int idx, SqList L, Node &e)
{if (idx < 1 || idx > L.length) return false;e = L.element[idx - 1];return true;
}
按值查找
// 按值查找
int LocateElem(SqList L, Node e)
{for (int i = 0; i < L.length; i ++){if (L.element[i].e == e.e) return i + 1;}return 0; // 查找失败
}
顺序表的插入
// 顺序表的插入
bool ListInsert_Sq(SqList &L, int idx, Node e)
{if (idx < 1 || idx > L.length + 1) return false;for (int i = L.length - 1; i >= idx - 1; i --){L.element[i + 1] = L.element[i];}L.element[idx - 1] = e;L.length ++;return true;
}
顺序表的删除
// 顺序表的删除
bool ListDelete_Sq(SqList &L, int idx)
{if (idx < 1 || idx > L.length) return false;for (int i = idx; i < L.length; i ++){L.element[i - 1] = L.element[i];}L.length --;return true;
}
链式存储结构(链表)
定义:
n个结点由指针链组成一个链表。它是线性表的链式存储映像,称为线性表的链式存储结构。
概念表示:
结点:
数据元素的存储映像称为结点,它由数据域和指针域两部分组成。
特殊结点:
- 头结点:在链表的首元结点之前额外设置的一个结点。
- 首元结点:链表中存储第一个数据元素a1的结点
数据域:存储当前结点的数据。
指针域:存储下一个节点的位置。
头指针:
指向链表中第一个节点的指针。
链表:
链表分为单链表、双链表、循环链表。
- 单链表:结点只有一个指针域,存储的是下一个节点的地址。
- 双链表:结点有两个指针域。存储相邻两个结点的地址。
- 循环链表:是一种头尾相接的链表,表中的最后一个结点的指针域指向头结点,整个链表形成一个环。
存储表示:
逻辑结构:(a1,a2,a3,...... an)
存储结构:
第一种 (无头结点) :
第二种(有头结点):
空表
1.无头结点时,头指针为空时表示空表,表示空表。
2.有头结点时,头结点的指针域为空时,表示空表。
单链表
数组模拟单链表:数组模拟单链表文章浏览阅读118次。数组模拟单链表https://blog.csdn.net/m0_73569492/article/details/128693718?ops_request_misc=%257B%2522request%255Fid%2522%253A%25220bb3388a11ebbfdf7502eedcb53293d6%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255Fblog.%2522%257D&request_id=0bb3388a11ebbfdf7502eedcb53293d6&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~blog~first_rank_ecpm_v1~rank_v31_ecpm-1-128693718-null-null.nonecase&utm_term=%E5%8D%95%E9%93%BE%E8%A1%A8&spm=1018.2226.3001.4450
链表定义
定义了两种类型:LNode 为结构体类型;LinkList 为指向该结构体类型的指针类
typedef struct {int e;
} Data;typedef struct Lnode {Data data; // 结点的数据域struct Lnode *next; // 结点的指针域
} LNode, *LinkList; // 定义了两种类型:LNode 为结构体类型;LinkList 为指向该结构体类型的指针类型。
LinkList L; // 定义链表L
LNode *p; // 定义结点指针
LinkList q; //定义结点指针
链表操作
初始化单链表
1.生成新节点作为头结点
2.头指针指向头结点
3.头结点的指针域指向空
分配内存:
L = (LinkList)malloc(sizeof(LNode));
这一行代码调用了 malloc 函数来为一个新的 LNode 结构体分配内存。malloc 返回的是一个指向所分配内存块的指针(类型为 void*),然后通过 (LinkList) 强制转换为 LinkList 类型(即 LNode*)。此时,L 已经指向了这块新分配的内存,这块内存代表了一个新的链表节点。
// 单链表的初始化
bool InitList_L(LinkList &L)
{L = (LinkList)malloc(sizeof(LNode)); L->next = NULL;return true;
}
判断单链表是否为空
其实就是判断头结点的指针域是否为空,如果为空,则代表是空表,如果不为空,则代表不为空表。
// 判断链表是否为空
bool IsEmpty_List(LinkList L)
{if (L->next == NULL) return true;return false;
}
单链表的销毁
销毁过程如下:
// 单链表的销毁
void Destroy_List(LinkList &L)
{LNode *p;while (L){p = L;L = L->next;free(p);}
}
清空单链表
// 清空单链表
void Clear_List(LinkList &L)
{LNode *p;while (L->next) {p = L->next;L->next = p->next;free(p);}
}
求单链表的表长
// 求单链表的表长
int Caculate_Length(LinkList L)
{int cnt = 0;for (LNode* p = L->next; p != NULL; p = p->next)cnt ++;return cnt;
}
根据位置获取元素
// 取值-取单链表中第idx个元素的内容
bool GetElement(LinkList L, Data &e, int idx)
{int cnt = 0;for (LNode* p = L->next; p != NULL; p = p->next){cnt ++;if (cnt == idx) {e = p->data;return true;} }return false;
}
按值查找
// 按值查找-根据数据获取该数据所在位置
int GetIdx(LinkList L, Data &element)
{int cnt = 0;for (LNode* p = L->next; p != NULL; p = p->next){cnt ++;if (p->data.e == element.e) return cnt; }return -1;
}
单链表的插入(任意位置)
// 单链表的插入-在第i个元素之前插入
bool Insert(LinkList &L, int idx, Data element)
{int cnt = 0;for (LNode* p = L; p->next != NULL; p = p->next){if (cnt == idx - 1){LNode *e = (LNode*)malloc(sizeof(LNode));e->data = element;e->next = p->next;p->next = e;return true;}cnt ++;} return false;
}
单链表删除元素
// 删除-删除第idx个元素
bool Delete(LinkList &L, int idx)
{int cnt = 0;for (LNode* p = L; p != NULL; p = p->next){if (cnt == idx - 1){LNode *q = p->next;p->next = q->next;free(q);return true;}cnt ++;}return false;
}
头插法
// 头插法
bool Insert_Head(LinkList &L, Data element)
{LNode *cur = (LNode*)malloc(sizeof(LNode));cur->data = element;cur->next = L->next;L->next = cur;return true;
}
尾插法
// 尾插法
bool Insert_Tail(LinkList &L, Data element)
{LNode *p = L;while (p->next){p = p->next;}LNode *cur = (LNode*)malloc(sizeof(LNode));cur->data = element;cur->next = NULL;p->next = cur;return true;
}
输出单链表
// 输出单链表
void Print_List(LinkList &L)
{for (LNode* p = L->next; p != NULL; p = p->next){printf("%d ", p->data.e);}printf("\n");
}
循环链表
优点:
从表中任意节点出发都能够找到其他结点。
注意:
当执行遍历操作时,条件与单链表不同,结束条件需要看当前节点的指针域是不是等于头结点。
链表定义:
typedef struct {int e;
} Data;typedef struct Lnode {Data data; // 结点的数据域struct Lnode *next; // 结点的指针域
} LNode, *LinkList; // 定义了两种类型:LNode 为结构体类型;LinkList 为指向该结构体类型的指针类型。
链表操作:
带头指针的:
// 循环链表的初始化
bool InitList_L(LinkList &L)
{L = (LinkList)malloc(sizeof(LNode));L->next = L;return true;
}
// 判断循环链表是否为空
bool IsEmpty_List(LinkList L)
{if (L->next == L) return true;return false;
}
// 循环链表的销毁
void Destroy_List(LinkList &L)
{LNode *p = L->next;while (p->next != L){L = L->next;free(p);p = L->next;}free(L);
}
// 清空循环链表
void Clear_List(LinkList &L)
{LNode *p;while (L->next != L){p = L->next;L->next = p->next;free(p);}
}
// 求循环链表的表长
int Caculate_Length(LinkList L)
{int len = 0;LNode *p = L;while (p->next != L){len ++;p = p->next;}return len;
}
// 取值-取循环链表中第idx个元素的内容
bool GetElement(LinkList L, Data &e, int idx)
{int len = 0;LNode *p = L;while (p->next != L){len ++;p = p->next;if (len == idx){e = p->data;return true;}}return false;
}
// 按值查找-根据数据获取该数据所在位置
int GetIdx(LinkList L, Data &element)
{int len = 0;LNode *p = L;while (p->next != L){len ++;p = p->next;if (p->data.e == element.e){return len;}}return -1;
}
// 循环链表的插入-在第i个元素之前插入
bool Insert(LinkList &L, int idx, Data element)
{int len = 0;LNode *p = L;while (p->next != L){if (len == idx - 1){LNode *q = (LNode*)malloc(sizeof(LNode));q->data = element;q->next = p->next;p->next = q;return true;}len ++;p = p->next;}return false;
}
// 删除-删除第idx个元素
bool Delete(LinkList &L, int idx)
{int len = 0;LNode *p = L;while (p->next != L){len ++;p = p->next;if (len == idx - 1){LNode *q = p->next;p->next = q->next;free(q);return true;}}return false;
}// 头插法
bool Insert_Head(LinkList &L, Data element)
{LNode *p = (LNode*)malloc(sizeof(LNode));p->data = element;p->next = L->next;L->next = p;return true;
}// 尾插法
bool Insert_Tail(LinkList &L, Data element)
{LNode *p = L;while (p->next != L){p = p->next;}LNode *q = (LNode*)malloc(sizeof(LNode));q->data = element;q->next = p->next;p->next = q;return true;
}
// 输出循环链表
void Print_List(LinkList &L)
{for (LNode* p = L->next; p != L; p = p->next){printf("%d ", p->data.e);}printf("\n");
}
带尾指针的:
// 循环链表的初始化
bool InitList_R(LinkList &R)
{R->next = R;return true;
}
// 判断循环链表是否为空
bool IsEmpty_List(LinkList R)
{if (R->next == R) return true;return false;
}
// 循环链表的销毁
void Destroy_List(LinkList &R)
{LNode *p;while (R->next != R){p = R->next;R->next = p->next;free(p);}free(R);
}
// 清空循环链表
void Clear_List(LinkList &R)
{LNode *p;while (R->next != R){p = R->next;R->next = p->next;free(p);}
}
// 求循环链表的表长
int Caculate_Length(LinkList R)
{LNode *p = R;int len = 0;while (p->next != R){len ++;p = p->next;}return len;
}
// 取值-取循环链表中第idx个元素的内容
bool GetElement(LinkList R, Data &e, int idx)
{int len = 0;LNode *p = R;while (p->next != R){len ++;p = p->next;if (len == idx){e = p->data;return true;}}return false;
}
// 按值查找-根据数据获取该数据所在位置
int GetIdx(LinkList R, Data &element)
{int len = 0;LNode *p = R;while (p->next != R){len ++;p = p->next;if (p->data.e == element.e){return len;}}return -1;
}
// 循环链表的插入-在第i个元素之前插入
bool Insert(LinkList &R, int idx, Data element)
{int len = 0;LNode *p = R;while (p->next != R){if (len == idx - 1){LNode *q = (LNode*)malloc(sizeof(LNode));q->data = element;q->next = p->next;p->next = q;return true;}len ++;p = p->next;}return false;
}
// 删除-删除第idx个元素
bool Delete(LinkList &R, int idx)
{int len = 0;LNode *p = R;while (p->next != R){len ++;p = p->next;if (len == idx - 1){LNode *q = p->next;p->next = q->next;free(q);return true;}}return false;
}// 头插法
bool Insert_Head(LinkList &R, Data element)
{LNode *p = (LNode*)malloc(sizeof(LNode));p->data = element;p->next = R->next;R->next = p;return true;
}// 尾插法
bool Insert_Tail(LinkList &R, Data element)
{LNode *p = R;while (p->next != R){p = p->next;}LNode *q = (LNode*)malloc(sizeof(LNode));q->data = element;q->next = R;p->next = q;return true;
}
// 输出循环链表
void Print_List(LinkList &R)
{for (LNode* p = R->next; p != R; p = p->next){printf("%d ", p->data.e);}printf("\n");
}
双链表
数组模拟双链表:数组模拟双链表文章浏览阅读92次。数组模拟双链表_;.ir=k,8https://blog.csdn.net/m0_73569492/article/details/128704895?ops_request_misc=%257B%2522request%255Fid%2522%253A%25221c13d05d054d65bc8bd9b7e25466efa9%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255Fblog.%2522%257D&request_id=1c13d05d054d65bc8bd9b7e25466efa9&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~blog~first_rank_ecpm_v1~rank_v31_ecpm-1-128704895-null-null.nonecase&utm_term=%E5%8F%8C%E9%93%BE%E8%A1%A8&spm=1018.2226.3001.4450
链表定义
typedef struct {int e;
} Data;typedef struct Lnode {struct Lnode *pre; // 指向前驱结点Data data; // 结点的数据域struct Lnode *next; // 指向后继结点
} LNode, *LinkList; // 定义了两种类型:LNode 为结构体类型;LinkList 为指向该结构体类型的指针类型。
链表操作
// 双链表的初始化
bool InitList_L(LinkList &L)
{L = (LinkList)malloc(sizeof(LNode));L->pre = NULL;L->next = NULL;return true;
}
// 判断链表是否为空
bool IsEmpty_List(LinkList L)
{if (L->next == NULL) return true;return false;
}
// 双链表的销毁
void Destroy_List(LinkList &L)
{LNode *p;while (L){p = L;L = L->next;free(p);}
}
// 清空双链表
void Clear_List(LinkList &L)
{LNode *p;while (L->next != NULL) {p = L->next;L->next = p->next;free(p);}
}
// 求双链表的表长
int Caculate_Length(LinkList L)
{int cnt = 0;for (LNode* p = L->next; p != NULL; p = p->next)cnt ++;return cnt;
}
// 取值-取双链表中第idx个元素的内容
bool GetElement(LinkList L, Data &e, int idx)
{int cnt = 0;for (LNode* p = L->next; p != NULL; p = p->next){cnt ++;if (cnt == idx) {e = p->data;return true;} }return false;
}
// 按值查找-根据数据获取该数据所在位置
int GetIdx(LinkList L, Data &element)
{int cnt = 0;for (LNode* p = L->next; p != NULL; p = p->next){cnt ++;if (p->data.e == element.e) return cnt; }return -1;
}
// 双链表的插入-在第i个元素之前插入
bool Insert(LinkList &L, int idx, Data element)
{int cnt = 0;for (LNode* p = L; p->next != NULL; p = p->next){if (cnt == idx - 1){LNode *e = (LNode*)malloc(sizeof(LNode));e->data = element;e->next = p->next;e->pre = p;p->next->pre = e;p->next = e;}cnt ++;} return false;
}
// 删除-删除第idx个元素
bool Delete(LinkList &L, int idx)
{int cnt = 0;for (LNode* p = L; p != NULL; p = p->next){if (cnt == idx - 1){LNode *q = p->next;if (!q->next) {p->next = NULL;free(q);return true; }p->next = q->next;q->next->pre = p;free(q);return true;}cnt ++;}return false;
}// 头插法
bool Insert_Head(LinkList &L, Data element)
{LNode *p = (LNode*)malloc(sizeof(LNode));p->data = element;if (L->next) {p->pre = L;p->next = L->next;L->next->pre = p;L->next = p;}else{L->next = p;p->pre = L;p->next = NULL;}return true;
}// 尾插法
bool Insert_Tail(LinkList &L, Data element)
{LNode *p = L;while (p->next != NULL){p = p->next;}// 在p后面插入curLNode *cur = (LNode*)malloc(sizeof(LNode));cur->data = element;if (p->next){cur->pre = p;cur->next = p->next;p->next->pre = cur;p->next = cur;}else{p->next = cur;cur->pre = p;cur->next = NULL;}return true;
}
// 输出链表
void Print_List(LinkList &L)
{for (LNode* p = L->next; p != NULL; p = p->next){printf("%d ", p->data.e);}printf("\n");
}
相关文章:
数据结构(ing)
学习内容 指针 指针的定义: 指针是一种变量,它的值为另一个变量的地址,即内存地址。 指针在内存中也是要占据位置的。 指针类型: 指针的值用来存储内存地址,指针的类型表示该地址所指向的数据类型并告诉编译器如何解…...

杰盛微 JSM4056 1000mA单节锂电池充电器芯片 ESOP8封装
JSM4056 1000mA单节锂电池充电器芯片 JSM4056是一款单节锂离子电池恒流/恒压线性充电器,简单的外部应用电路非常适合便携式设备应用,适合USB电源和适配器电源工作,内部采用防倒充电路,不需要外部隔离二极管。热反馈可对充电电流进…...
webpack5基础(上篇)
一、基本配置 在开始使用 webpack 之前,我们需要对 webpack 的配置有一定的认识 1、5大核心概念 1)entry (入口) 指示 webpack 从哪个文件开始打包 2)output(输出) 制视 webpack 打包完的…...
快速理解MIMO技术
引言 在无线通信领域,MIMO(Multiple-Input Multiple-Output,多输入多输出)技术是一项革命性的进步,它通过在发射端和接收端同时使用多个天线,极大地提高了通信系统的容量、可靠性和覆盖范围。本文简要阐释其…...

【RTD MCAL 篇3】 K312 MCU时钟系统配置
【RTD MCAL 篇3】 K312 MCU时钟系统配置 一,文档简介二, 时钟系统理论与配置2.1 K312 时钟系统2.1.1 PLL2.1.2 MUX_0系统2.1.3 MUX_6 时钟输出2.1.4 option B推荐方案 2.2 EB 配置2.2.1 General 配置2.2.2 McuClockSettingConfig配置2.2.2.1 McuFIRC配置…...
探索Docker Compose:轻松管理多容器应用
探索Docker Compose:轻松管理多容器应用 在现代软件开发中,容器化已经成为构建、部署和扩展应用的主流方式。而Docker Compose作为Docker生态系统的重要组成部分,可以简化多容器应用的管理。本文将深入探讨Docker Compose的核心功能及应用场…...

计算机网络 (18)使用广播信道的数据链路层
一、广播信道的基本概念 广播信道是一种允许一个发送者向多个接收者发送数据的通信信道。在计算机网络中,广播信道通常用于局域网(LAN)内部的主机之间的通信。这种通信方式的主要优点是可以节省线路,实现资源共享。 二、广播信道数…...
【vLLM 学习】欢迎来到 vLLM!
vLLM 是一款专为大语言模型推理加速而设计的框架,实现了 KV 缓存内存几乎零浪费,解决了内存管理瓶颈问题。 更多 vLLM 中文文档及教程可访问 →https://vllm.hyper.ai/ vLLM 是一个快速且易于使用的库,专为大型语言模型 (LLM) 的推理和部署…...

现代网络基础设施中的 TCP 握手之下
TCP 3 次握手 在最简单的形式中,TCP 三次握手很容易理解,并且有 大量在线材料都在讨论这个问题。(如果你能读懂 Chinease,你可以看看我之前的一篇文章。 然而,在实际中理解、练习和解决 TCP 问题 世界是另一回事。随…...

GRAPE——RLAIF微调VLA模型:通过偏好对齐提升机器人策略的泛化能力(含24年具身模型汇总)
前言 24年具身前沿模型大汇总 过去的这两年,工作之余,我狂写大模型与具身的文章,加之具身大火,每周都有各种朋友通过CSDN私我及我司「七月在线」寻求帮助/指导(当然,也欢迎各大开发团队与我司合作共同交付)…...

NeurIPS 2024 | 像素级LLM实现图像视频理解、生成、分割和编辑大统一(昆仑万维等)
Accepted by NeurIPS 2024 文章链接:https://arxiv.org/pdf/2412.19806 项目链接:https://vitron-llm.github.io/ Github链接:https://github.com/SkyworkAI/Vitron 亮点直击 首次提出了一种通用的视觉多模态大语言模型(MLLM&…...
中药和西药的区别
中药和西药的区别 一、定义与来源 (一)中药 中药主要是在中国传统医学理论指导下用于预防、诊断、治疗疾病或调节人体机能的药物。它的来源广泛,包括植物药、动物药、矿物药等。植物药是中药的主要组成部分,例如人参࿰…...

Spring Security(maven项目) 3.0.2.4版本
前言: 通过实践而发现真理,又通过实践而证实真理和发展真理。从感性认识而能动地发展到理性认识,又从理性认识而能动地指导革命实践,改造主观世界和客观世界。实践、认识、再实践、再认识,这种形式,循环往…...
【Ubuntu】安装华为的MindSpore
目录 1 安装Anaconda 2 更换国内源 3 安装MindSpore 1 安装Anaconda 2 更换国内源 具体方法如下: 打开命令行 cmd 工具,输入以下命令。 ① Conda 换源 conda config --add channels https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/free/ c…...

【模型】Qwen2-VL 服务端UI
1. 前言 最近在测试VLM模型,发现官方的网页demo,代码中视频与图片分辨率可能由于高并发设置的很小,导致达不到预期效果,于是自己研究了一下,搞了一个简单的前端部署,自己在服务器部署了下UI界面࿰…...

计算机网络•自顶向下方法:网络层介绍、路由器的组成
网络层介绍 网络层服务:网络层为传输层提供主机到主机的通信服务 每一台主机和路由器都运行网络层协议 发送终端:将传输层报文段封装到网络层分组中,发送给边缘路由器路由器:将分组从输入链路转发到输出链路接收终端࿱…...
安卓11 SysteUI添加按钮以及下拉状态栏的色温调节按钮
最近客户想要做一个台灯产品,需要实现 串口调节台灯功能 ,其中包括 亮度调节 色温调节 开关 三个功能 话不多说,贴代码 diff --git a/packages/SystemUI/AndroidManifest.xml b/packages/SystemUI/AndroidManifest.xml old mode 100644 new …...
多个线程处理不同的数据,等线程都完成后再进行下一步操作
现在有三个任务,三个任务之间没有关联关系,但是第四个任务要等前三个完成之后才能进行,于是使用多线程完成前三个任务节省时间 示例代码: public void saveDataByOnlineTimeNew(LocalDateTime startTime, LocalDateTime endTime) {Objects.requireNonNull(startTime, "开…...

聆听音乐 1.5.9 | 畅听全网音乐,支持无损音质下载
聆听音乐手机版是面向广大音乐爱好者的移动应用程序,用户可以随时随地通过手机享受丰富的音乐资源。它提供了多种魅力功能,让用户在手机上畅享更舒适的音乐体验,每位用户都能享受精彩纷呈的收听体验。此外,软件还支持无损音质音乐…...
Rust 基础入门指南
Rust 基础入门指南 1. Rust 语言概述 Rust 的历史与设计理念 Rust 是由 Mozilla 研究院的 Graydon Hoare 于2010年开始创建的系统编程语言。其设计目标是创建一种安全、并发、实用的编程语言,特别关注内存安全和并发性。 Rust 的核心设计理念包括: …...
Java 语言特性(面试系列2)
一、SQL 基础 1. 复杂查询 (1)连接查询(JOIN) 内连接(INNER JOIN):返回两表匹配的记录。 SELECT e.name, d.dept_name FROM employees e INNER JOIN departments d ON e.dept_id d.dept_id; 左…...
线程同步:确保多线程程序的安全与高效!
全文目录: 开篇语前序前言第一部分:线程同步的概念与问题1.1 线程同步的概念1.2 线程同步的问题1.3 线程同步的解决方案 第二部分:synchronized关键字的使用2.1 使用 synchronized修饰方法2.2 使用 synchronized修饰代码块 第三部分ÿ…...
python如何将word的doc另存为docx
将 DOCX 文件另存为 DOCX 格式(Python 实现) 在 Python 中,你可以使用 python-docx 库来操作 Word 文档。不过需要注意的是,.doc 是旧的 Word 格式,而 .docx 是新的基于 XML 的格式。python-docx 只能处理 .docx 格式…...

【Zephyr 系列 10】实战项目:打造一个蓝牙传感器终端 + 网关系统(完整架构与全栈实现)
🧠关键词:Zephyr、BLE、终端、网关、广播、连接、传感器、数据采集、低功耗、系统集成 📌目标读者:希望基于 Zephyr 构建 BLE 系统架构、实现终端与网关协作、具备产品交付能力的开发者 📊篇幅字数:约 5200 字 ✨ 项目总览 在物联网实际项目中,**“终端 + 网关”**是…...

12.找到字符串中所有字母异位词
🧠 题目解析 题目描述: 给定两个字符串 s 和 p,找出 s 中所有 p 的字母异位词的起始索引。 返回的答案以数组形式表示。 字母异位词定义: 若两个字符串包含的字符种类和出现次数完全相同,顺序无所谓,则互为…...
OpenPrompt 和直接对提示词的嵌入向量进行训练有什么区别
OpenPrompt 和直接对提示词的嵌入向量进行训练有什么区别 直接训练提示词嵌入向量的核心区别 您提到的代码: prompt_embedding = initial_embedding.clone().requires_grad_(True) optimizer = torch.optim.Adam([prompt_embedding...
Android Bitmap治理全解析:从加载优化到泄漏防控的全生命周期管理
引言 Bitmap(位图)是Android应用内存占用的“头号杀手”。一张1080P(1920x1080)的图片以ARGB_8888格式加载时,内存占用高达8MB(192010804字节)。据统计,超过60%的应用OOM崩溃与Bitm…...

安宝特方案丨船舶智造的“AR+AI+作业标准化管理解决方案”(装配)
船舶制造装配管理现状:装配工作依赖人工经验,装配工人凭借长期实践积累的操作技巧完成零部件组装。企业通常制定了装配作业指导书,但在实际执行中,工人对指导书的理解和遵循程度参差不齐。 船舶装配过程中的挑战与需求 挑战 (1…...

Linux 内存管理实战精讲:核心原理与面试常考点全解析
Linux 内存管理实战精讲:核心原理与面试常考点全解析 Linux 内核内存管理是系统设计中最复杂但也最核心的模块之一。它不仅支撑着虚拟内存机制、物理内存分配、进程隔离与资源复用,还直接决定系统运行的性能与稳定性。无论你是嵌入式开发者、内核调试工…...

三分算法与DeepSeek辅助证明是单峰函数
前置 单峰函数有唯一的最大值,最大值左侧的数值严格单调递增,最大值右侧的数值严格单调递减。 单谷函数有唯一的最小值,最小值左侧的数值严格单调递减,最小值右侧的数值严格单调递增。 三分的本质 三分和二分一样都是通过不断缩…...