当前位置: 首页 > news >正文

顺序表(数据结构与算法)

请添加图片描述
✅✅✅✅✅✅✅✅✅✅✅✅✅✅✅✅
✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨
🌿🌿🌿🌿🌿🌿🌿🌿🌿🌿🌿🌿🌿🌿🌿🌿
🌟🌟🌟🌟🌟🌟🌟🌟🌟🌟🌟🌟🌟🌟🌟🌟
🌟🌟 无人扶我青云志 🌟🌟
🍀🍀🍀🍀🍀🍀🍀🍀🍀🍀🍀🍀🍀🍀🍀🍀
🌟🌟 我自踏雪之山巅🌟🌟
🌟🌟🌟🌟🌟🌟🌟🌟🌟🌟🌟🌟🌟🌟🌟🌟
🌿🌿🌿🌿🌿🌿🌿🌿🌿🌿🌿🌿🌿🌿🌿🌿
✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨
✅✅✅✅✅✅✅✅✅✅✅✅✅✅✅✅

🍋顺序表

  • 🍌顺序表的定义
  • 🍌顺序表的结构
    • 🍍静态顺序表
    • 🍍动态顺序表
  • 🍌顺序表接口的实现(增删查改)
    • 🍍其它接口
    • 🍍顺序表初始化
    • 🍍检查空间是否增容(空间满了就增容)
    • 🍍顺序表尾插
    • 🍍顺序表尾删
    • 🍍顺序表头插
    • 🍍顺序表头删
    • 🍍顺序表查找
    • 🍍顺序表在pos位置插入x
    • 🍍顺序表删除pos位置的值
    • 🍍顺序表修改pos位置的值
    • 🍍顺序表销毁
    • 🍍顺序表打印
  • 🍌顺序表整体代码的实现

🍌顺序表的定义

顺序表是在计算机内存中以数组的形式保存的线性表,线性表的顺序存储是指用一组地址连续的存储单元依次存储线性表中的各个元素、使得线性表中在逻辑结构上相邻的数据元素存储在相邻的物理存储单元中,即通过数据元素物理存储的相邻关系来反映数据元素之间逻辑上的相邻关系,采用顺序存储结构的线性表通常称为顺序表。顺序表是将表中的结点依次存放在计算机内存中一组地址连续的存储单元中。

在这里插入图片描述

