【数据结构】查找与排序

news2025/2/6 3:07:42

要查询信息,涉及两个问题:

在哪里查?——查找表

怎么查?——查找方法

一.查找

1.查找表的定义:

查找表是由同类型的数据元素构成的集合

2.对查找表的基本操作:

1)查询某个数据元素是否在查找表中

2)检索某个数据元素的各种属性

3)在查找表中插入一个数据元素

4)从查找表中删除某个元素

3.查找表的分类:

静态查找表:

仅作查询和检索操作的查找表

动态查找表:

可以进行“插入”和“删除”操作

4.关键字:

关键字:是数据元素中某个数据项的值,用以标识一个数据元素。

主关键字:若关键字能标识唯一的一个数据元素

次关键字:若关键字能标识若干个数据元素

5.查找:

根据给定的某个值,在查找表中确定一个其关键字等于给定值的数据元素。

6.查找方法评价:

  • 算法本身的时间复杂度
  • 临时变量占用存储空间的多少
  • 平均查找长度ASL(Average Search Length)

对于含有n个记录的表,ASL=\sum_{i=1}^{n}p_ic_i

其中,p_i为查找表中第i个元素的概率,\sum_{i=1}^{n}p_i=1

c_i为找到表中第i个元素所需要比较的次数

7. 顺序表的查找:

7.1 基本思想:

从表中指定位置的记录开始,沿着某个方向将记录的关键字与给定值相比较,若某个记录的关键字与给定值相同,则查找成功。

反之,若找完整个顺序表,都没有与给定关键字值相同的记录,则查找失败。

7.2 顺序查找的性能分析:

查找第n个元素:1次

查找第n-1个元素:2次

...

查找第1个元素:n次

查找第i个元素:n+1-i次

查找失败:n+1次

空间复杂度:

需要一个辅助空间R[0]

时间复杂度:

ASL=\sum_{i=1}^{n}p_ic_i         c_i=n-i+1

等概率情况下:ASL=\frac{n+1}{2}

平均情况:O(n)

优点:算法简单,适用面广

缺点:平均查找长度较大

 8.折半查找

8.1 基本思想:

查找过程:每次将待查记录所在区间缩小一半。

适用条件:采用顺序存储的有序表

8.2 伪代码:

设表长为n,low、high和mid分别指向待查元素所在区间的上界、下界和中点,k为给定值。

初始时,令low=0,high=n-1,mid=(high+low)/2。

让k与mid指向的记录比较

  • 若k==r[mid].key 查找成功
  • 若k<r[mid].key 则high=mid-1
  • 若k>r[mid].key 则low=mid+1

重复上述操作,直至low>high为止,查找失败。

int biserach(int r[],int n,int k){
    int low=0,high=n-1,mid=0;
    while(low<=high){
        mid=(low+high)/2;
        if(r[mid]==k){
            break;
        }
        else if(r[mid]>k){
            high=mid-1;
        }
        else{
            low=mid+1;
        }
    }
    if(low>high){
        return -1;
    }
    else{
        return mid;
    }
}

8.3 算法性能分析:

判定树:描述查找过程的二叉树

有n个结点的判定树的层次数为$\lfloor log_2n\rfloor +1$

折半查找在查找过程中进行的比较次数最多不超过其判定树的深度。

折半查找的ASL:

设表长为2^h-1,h=log_2{(n+1)},即判定树为深度为h的满二叉树

设表中每个记录的查找概率相等

ASL=\sum_{i=1}^{n}p_ic_i=\frac{1}{n} \sum_{i=1}^{n}c_i=\frac{1}{n}\sum_{j=1}^{h}j*2^{j-1}=\frac{n+1}{n}log_2{(n+1)}-1\approx log_2(n+1)-1 

8.4 折半查找的特点:

1)查找效率高

2)平均查找性能和最坏性能相当接近

3)要求查找表为有序表

4)只适用于顺序存储结构

9.索引表查找

9.1 索引表的构建

数据分块

按关键字分成若干块R_1,R_2,...,R_L,R_k<R_{k+1},达到分块有序。

建索引项

每一个块建立一个索引项,每个索引项包含最大关键字项,块的起始地址。

组成索引表

所有索引项组成索引表

9.2 索引表的查找:

索引表内查找:确定关键字所在区块。

查找表内查找:查找表的某个块内查找

9.3 索引表查找的代码实现:

typedef struct{
    int key;
    int link;
}SD;
typedef struct{
    int key;
    float info;
}JD;
int block_search(JD r[],SD nd[],int b,int k,int n){//n个记录分成b块
    int i=0,j;
    while(k>nd[i].key&&i<b){
        i++;
    }
    if(i>=b){
        cout<<"not found"<<endl;
        return -1;
    }
    else{
        //在块内顺序查找
        j=nd[i].link;
        while(j<n&&k!=r[j].key){
            j++;
        }
        if(k!=r[j].key){
            cout<<"not found"<<endl;
            return -1;
        }
        else{
            return j;
        }
    }
}

9.4 分块查找方法评价:

ASL=L_b+L_w 

若将表长为n的表平均分成b块,每块含有s个记录,并设表中每个记录的查找概率相等。

则有:

1)用顺序查找确定所在块:

ASL=\frac{1}{b}\sum_{j=1}^bj+\frac{1}{s}\sum_{i=1}^si=\frac{b+1}{2}+\frac{s+1}{2}=\frac{1}{2}(\frac{n}{s}+s)+1

2)用折半查找确定所在块:

ASL\approx log_2(\frac{n}{s}+1)+\frac{s}{2}

10.查找方法比较

顺序查找折半查找索引查找
ASL最大最小两者之间
表结构有序表、无序表有序表分块有序表
存储结构顺序存储、单链表顺序存储顺序存储、单链表

11.哈希表查找 

ASL=1的查找算法。

如果可以确定关键字与存储位置的对应关系,就有可能让ASL=1.

11.1 哈希查找的基本定义:

哈希函数:在记录的关键字与记录的存储地址之间建立的一种对应关系

哈希查找:又叫散列查找,利用哈希函数进行查找的过程。

哈希函数是一种映射,即从关键字空间到存储地址空间的一种映射

哈希函数可以写成:

H(k_i)=addr(k_i)

11.2 冲突

哈希函数通常是一种压缩映射,所以冲突不可避免。

冲突发生后,应该有处理冲突的方法。

(1)直接定址法(线性函数):

例如:H(key)=key-1948

 直接定址法所得地址集合与关键字集合大小相等,不会发生冲突。

 (2)数字分析法:

对关键字进行分析,取关键字的若干位或其组合作为哈希地址。

适用于关键字位数比哈希地址位数大,且可能出现的关键字事先知道的情况。

(3)平方取中法:

取关键字平方后的中间几位作为哈希地址

为什么要取关键字的平方值?

  • 扩大差别 
  • 均衡贡献

(4)折叠法:

将关键字分割为位数相同的几部分,然后取这几部分的叠加和(舍去进位)作哈希地址。

适用于关键字位数很多,且每一位上数字分布大致均匀的情况

例如: 关键字为 04 4220 5864 哈希地址位数为4

移位叠加:                                        间界叠加:

5        8        6        4                        5        8        6        4

4        2        2        0                        0        2        2        4

0        0        0        4                        0        0        0        4

---------------------------------------------------------------------------

(5)除留余数法:

H(key)=key MOD p,p<=m,m为hash表长。

p选取不好,容易产生同义词,通常选取一个质数。

(6)伪随机数法

取关键字的随机函数作哈希地址值,即:H(key)=random(key)

适用于关键字长度不等的情况。

11.3 选取哈希函数需要考虑的因素:

1)计算哈希函数所需的时间

2)关键字长度

3)哈希表长度

4)关键字分布情况

5)记录的查找频率

11.4 冲突处理

为出现哈希地址冲突的关键字寻找下一个新的哈希地址。

(1)开放定址法:

当冲突发生时,形成一个探查序列,沿着此序列逐个地址探查,直到找到一颗空位置,将发生冲突的记录放入该地址中,即H_i=(H(key)+di)MOD \quad m

m 哈希表表长,di 增量序列。

增量序列分类:

线性探测再散列 di=1,2,3,...,m-1

平方探测再散列 di=1^2,-1^2,2^2,-2^2,...,\pm k^2(k\leq m/2)

伪随机探测再散列 di=伪随机数序列

例:

(2)再哈希法:

构造若干个哈希函数,当发生冲突时,计算下一个哈希地址。

(3)链地址法:

将所有关键字为同义词的记录存储在一个单链表中,并用一位数组存放头指针。

(4)公共溢出区法

假设某哈希函数的值域为[o,m-1]