线性表:线性表是最基本、最简单、也是最常用的一种数据结构。大部分线性表除了第一个和最后一个数据元素之外,其它数据元素都是首尾相接的。而又一些小部分,比如,循环链表逻辑层次上也是一种线性表(存储层次上属于链式存储,但是把最后一个数据元素的尾指针指向了首位结点

🍌顺序表的结构

🍍静态顺序表

静态顺序表就是以一定长度的数组来存储元素

//静态存储
#define  N  5
typedef int SLDetatype ;
typedef struct SeqList
{SLDetatype a[N] ;//有限空间的数组int size ;//有效的数据个数
}SeqList;

在这里插入图片描述

🍍动态顺序表

动态顺序表使用动态开辟的数组来存储元素

//动态存储
typedef  int SLDetatype ;
typedef struct SeqList
{SLDetatype *a ;   //指向动态开辟的数组int size ;       //有效的数据个数int capicity ;   //空间的容量
}SeqList;

在这里插入图片描述

🍌顺序表接口的实现(增删查改)

🍍其它接口

#include<stdio.h>
#include<assert.h>
#include<stdlib.h>
#include<stdbool.h>typedef int SLDatatype;
typedef struct SeqList
{SLDatatype* a;int capacity;int size;
}SeqList;

🍍顺序表初始化

void SeqListInit(SeqList* ps)
{ps->a = NULL;            //在初始情况我们可以直接置空//当然也可以创建空间,看自己习惯ps->capacity = ps->size = 0;
}

🍍检查空间是否增容(空间满了就增容)

void CheckCapacity(SeqList* ps)
{assert(ps);//在两个相等时,空间可能会满,还可能空间为0,这是因为我们在初始化没有创建空间导致if (ps->capacity == ps->size){if (ps->capacity == 0)ps->capacity = 2;elseps->capacity *= 2;int newcapacity = ps->capacity;//在扩容时,我们都是利用realloc,创建空间利用mallocSLDatatype* cur = (SLDatatype*)realloc(ps->a, sizeof(SLDatatype) * newcapacity);if (cur == NULL){perror("realloc   faild");exit(-1);}ps->a = cur;ps->capacity = newcapacity;}
}

大家如果对于malloc和realloc以及空间的创建的用法有些遗忘,可以看我这篇博客:动态内存管理(这是一个链接,有需要的朋友可以直接点进去)

🍍顺序表尾插

void SeqListPushBack(SeqList* ps, SLDatatype x)
{assert(ps);CheckCapacity(ps);  //需要检查空间是否满或者空ps->a[ps->size] = x;(ps->size)++;
}

在这里插入图片描述

🍍顺序表尾删

//顺序表尾删
void SeqListPopBack(SeqList* ps)
{assert(ps);assert(ps->size > 0);  //检查数据个数是否为0,如果为0就不执行,反之亦然(ps->size)--;
}

在这里插入图片描述

🍍顺序表头插

// 顺序表头插
void SeqListPushFront(SeqList* ps, SLDatatype x)
{assert(ps);CheckCapacity(ps);//判断空间是否满还是空//注意头插要分两种情况//第一种是数组里没有元素,此时头插就是相当于尾插//第二种是数组里有元素,这时就先把整体元素往后移动一位if (ps->size - 1 == 0){ps->a[ps->size -1] = x;(ps->size)++;}else{int end = ps->size - 1;while (end >= 0){ps->a[end + 1] = ps->a[end];end--;}ps->a[0] = x;(ps->size)++;}
}

注意
注意头插要分两种情况
(1)第一种是数组里没有元素,此时头插就是相当于尾插
(2)第二种是数组里有元素,这时就先把整体元素往后移动一位

在这里插入图片描述

🍍顺序表头删

// 顺序表头删
void SeqListPopFront(SeqList* ps)
{assert(ps);assert(ps->size > 0);//注意头删要分两种情况//第一种是数组里没有元素,此时头删就是相当于尾删//第二种是数组里有元素,这时就需要把除了第一个元素外的所有元素往前移动一位,把原来的第一位元素覆盖if (ps->size - 1 == 0){(ps->size)--;}else{int end = 0;while (end < ps->size - 1){ps->a[end] = ps->a[end + 1];end++;}(ps->size)--;}
}

注意:
注意头删要分两种情况
(1)第一种是数组里没有元素,此时头删就是相当于尾删
(2)第二种是数组里有元素,这时就需要把除了第一个元素外的所有元素往前移动一位,把原来的第一位元素覆盖

在这里插入图片描述

🍍顺序表查找

// 顺序表查找
int SeqListFind(SeqList* ps, SLDatatype x)
{assert(ps);int i = 0;for (int i = 0; i < ps->size; i++){if (ps->a[i] == x)return 1;}return -1;
}

🍍顺序表在pos位置插入x

// 顺序表在pos位置插入x
void SeqListInsert(SeqList* ps, int pos, SLDatatype x)
{assert(ps);assert(pos >= 0 && pos <= ps->size);CheckCapacity(ps);int i = 0;for (i = pos - 1; i < ps->size - 1; i++){ps->a[i + 1] = ps->a[i];}ps->a[pos-1] = x;(ps->size)++;
}

注意:pos必须在0到ps->size之间

在这里插入图片描述

🍍顺序表删除pos位置的值

// 顺序表删除pos位置的值
void SeqListErase(SeqList* ps, int pos)
{assert(ps);assert(pos >= 0 && pos <= ps->size);int i = 0;for (i = pos - 1; i < ps->size - 1; i++){ps->a[i] = ps->a[i + 1];}(ps->size)--;
}

注意:pos必须在0到ps->size之间

🍍顺序表修改pos位置的值

//顺序表修改pos位置的值
void SeqModify(SeqList* ps, int pos, SLDatatype x)
{assert(ps);assert(pos >= 0 && pos < ps->size);ps->a[pos - 1] = x;
}

🍍顺序表销毁

// 顺序表销毁
void SeqListDestory(SeqList* ps)
{assert(ps);free(ps->a);ps->a = NULL;ps->size = ps->capacity = 0;
}

🍍顺序表打印

// 顺序表打印
void SeqListPrint(SeqList* ps)
{assert(ps);int i = 0;for (i = 0; i < ps->size; i++){printf("%d ", ps->a[i]);}printf("\n");
}

🍌顺序表整体代码的实现

#include<stdio.h>
#include<assert.h>
#include<stdlib.h>
#include<stdbool.h>typedef int SLDatatype;
typedef struct SeqList
{SLDatatype* a;int capacity;int size;
}SeqList;//顺序表初始化
void SeqListInit(SeqList* ps)
{ps->a = NULL;ps->capacity = ps->size = 0;
}//检查空间,如果满了就增容
void CheckCapacity(SeqList* ps)
{assert(ps);if (ps->capacity == ps->size){if (ps->capacity == 0)ps->capacity = 2;elseps->capacity *= 2;int newcapacity = ps->capacity;SLDatatype* cur = (SLDatatype*)realloc(ps->a, sizeof(SLDatatype) * newcapacity);if (cur == NULL){perror("realloc   faild");exit(-1);}ps->a = cur;ps->capacity = newcapacity;}
}//顺序表尾插
void SeqListPushBack(SeqList* ps, SLDatatype x)
{assert(ps);CheckCapacity(ps);ps->a[ps->size] = x;(ps->size)++;
}//顺序表尾删
void SeqListPopBack(SeqList* ps)
{assert(ps);assert(ps->size > 0);(ps->size)--;
}// 顺序表头插
void SeqListPushFront(SeqList* ps, SLDatatype x)
{assert(ps);CheckCapacity(ps);if (ps->size == 0){ps->a[ps->size] = x;(ps->size)++;}else{int end = ps->size - 1;while (end >= 0){ps->a[end + 1] = ps->a[end];end--;}ps->a[0] = x;(ps->size)++;}
}// 顺序表头删
void SeqListPopFront(SeqList* ps)
{assert(ps);assert(ps->size > 0);if (ps->size - 1 == 0){(ps->size)--;}else{int end = 0;while (end < ps->size - 1){ps->a[end] = ps->a[end + 1];end++;}(ps->size)--;}
}// 顺序表查找
int SeqListFind(SeqList* ps, SLDatatype x)
{assert(ps);int i = 0;for (int i = 0; i < ps->size; i++){if (ps->a[i] == x)return 1;}return -1;
}// 顺序表在pos位置插入x
void SeqListInsert(SeqList* ps, int pos, SLDatatype x)
{assert(ps);assert(pos >= 0 && pos <= ps->size);CheckCapacity(ps);int i = 0;for (i = pos - 1; i < ps->size - 1; i++){ps->a[i + 1] = ps->a[i];}ps->a[pos-1] = x;(ps->size)++;
}// 顺序表删除pos位置的值
void SeqListErase(SeqList* ps, int pos)
{assert(ps);assert(pos >= 0 && pos <= ps->size);int i = 0;for (i = pos - 1; i < ps->size - 1; i++){ps->a[i] = ps->a[i + 1];}(ps->size)--;
}// 顺序表销毁
void SeqListDestory(SeqList* ps)
{assert(ps);free(ps->a);ps->a = NULL;ps->size = ps->capacity = 0;
}// 顺序表打印
void SeqListPrint(SeqList* ps)
{assert(ps);int i = 0;for (i = 0; i < ps->size; i++){printf("%d ", ps->a[i]);}printf("\n");
}//顺序表修改pos位置的值
void SeqModify(SeqList* ps, int pos, SLDatatype x)
{assert(ps);assert(pos >= 0 && pos < ps->size);ps->a[pos - 1] = x;
}void test1()
{SeqList cur;SeqListInit(&cur);SeqListPushBack(&cur, 500);//尾插SeqListPushBack(&cur, 400);//尾插SeqListPushBack(&cur, 300);//尾插SeqListPrint(&cur);SeqListPopBack(&cur);//尾删SeqListPrint(&cur);SeqListPushFront(&cur, 100);//头插SeqListPushFront(&cur, 200);//头插SeqListPushFront(&cur, 600);//头插SeqListPrint(&cur);SeqListPopFront(&cur); //头删SeqListPrint(&cur);if (SeqListFind(&cur,200) == 1)//元素查找printf("找到了\n");else{printf("没有找到\n");}SeqListInsert(&cur, 3, 999);//在pos位置插入xSeqListPrint(&cur);SeqListErase(&cur, 3);//删除pos位置的值SeqListPrint(&cur);SeqModify(&cur, 3, 666); //修改pos位置的值SeqListPrint(&cur);
}int main()
{test1();return 0;
}

请添加图片描述

相关文章:

顺序表(数据结构与算法)

✅✅✅✅✅✅✅✅✅✅✅✅✅✅✅✅ ✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨ &#x1f33f;&#x1f33f;&#x1f33f;&#x1f33f;&#x1f33f;&#x1f33f;&#x1f33f;&#x1f33f;&#x1f33f;&#x1f33f;&#x1f33f;&#x1f33f;&#x1f33f;&#x1f33f;&#x1…...

【大连民族大学C语言CG题库练习题】——判断一个矩阵是另一个矩阵的子矩阵

【问题描述】 从标准输入中输入一个N&#xff08;N<9&#xff09;阶矩阵和一个M&#xff08;M<N&#xff09;阶矩阵&#xff0c;判断矩阵M是否是N的子矩阵&#xff0c;若是则输出M在N中的起始位置&#xff0c;若不是则输出-1。若矩阵M能与N中某一区域完全相等&#xff0…...

C#WPF控制模板实例

一、控制模板 ControlTemplate(控件模板)不仅是用于来定义控件的外观、样式, 还可通过控件模板的触发器(ControlTemplate.Triggers)修改控件的行为、响应动画等。 控件模板定义控件的视觉外观,所有的 UI 元素都具有某种外观和行为,例如,Button 具有外观和行为。单击事件或…...

MATLAB Simulink和S7-1200PLC MOBUSTCP通信

MATLAB Simulink和SMART PLC OPC通信详细配置请查看下面文章链接: MATLAB和西门子SMART PLC OPC通信-CSDN博客文章浏览阅读749次,点赞26次,收藏2次。西门子S7-200SMART PLC OPC软件的下载和使用,请查看下面文章Smart 200PLC PC Access SMART OPC通信_基于pc access smart的…...

五、函数的介绍

1、为什么需要函数 (1)当程序足够简单时&#xff0c;一个main函数就可以实现所有功能。随着程序功能的增加、复杂化&#xff0c;超出人的大脑的承受范围&#xff0c;这时一个main函数可能就逻辑不清了。这是就需要把一个大程序分成许多小的模块来组织&#xff0c;于是乎出现了…...

【广州华锐互动VRAR】VR元宇宙技术在气象卫星知识科普中的应用

随着科技的不断发展&#xff0c;虚拟现实&#xff08;VR&#xff09;和元宇宙等技术正逐渐走进我们的生活。这些技术为我们提供了一个全新的互动平台&#xff0c;使我们能够以更加直观和生动的方式了解和学习各种知识。在气象天文领域&#xff0c;VR元宇宙技术的应用也日益显现…...

F. Alex‘s whims Codeforces Round 909 (Div. 3) 1899F

Problem - F - Codeforces 题目大意&#xff1a;有q次询问&#xff0c;每次询问给出一个数x&#xff0c;要求构造一棵n个点的树&#xff0c;使得对于每次询问&#xff0c;树上都有一条简单路径的长度等于x&#xff0c;同时每次询问前可以对树进行一次操作&#xff0c;即将一个…...

面试题-5

1.用递归的时候有没有遇到什么问题&#xff1f; 如果一个函数内可以调用函数本身,那么这个就是递归函数 函数内部调用自己 特别注意:写递归必须要有退出条件return 2.如何实现一个深拷贝 深拷贝就是完全拷贝一份新的对象,会在堆内存中开辟新的空间,拷贝的对象被修改后&…...

车载以太网-ARP

文章目录 车载以太网ARP协议ARP协议帧格式ARP报文示例ARP报文完整流程ARP流程报文示例ARP协议测试 车载以太网ARP协议 车载以太网ARP协议是指在车载以太网中使用的ARP协议。ARP&#xff08;Address Resolution Protocol&#xff09;是一种用于将IP地址解析为MAC地址的协议。在…...

Kafka学习笔记(三)

目录 第5章 Kafka监控&#xff08;Kafka Eagle&#xff09;5.2 修改kafka启动命令5.2 上传压缩包5.3 解压到本地5.4 进入刚才解压的目录5.5 将kafka-eagle-web-1.3.7-bin.tar.gz解压至/opt/module5.6 修改名称5.7 给启动文件执行权限5.8 修改配置文件5.9 添加环境变量5.10 启动…...

JVM-HotSpot虚拟机对象探秘

目录 一、对象的实例化 &#xff08;一&#xff09;创建对象的方式 &#xff08;二&#xff09;创建对象的步骤 二、对象的内存布局 &#xff08;一&#xff09;对象头 &#xff08;二&#xff09;实例数据 &#xff08;三&#xff09;对齐填充 三、 对象的访问定位 &…...

大模型技术的发展:开源和闭源,究竟谁强谁弱又该何去何从?

一、开源和闭源的优劣势比较 开源和闭源软件都有各自的优劣势&#xff0c;具体比较如下&#xff1a; 安全性&#xff1a;闭源软件的安全性相对较高&#xff0c;因为其源代码不公开&#xff0c;攻击者难以找到漏洞进行攻击。而开源软件由于源代码公开&#xff0c;容易被攻击者发…...

Python学习笔记--自定义元类

四、自定义元类 到现在&#xff0c;我们已经知道元类是什么鬼东西了。 那么&#xff0c;从始至终我们还不知道元类到底有啥用。 只是了解了一下元类。 在了解它有啥用的时候&#xff0c;我们先来了解下怎么自定义元类。 因为只有了解了怎么自定义才能更好的理解它的作用。…...

软件测试 —— 常见的自动化测试架构!

一个自动化测试架构就是一个集成体系&#xff0c;其中定义了一个特殊软件产品的自动化测试规则。这一体系中包含测试功能函数库、测试数据源、测试对象识别标准&#xff0c;以及各种可重用的模块。这些组件作为小的构建模块&#xff0c;被组合起来代表某种商业流程。自动化测试…...

Python 的 @lru_cache() 装饰器

在 Python 标准库的 functools 模块中&#xff0c;有个 lru_cache 装饰器&#xff0c;用于为一个函数添加缓存系统&#xff1a; 存储函数的输入和对应的输出当函数被调用&#xff0c;并且给出了已经缓存过的输入&#xff0c;那么函数不会再运行&#xff0c;而是直接从缓存中获…...

Swift制作打包framework

新建framework项目 设置生成fat包&#xff0c;包括模拟器x86_64和arm64 Buliding Settings -> Architectures -> Build Active Architecture Only 设置为NO 设置打包环境&#xff0c;选择release edit Scheme -> run -> Build configuration 设置为 Release 设置…...

无线WiFi安全渗透与攻防(N.2)WPA渗透-使用airolib-ng创建彩虹表加速

WPA渗透-使用airolib-ng创建彩虹表加速 WPA渗透-使用airolib-ng创建彩虹表加速1.什么是彩虹表?2.渗透wifi1.创建数据库名2.将字典导入数据库3.生成渗透wifi密码的PMK4.生成需要渗透wifi的彩虹表5.渗透wifiWPA渗透-使用airolib-ng创建彩虹表加速 1.什么是彩虹表? 彩虹表是一…...

整形数据和浮点型数据在内存中的存储差别

愿所有美好如期而遇 我们先来看代码&#xff0c;猜猜结果是什么呢&#xff1f; int main() {//以整型数据的方式存储int n 10;float* m (float*)&n;//以整型数据的方式读取printf("%d\n", n);//以浮点型数据的方式2读取printf("%f\n", *m);printf(&…...

【Python基础篇】运算符

博主&#xff1a;&#x1f44d;不许代码码上红 欢迎&#xff1a;&#x1f40b;点赞、收藏、关注、评论。 格言&#xff1a; 大鹏一日同风起&#xff0c;扶摇直上九万里。 文章目录 一 Python中的运算符二 算术运算符1 Python所有算术运算符的说明2 Python算术运算符的所有操作…...

开启数据库审计 db,extended级别或os级别)并将审计文件存放到/opt/oracle/audit/下