向量HashTable[0,m-1]为基本表,每个分量存放一个记录,另设一个向量OverTable[0,v]为溢出表。将与基本表中的关键字发生冲突的所有记录都填入溢出表中。

11.5 例题分析

已知一组关键字(19,14,23,1,68,20,84,27,55,11,10,79)

哈希函数为H(key)=key MOD 13 ,哈希表长为16,设每个记录的查找概率相等。

1)线性探测再散列处理冲突
0123456789101112131415
14168275519208479231110

1 1 1 2 1 1 3 4 3 1 3 9

ASL=30/12=2.5

2)链地址法处理冲突

ASL=(6*1+4*2+1*3+1*4)/12=1.75

11.6 哈希查找分析

哈希查找过程仍然是一个给定值与关键字进行比较的过程

评价哈希查找仍要用ASL

哈希查找过程与给定值进行关键字比较的次数取决于:

  • 哈希函数
  • 处理冲突的方法
  • 哈希表的装载因子\alpha

\alpha =k/L

k:表中填入的记录数

L:哈希表长度

二.排序

1.内部排序的方法:

内部排序的过程是一个逐步扩大有序区记录的过程

2.排序分为:

  • 稳定排序
  • 不稳定排序

3.直接插入排序(稳定):

3.1 基本思想:

先将序列中第一个记录看成是一个有序子序列,然后从第二个记录开始,逐个进行插入,直至整个序列有序。整个排序过程为n-1躺插入。

3.2 具体例子:

i=1        49 38 65 97 76 13 27

i=2        38 49 65 97 76 13 27

i=3        38 49 65 97 76 13 27

i=4        38 49 65 97 76 13 27

i=5        38 49 65 76 97 13 27

i=6        13 38 49 65 97 76 27

i=7        13 27 38 49 65 76 97

3.3 代码实现:

void insert_select(int r[],int n){
    int i,j,temp;
    for(i=1;i<n;i++){
        temp=r[i];
        j=i-1;
        while(temp<r[j]){
            r[j+1]=r[j];
            --j;
        }
        r[j+1]=temp;
    }
}

3.4 算法评价:

时间复杂度:

O(n^2)

空间复杂度:

O(1 )

4.折半插入排序(稳定)

4.1 基本思想:

用折半查找方法确定插入位置的排序

4.2 算法分析:

时间复杂度:

O(n^2)

空间复杂度:

O(1 )

5.希尔排序(缩小增量法)(非稳定)

5.1 基本思想:

希尔排序是对插入排序的改进。

(1) 插入排序对几乎已排好序的数据操作时,效率很高,可以达到线性排序的效率。 

(2) 插入排序在每次往前插入时只能将数据移动一位,效率比较低。

先将整个待排元素序列分割成若干个子序列(由相隔某个“增量”的元素组成的)分别进行直接插入排序,然后依次缩减增量再进行排序,待整个序列中的元素基本有序(增量足够小)时,再对全体元素进行一次直接插入排序。

局部有序不能提高直接插入排序算法的时间性能

5.2 代码实现:

void shell_sort(int r[],int n){
    int di=n/2,i,j,temp;
    while(di>=1){
        for(i=di;i<n;i++){
            j=i-di;
            temp=r[i];
            while(temp>r[j]&&j>=0){
                r[j+di]=r[j];
                j-=di;
            }
            r[j+di]=temp;
        }
        di/=2;
    }
}

5.3 性能分析:

时间复杂度:

O(nlog_2n)

空间复杂度:

S(1)

6.冒泡排序(稳定)

6.1 基本思想:

两两比较相邻记录的关键码,如果反序则交换,直到没有反序的记录为止。

6.2 对冒泡排序的改进:

1)设变量exchange记载记录交换的位置。则一趟排序后,exchange记载的一定是这一趟排序中记录的最后一次交换的位置。且从此位置以后的记录均已有序。

2)设bound位置的记录是无序区的最后一个记录,则每趟冒泡排序的范围是r[0]~r[bound]。

在一趟排序后,从exchange位置之后的记录一定是有序的,所以bound=exchange。

3)令exchange初值为0,在以后的排序中,只要有记录交换,exchange的值就会大于0。则当exchange=0时,冒泡排序结束。

6.3 代码实现:

void buble_sort(int r[],int n){
    int exchange=n-1,bound,i,temp;
    while(exchange){
        bound=exchange;
        exchange=0;
        
        for(i=0;i<bound;i++){
            if(r[i]>r[i+1]){
                temp=r[i];
                r[i]=r[i+1];
                r[i+1]=temp;
                exchange=i;
            }
        }
        
    }
    
}