文章目录 1、登录到数据库2、查看审计状态3、创建审计目录4、启用审计5、设置审计文件路径6、再次查看结果 1、登录到数据库 使用SQL*Plus或者其他Oracle数据库客户端登录到数据库。 sqlplus / as sysdba;2、查看审计状态 show parameter audit;目前是DB状态&#xff0c;并且…...

解决本地部署 SmolVLM2 大语言模型运行 flash-attn 报错

出现的问题 安装 flash-attn 会一直卡在 build 那一步或者运行报错 解决办法 是因为你安装的 flash-attn 版本没有对应上&#xff0c;所以报错&#xff0c;到 https://github.com/Dao-AILab/flash-attention/releases 下载对应版本&#xff0c;cu、torch、cp 的版本一定要对…...

06 Deep learning神经网络编程基础 激活函数 --吴恩达

深度学习激活函数详解 一、核心作用 引入非线性:使神经网络可学习复杂模式控制输出范围:如Sigmoid将输出限制在(0,1)梯度传递:影响反向传播的稳定性二、常见类型及数学表达 Sigmoid σ ( x ) = 1 1 +...

鸿蒙DevEco Studio HarmonyOS 5跑酷小游戏实现指南

1. 项目概述 本跑酷小游戏基于鸿蒙HarmonyOS 5开发&#xff0c;使用DevEco Studio作为开发工具&#xff0c;采用Java语言实现&#xff0c;包含角色控制、障碍物生成和分数计算系统。 2. 项目结构 /src/main/java/com/example/runner/├── MainAbilitySlice.java // 主界…...

大语言模型(LLM)中的KV缓存压缩与动态稀疏注意力机制设计

随着大语言模型&#xff08;LLM&#xff09;参数规模的增长&#xff0c;推理阶段的内存占用和计算复杂度成为核心挑战。传统注意力机制的计算复杂度随序列长度呈二次方增长&#xff0c;而KV缓存的内存消耗可能高达数十GB&#xff08;例如Llama2-7B处理100K token时需50GB内存&a…...

Springboot社区养老保险系统小程序

一、前言 随着我国经济迅速发展&#xff0c;人们对手机的需求越来越大&#xff0c;各种手机软件也都在被广泛应用&#xff0c;但是对于手机进行数据信息管理&#xff0c;对于手机的各种软件也是备受用户的喜爱&#xff0c;社区养老保险系统小程序被用户普遍使用&#xff0c;为方…...

Go 语言并发编程基础:无缓冲与有缓冲通道

在上一章节中&#xff0c;我们了解了 Channel 的基本用法。本章将重点分析 Go 中通道的两种类型 —— 无缓冲通道与有缓冲通道&#xff0c;它们在并发编程中各具特点和应用场景。 一、通道的基本分类 类型定义形式特点无缓冲通道make(chan T)发送和接收都必须准备好&#xff0…...

【LeetCode】算法详解#6 ---除自身以外数组的乘积