6.4 性能分析:

时间复杂度:

O(n^2)

空间复杂度:

O(1 )

7.快速排序

7.1 基本思想:

通过一趟排序将待排记录分隔成独立的两部分。其中一部分记录的关键码均比另一部分的关键码小,则可分别对这两部分记录继续进行排序,以达到整个序列有序。

首先选取一个轴值。通过一趟排序,将待排序记录分割成独立的两部分。前一部分记录的关键码均小于或等于轴值;后一部分记录的关键码均大于或等于轴值。然后分别对这两部分重复上述方法。

7.2 如何实现划分:

设待划分的序列是r[s]~r[t]。设参数i,j分别指向子序列左右两端的下标,s和t。令r[s]为轴值。

  1. j从后向前扫描直到r[j]<r[i],将r[j]移动到r[i]的位置,使关键码小的记录移动到前面。
  2. i从前向后扫描直到r[i]>r[j],将r[i]移动到r[j]的位置,使关键码大的记录移动到后面。
  3. 重复上述过程,直到i=j。

7.3 递归出口:

 若待排序序列中只有一个记录,则显然有序,否则进行一次划分后,再分别对所得的两个子序列进行快速排序。

7.4 代码实现:

int get_partition(int first,int end,int r[]){
    int i=first,j=end,temp;
    while(i<j){
        while(r[i]<=r[j]&&i<j){
            --j;
        }
        if(i<j){
            temp=r[j];
            r[j]=r[i];
            r[i]=temp;
            ++i;
        }
        while(r[i]<=r[j]&&i<j){
            ++i;
        }
        if(i<j){
            temp=r[j];
            r[j]=r[i];
            r[i]=temp;
            --j;
        }
    }
    return i;
}
void quick_sort(int r[],int first,int end){
    if(first<end){
        int pos=get_partition(first, end, r);
        quick_sort(r, first, pos-1);
        quick_sort(r, pos+1, end);
    }
}

7.5 性能分析:

时间复杂度与选取的轴值有关。

最好情况为:每次均选取到中间值作为轴值;最坏情况为:每次都选取到最大或最小元素最为轴值。

平均时间复杂度:O(nlog_2n)

最坏时间复杂度:O(n^2)

采用“三者取中”来确定轴值,即:第一个元素,最后一个元素,最中间的元素中的中间值作为划分元。

空间复杂度:O(log_2n)

8.选择排序

8.1 基本思想:

 每趟排序在当前待排序序列中选出关键码最小的记录,添加到有序序列中。

8.2 代码实现:

void select_sort(int r[],int n){
    int min,i,j,temp;
    for(i=0;i<n-1;i++){
        min=i;
        for(j=i+1;j<n;j++){
            if(r[j]<r[min]){
                min=j;
            }
        }
        if(min!=i){
            temp=r[min];
            r[min]=r[i];
            r[i]=temp;
        }
    }
}

8.3 性能分析:

时间复杂度:

O(n^2)

9.归并排序(稳定)

速度仅慢于快速排序,适用于分段有序的数列,为稳定排序算法。

9.1 基本思想(分治):

1)只包含一个元素的子表是有序表

2)将有序的子表合并

3)得到最终表

4) 需要一个辅助的临时数组

9.2 代码实现:

void merge_sort_recursive(int r[],int reg[],int start,int end){
    if(start>=end){
        return;
    }
    int mid=(start+end)/2;
    merge_sort_recursive(r, reg, start, mid);
    merge_sort_recursive(r, reg, mid+1, end);
    //通过上述操作,已经获得了两个有序的子序列
    //合并
    int i=start,j=mid+1,k=start;
    while(i<=mid&&j<=end){
        if(r[i]<=r[j]){
            reg[k++]=r[i++];
        }
        else{
            reg[k++]=r[j++];
        }
    }
    while(i<=mid){
        reg[k++]=r[i++];
    }
    while(j<=end){
        reg[k++]=r[j++];
    }
    for(i=start;i<=end;i++){
        r[i]=reg[i];
    }
}
void merge_sort(int r[],int n){
    int reg[MAX_SIZE];//辅助数组
    merge_sort_recursive(r, reg, 0, n-1);
}

9.3 性能分析:

时间复杂度:O(nlog_2n)

空间复杂度:O(n)

10.排序方法比较

10.1 排序方法选择主要考虑:

1)待排序记录的数量

2)关键字的分布情况

3)对排序稳定性的要求

10.2 时间特性:

时间复杂度为O(nlog_2n):快速、归并

时间复杂度为O(n^2):插入、冒泡、选择

待排序记录基本有序时:插入和冒泡可以达到O(n)

选择、归并排序的时间特性不随关键字的分布而改变。

稳定排序:插入、冒泡、归并

不稳定:快速、选择、希尔

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

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

相关文章

【原创分享】DDR拓扑结构的详细解析

在进行多片DDR设计的时候&#xff0c;通常DDR会存在拓扑结构&#xff0c;下面我们将详细介绍一下各种拓扑结构的区别以以及应用场景。 首先我们先介绍一下&#xff0c;当只存在一片DDR的时候通常是采用点对点的连接方式&#xff0c;点对点的布线方式优点是结构简单&#xff0c…

git之UGit可视化工具使用

一、下载安装UGit 链接&#xff1a;https://pan.baidu.com/s/1KGJvWkFL91neI6vAxjGAag?pwdsyq1 提取码&#xff1a;syq1 二 、使用SSH进行远程仓库连接 1.生成SSH密钥 由于我们的本地 git仓库和 gitee仓库之间的传输是通过SSH加密的&#xff0c;所以我们需要配置SSH公钥。才…

瓷片图绘制教程,R语言ggplot2绘图笔记

瓷片图像地板砖一样&#xff0c;由许多个小格子组成&#xff0c;不用的颜色深浅可以用来表示不同的值&#xff0c;横轴和纵轴可以用来展示不同的位置&#xff0c;二维码图、马赛克图、热图等都有异曲同工之妙。 今天分享一个在R语言中利用ggplot2包绘制瓷片图的方法&#xff0c…

处理器类型简介

转载自&#xff1a;https://www.cnblogs.com/zamely/p/4334979.html 多核处理器也称片上多核处理器&#xff08;Chip Multi-Processor&#xff0c;CMP&#xff09;。 1.多核处理器的流行 多核出现前&#xff0c;商业化处理器都致力于单核处理器的发展&#xff0c;其性能已经…

轻量封装WebGPU渲染系统示例<54>- 表现GLB模型之拱形门

当前示例源码github地址: https://github.com/vilyLei/voxwebgpu/blob/feature/material/src/voxgpu/sample/GLBMaterialTest.ts 当前示例运行效果: 此示例基于此渲染系统实现&#xff0c;当前示例TypeScript源码如下: export class GLBMaterialTest {private mRscene new …

java内存溢出初步排查

java内存模型 java内存空间主要包括以下几个部分&#xff1a;方法区、堆内存、虚拟机栈、本地方法栈 方法区&#xff1a;主要存放已被加载的类信息&#xff0c;常量&#xff0c;静态变量等。堆内存&#xff1a;Java堆是JVM所管理的最大一块内存空间&#xff0c;几乎所有的对象…

【ai】阿里云 大模型 api 聚合平台 dashscope

阿里云登录 - 欢迎登录阿里云&#xff0c;安全稳定的云计算服务平台 快速调用 前提条件 已开通服务并获得API-KEY&#xff1a;开通DashScope并创建API-KEY。 已安装最新版SDK&#xff1a;安装DashScope SDK。 DashScope灵积模型服务建立在“模型即服务”&#xff08;Model-a…

Sqlserver-查询和kill杀死正在运行的事务

Sqlserver-查询和kill杀死正在运行的事务 1.查询正在运行的事务2.杀死运行的事务Kill 1.查询正在运行的事务 SELECT session_id, task_state, pending_io_count, context_switches_count FROM sys.dm_os_tasks WHERE session_id > 50 ORDER BY task_state asc2.杀死运行的事…

【51单片机系列】DS18B20温度传感器模块

本文是关于温度传感器的相关内容。 文章目录 一、 DS18B20数字温度传感器介绍1.1、 DS18B20温度传感器的特点1.2、DA18B20内部结构1.3、 DS18B20的温度转换规则1.4、 DS18B20的ROM指令表1.6、 计算温度1.7、 读写时序 二、DS18B20使用示例 一、 DS18B20数字温度传感器介绍 DS1…

真心建议,入职业务部门前先学会BI数据分析