1.题目介绍 给定一个整数数组 nums&#xff0c;返回 数组 answer &#xff0c;其中 answer[i] 等于 nums 中除 nums[i] 之外其余各元素的乘积 。 题目数据 保证 数组 nums之中任意元素的全部前缀元素和后缀的乘积都在 32 位 整数范围内。 请 不要使用除法&#xff0c;且在 O…...

mac:大模型系列测试

0 MAC 前几天经过学生优惠以及国补17K入手了mac studio,然后这两天亲自测试其模型行运用能力如何&#xff0c;是否支持微调、推理速度等能力。下面进入正文。 1 mac 与 unsloth 按照下面的进行安装以及测试&#xff0c;是可以跑通文章里面的代码。训练速度也是很快的。 注意…...

react菜单,动态绑定点击事件,菜单分离出去单独的js文件,Ant框架

1、菜单文件treeTop.js // 顶部菜单 import { AppstoreOutlined, SettingOutlined } from ant-design/icons; // 定义菜单项数据 const treeTop [{label: Docker管理,key: 1,icon: <AppstoreOutlined />,url:"/docker/index"},{label: 权限管理,key: 2,icon:…...

深入解析 ReentrantLock:原理、公平锁与非公平锁的较量

ReentrantLock 是 Java 中 java.util.concurrent.locks 包下的一个重要类,用于实现线程同步,支持可重入性,并且可以选择公平锁或非公平锁的实现方式。下面将详细介绍 ReentrantLock 的实现原理以及公平锁和非公平锁的区别。 ReentrantLock 实现原理 基本架构 ReentrantLo…...