不管进入哪个业务部门&#xff0c;都需要具备一定的数据分析能力&#xff0c;能够从不断累积的数据中发现并解决问题。比如销售部门的需要通过分析销售数据&#xff0c;及时发现销售不佳的商品&#xff0c;调整销售策略&#xff0c;提高销售额、销售利润等。而随着精细化数据分…

一体式读卡器:引领数据读取新潮流

一体式读卡器&#xff1a;引领数据读取新潮流 随着科技的发展&#xff0c;读卡器在各个领域的应用越来越广泛&#xff0c;如工业自动化生产、身份认证、门禁控制、数据采集等。读卡器主要有两种类型&#xff1a;一体式读卡器和分体式读卡器。这两种类型的读卡器各有其优缺点&a…

Pr2024 for Mac/win中文版:为创意无限延展的全新时代

随着科技的不断进步和创新&#xff0c;影视制作行业也在不断发展。作为专业视频编辑软件的领军者&#xff0c;Premiere Pro于2024年推出了全新的版本Pr2024&#xff0c;为创意无限延展的全新时代揭开了崭新的篇章。 Pr2024以其强大的功能和卓越的性能&#xff0c;为用户带来了…

基于图搜索的自动驾驶规划算法 - BFS,Dijstra,A*

本文将讲解BFS&#xff0c;Dijstra&#xff0c;A*&#xff0c;动态规划的算法原理&#xff0c;不正之处望读者指正&#xff0c;希望有兴趣的读者能在评论区提出一些这些算法的面试考点&#xff0c;共同学习&#xff0c;一起进步 0 图论基础 图有三种&#xff1a;无向图、有向…

软件架构师的主要职责说明文(合集)

软件架构师的主要职责说明文1 职责&#xff1a; 1、挖掘和分析业务需求&#xff0c;对公司业务平台进行架构改进和升级设计&#xff0c;制定架构升级规划和过渡方案; 2、承担软件产品核心功能的开发工作&#xff0c;牵头保障整个系统不出现重大技术故障; 3、进行技术评估与产品…

有什么好用的C/C++源代码混淆工具?

​ 有什么好用的C/C源代码混淆工具&#xff1f; 开始使用ipaguard 前言 iOS加固保护是直接针对ios ipa二进制文件的保护技术&#xff0c;可以对iOS APP中的可执行文件进行深度混淆、加密。使用任何工具都无法逆向、破解还原源文件。对APP进行完整性保护&#xff0c;防止应用…

财务分析进阶篇:终于有人把利润分析怎么做给讲清了!

在之前的BI系列文章中&#xff0c;我们给大家介绍了如何用BI进行企业费用分析和毛利分析的方法。   发布后有小伙伴提到&#xff1a;“既然费用和毛利都分析了&#xff0c;顺便把利润表的数据分析一起做了呗”&#xff0c;因此这就有了本期内容。我希望结合前两篇文章&#xf…

ssh工具 从ssh服务器下载文件夹

此文分享一个python脚本,用于快速的定位、选择ssh服务器上的文件夹,并将其下载到本地指定的位置。 效果演示 🔥完整演示效果 👇 第一步,显然,我们需要选择功能 👇 第二步,确认我们需要从哪个ssh服务器上下载文档 👇 第三步,定位、选择、确认需要下载的文件夹…

计网03-数据的封装和解封装

数据封装和解封装的过程 实例&#xff1a;有两台电脑 PC&#xff11;和PC&#xff12;&#xff0c;PC1要给PC&#xff12;发送一个文本文件 1、数据的封装过程&#xff1a; 应用层&#xff1a;将原始数据转换成计算机能识别的二进制数传输层&#xff1a;在传输层是有固定的传…

vr虚拟高压电器三维仿真展示更立体全面

VR工业虚拟仿真软件的应用价值主要体现在以下几个方面&#xff1a; 降低成本&#xff1a;通过VR技术进行产品设计和开发&#xff0c;可以在虚拟环境中进行&#xff0c;从而减少对物理样机的依赖&#xff0c;降低试错成本和时间。此外&#xff0c;利用VR技术构建的模拟场景使用方…

Guava自加载缓存LoadingCache使用指南

第1章&#xff1a;引言 大家好&#xff0c;我是小黑&#xff0c;今天我们来聊聊缓存。在Java世界里&#xff0c;高效的缓存机制对于提升应用性能、降低数据库负担至关重要。想象一下&#xff0c;如果每次数据请求都要跑到数据库里取&#xff0c;那服务器岂不是要累趴了&#x…