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

二叉树顺序存储结构

目录

1.二叉树顺序存储结构

2.堆的概念及结构

3.堆的相关接口实现

3.1 堆的插入及向上调整算法

3.1.1 向上调整算法

3.1.2 堆的插入

3.2 堆的删除及向下调整算法

3.2.1 向下调整算法

3.2.2 堆的删除

3.3 其它接口和代码实现

4.建堆或数组调堆的两种方式及复杂度分析

4.1 向上调整建堆

4.1.1 建堆步骤

4.1.2 代码实现

4.1.3 时间复杂度分析 --- O(N*logN)

4.2 向下调整建堆

4.2.1 建堆步骤

4.2.2 代码实现

4.2.3 时间复杂度分析 --- O(N)

5.堆的应用

5.1 堆排序(假设升序)

5.1.1 堆排序步骤

5.1.2 代码实现

5.2 TopK问题

5.2.1 TopK解决步骤

5.2.2 代码实现(数据从文件读取)


1.二叉树顺序存储结构

顺序存储结构就是用数组来存储,一般是用数组只适合来表示完全二叉树,因为不是完全二叉树会有空间浪费的现象。

二叉树的顺序存储结构在物理上是一个数组,在逻辑上是一个二叉树。

现实中我们通常把堆使用顺序存储结构的数组来存储,而什么又是堆呢?

需要注意的是这里的堆和操作系统虚拟进程地址空间中的堆是两回事,一个是数据结构,一个是操作系统中管理内存的一块区域分段。

2.堆的概念及结构

其实堆就是一个完全二叉树,堆中的所有元素按完全二叉树的顺序存储方式存储在一个一维数组中,并且满足:堆中某个结点的值总是不大于其父节点的值(大堆)或者堆中某个结点的值总是不小于其父节点的值(小堆)。

总结来说:

  • 堆中某个节点的值总是不大于或不小于其父节点的值;
  • 堆总是一棵完全二叉树;

注意:所有的数组都可以表示成完全二叉树,但是他并不一定是堆。

3.堆的相关接口实现


补充:

对于具有n个结点的完全二叉树,如果按照从上至下从左至右的数组顺序对所有节点从0开始编号,则对于序号为i的结点有:
1.若i>0,i位置节点的双亲序号:(i-1)/2; i=0,i为根节点编号,无双亲节点
2.若2i+1 < n,左孩子序号:2i+1;若2i+1>=n(数组越界), 无左孩子

(叶子就是没有左孩子,也就是叶子结点的左孩子下标2i+1>=n越界)
3.若2i+2 < n,右孩子序号:2i+2; 若2i+2>=n(数组越界), 无右孩子


3.1 堆的插入及向上调整算法

  1. 先将元素插入到堆的末尾,即最后一个数组元素之后
  2. 插入之后如果堆的性质遭到破坏,插入的结点就根据向上调整算法找到合适位置即可

3.1.1 向上调整算法

那么什么是向上调整算法呢?如何实现?

例如: 堆:[4, 27, 11, 28, 35, 19, 15, 89, 2] Push:2

图片展示:

代码实现:

void AdjustUp(int* a, int child)
{int parent = (child - 1) / 2;while (child > 0){if (a[child] > a[parent]){Swap(a + child, a + parent);child = parent;parent = (parent - 1) / 2;}else{break;}}
}

代码注意事项:

  • 除了插入的元素,堆中的其他元素都符合堆的性质,所以调整到 待调整节点和父节点 符合堆的性质即可退出调整。
  • 循环退出条件:待调整节点调整到根节点 或者 待调整节点和父节点的大小关系符合堆的性质。
  • while语句中的条件不能写parent >= 0,因为 (0-1)/ 2 之后依旧是0,并不符合预期的循环退出条件。
  • 如果调大堆,比较符号就用>;如果调小堆,比较符号就用<;方便以后更改。

3.1.2 堆的插入

注意:堆的物理结构是一个数组,也就是用顺序表实现的,插入时容量不够要记得扩容。

void HeapPush(Heap* php, HPDataType x)
{assert(php);if (php->capacity == php->size){int newCapacity = php->capacity == 0 ? 4 : php->capacity * 2;HPDataType* tmp = (HPDataType*)realloc(php->a, sizeof(HPDataType) * newCapacity);if (tmp == NULL){perror("HeapPush:");exit(-1);}php->a = tmp;php->capacity = newCapacity;}php->a[php->size] = x;php->size++;AdjustUp(php->a, php->size - 1);
}

3.2 堆的删除及向下调整算法

这里堆的删除是删除堆顶数据,因为只有堆顶数据才有意义(堆顶数据都是最值,删除堆顶后能获得次大或者次小的数)

这里我们能直接删除堆顶数据吗?很明显不可以,根据顺序表删除数据的特点,后面的元素会依次覆盖前面的元素,删除堆顶数据后,堆的结构就被破坏了。

其实删除思想是这样的:

  1. 将堆顶元素与堆中最后一个元素交换
  2. 删除堆中最后一个元素
  3. 将堆顶元素向下调整直到满足堆的结构

这种思想很巧妙,在后面的堆排序中也会用到这种思想。

3.2.1 向下调整算法

代码实现:

void AdjustDown(int* a, int size, int parent)
{int child = parent * 2 + 1;while (child < size){if (child + 1 < size && a[child + 1] > a[child])child++;if (a[child] > a[parent]){Swap(a + child, a + parent);parent = child;child = child * 2 + 1;}else{break;}}
}

代码注意事项:

  • 除了堆顶元素,堆中的其他元素都符合堆的性质,所以调整到 待调整节点和左右孩子 符合堆的性质即可退出调整。
  • 循环退出条件:待调整节点调整到叶子节点 或者 待调整节点和左右孩子节点的大小关系符合堆的性质。
  • 因为要判断越界,函数参数中要有数组大小size。
  • 向下调整时,我们要和该结点的左右孩子中较小的那个交换。代码设计时我们可以先默认左孩子小,再和右孩子进行比较得出较小的那个节点。

3.2.2 堆的删除

void HeapPop(Heap* php)
{assert(php);assert(php->size > 0);Swap(&php->a[0], &php->a[php->size - 1]);php->size--;AdjustDown(php->a, php->size, 0);
}

3.3 其它接口和代码实现

#pragma once
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <time.h>typedef int HPDataType;typedef struct Heap
{HPDataType* a;int size;int capacity;
}Heap;void Swap(int* a, int* b);
void AdjustUp(int* a, int child);//a:要调整的孩子结点所在的数组  child:要调整的孩子节点的下标
void AdjustDown(int* a, int size, int parent);//a:要调整的父亲结点所在的数组   size:数组的size   parent:要调整的父亲节点的下标void HeapPrint(Heap* php);
void HeapInit(Heap* php);
void HeapDestory(Heap* php);
void HeapPush(Heap* php, HPDataType x);
void HeapPop(Heap* php);
HPDataType HeapTop(Heap* php);
int HeapSize(Heap* php);
int HeapEmpty(Heap* php);
#include "Heap.h"void Swap(int* a, int* b)
{int tmp = *a;*a = *b;*b = tmp;
}//调da堆
void AdjustUp(int* a, int child)
{int parent = (child - 1) / 2;while (child > 0){if (a[child] > a[parent]){Swap(a + child, a + parent);child = parent;parent = (parent - 1) / 2;}else{break;}}
}//调da堆
void AdjustDown(int* a, int size, int parent)
{int child = parent * 2 + 1;while (child < size){if (child + 1 < size && a[child + 1] > a[child])child++;if (a[child] > a[parent]){Swap(a + child, a + parent);parent = child;child = child * 2 + 1;}else{break;}}
}void HeapInit(Heap* php)
{assert(php);php->a = NULL;php->capacity = php->size = 0;
}void HeapDestory(Heap* php)
{free(php->a);php->capacity = php->size = 0;
}void HeapPrint(Heap* php)
{for (int i = 0; i < php->size; i++){printf("%d ", php->a[i]);}printf("\n");
}void HeapPush(Heap* php, HPDataType x)
{assert(php);if (php->capacity == php->size){int newCapacity = php->capacity == 0 ? 4 : php->capacity * 2;HPDataType* tmp = (HPDataType*)realloc(php->a, sizeof(HPDataType) * newCapacity);if (tmp == NULL){perror("HeapPush:");exit(-1);}php->a = tmp;php->capacity = newCapacity;}php->a[php->size] = x;php->size++;AdjustUp(php->a, php->size - 1);
}//这里删除的是堆顶数据,只有堆顶数据才有意义
//1.swap(堆顶数据,最后一个数据)
//2.删除最后一个数据
//3.堆顶数据AdjustDown
void HeapPop(Heap* php)
{assert(php);assert(php->size > 0);Swap(&php->a[0], &php->a[php->size - 1]);php->size--;AdjustDown(php->a, php->size, 0);
}HPDataType HeapTop(Heap* php)
{assert(php);assert(php->size > 0);return php->a[0];
}int HeapSize(Heap* php)
{assert(php);return php->size;
}int HeapEmpty(Heap* php)
{assert(php);return php->size == 0;
}

4.建堆或数组调堆的两种方式及复杂度分析


前面我们说过,所有的数组都可以表示成完全二叉树,但是他并不一定是堆。那么我们如何将这个数组调整成堆呢?

我们首先会想到:把数组的值依次push到堆中,再把堆中数据依次赋值给数组,这样就把数组调整成了堆。但是实际应用中我们不会再写一个堆这样的数据结构,其次这种方式会有空间复杂度的消耗,所以我们不提倡这么做。

调堆方式有两种:向上调整建堆和向下调整建堆


4.1 向上调整建堆

4.1.1 建堆步骤

参考堆插入的思想,数组中的每个元素都可以看做新插入的节点。

从根结点开始调整,一直调整到最后一个结点。

想要调成成小堆:如果该结点小于父节点,就一直向上交换,直到不小于其父节点或者调整到根结点。

4.1.2 代码实现

int main()
{int a[] = { 27,15,19,28,35,11,4,89,2 };int size = sizeof(a) / sizeof(a[0]);//这里我们建小堆//方法一:向上调整算法for (int i = 0; i < size; i++)//从根结点开始调整,一直调整到最后一个结点。{AdjustUp(a, i);}for (int i = 0; i < size; i++){printf("%d ",a[i]);}return 0;
}

4.1.3 时间复杂度分析 --- O(N*logN)

​​

4.2 向下调整建堆

4.2.1 建堆步骤

在解释向下调整算法之前,先说明一下:

向下调整算法有一个前提:左右子树必须是一个堆,才能调整。

那么我们如何调整呢?

这里我们可以利用递归思想来解决:先从倒数第一个非叶子结点的子树开始调整,一直调整到根结点的树。也就是倒着调整。

4.2.2 代码实现

int main()
{int a[] = { 27,15,19,28,35,11,4,89,2 };int size = sizeof(a) / sizeof(a[0]);//这里我们建小堆//方法二:向下调整算法for (int i = (size - 1 - 1) / 2; i >= 0; i--){AdjustDown(a, size, i);}for (int i = 0; i < size; i++){printf("%d ",a[i]);}return 0;
}

代码注意:

size - 1是最后一个数组元素的下标,对他减1除2后,就是他父节点的下标,也就是倒数第一个非叶子结点;

4.2.3 时间复杂度分析 --- O(N)

总结:向下调整算法建堆要比向上调整算法建堆要高效一些,并且向下调整算法要更常用(通常对堆顶数据进行向下调整操作),所以我们一般使用向下调整来建堆。

5.堆的应用


那么我们为什么要学堆呢?为什么要设计堆这种数据结构呢?

主要用于解决两个问题:

  • 排序
  • Topk问题:在N个数据中找最大或者最小的前k个(这里的N一般非常大)

注意:这里堆的应用问题和前面数组调堆的问题是同一个道理,我们不能使用堆数据结构的相关接口,需要在原生数组上进行操作。


5.1 堆排序(假设升序)

5.1.1 堆排序步骤

首先建堆这里就有一个坑了,正常思维来看,我们升序是建小堆,因为小堆的堆顶是最小值。

我们来看看升序建小堆的效率如何:

  1. 选出最小的数,放在第一个位置
  2. 最小的数删除后,剩下的看做一个堆。但是之前建好的关系都乱了,只能重新建堆,才能选出次小的数。

此时的时间复杂度:建堆的时间复杂度O(n),建了n次堆,时间复杂度O(n*n),这种效率还不如暴力遍历排序来的直接。

这里花里胡哨的建堆选堆顶的最值进行排序,结果效率和冒泡差不多,显然不是我们想要的结果。

那么堆排序到底是怎么排的呢,下面给出步骤

1.建堆

升序:建大堆

降序:建小堆

2.利用堆删除思想进行排序

(1)升序建的大堆,堆顶是最大元素,

(2)把堆顶(最大元素)和最后一个元素交换,

(3)最后一个元素(最大值)不看做堆中元素,堆顶元素向下调整,堆顶元素就变成了次大值,

(4)依次类推,重复(2)~(3)

可以计算一下这里的时间复杂度来和上面的建小堆方法来比较一下:

建大堆:n次向下调整,每次调整时间复杂度为O(logn),所以时间复杂度为:O(n*logn)

建小堆的时间复杂度O(n*n),很显然,数据非常多时,这两种方法的效率是天差地别

5.1.2 代码实现

//堆排序,升序
void HeapSort(int* a, int n)
{//第一步:建大堆for (int i = (n - 1 - 1) / 2; i >= 0; i--){AdjustDown(a, n, i);}//第二步:堆删除思想进行排序(依次选数,调堆)for (int i = n - 1; i > 0; i--)//最后一步交换后就一个堆顶元素(最小值),AdjustDown没有进行调整{//将堆顶元素和最后一个元素交换,交换后最后一个元素不计入堆内Swap(&a[0], &a[i]);AdjustDown(a, i , 0);//这里第二个参数是数据个数,最后一个元素不计入堆内,正好是i}
}

代码注意事项:

  • 以后我们建堆都用向下调整建堆。首先高效,其次堆排序的选数调堆也用的向下调整。
  • 这里的循环变量i是最后一个元素的下标,也正好是交换后数组的元素个数(交换后最后一个元素不计入数组内)
  • 最后一步i == 1时,交换后就一个堆顶元素(最小值),AdjustDown没有进行调整,但这一步也要执行,因为a[0]和a[1]要进行交换。

5.2 TopK问题

5.2.1 TopK解决步骤

Topk问题就是在N个数中找最大或者最小的前k个。(这里的N一般非常大,大到内存装不下)

第一次碰到这个问题,我们的惯性思维会去怎么解决呢?

  • 方法一:先排降序,前k个最大
  • 方法二:N个数依次插入大堆,pop k次,每次取的都是堆顶数据

但是当N非常大时,甚至内存都放不下,很显然这两种方法不靠谱。

我们可以算一下时间复杂度:

方法一:O(N*logN)

方法二:O(N+klogN) 建堆:N,k次pop :klogN

我们直接来说说Topk问题的实际解决办法:

  1. 用数据集合的前k个元素来建堆

前k个最大的元素:建小堆

前k个最小的元素:建大堆

2.用剩余的N-k个元素依次与对顶元素比较,找最大(小)的k个:比堆顶大(小),替换,向下调整。

3.最后堆中的k个元素就是最大(最小)的k个数

计算时间复杂度:O(k+(N-k)logk)~O(Nlogk)

5.2.2 代码实现(数据从文件读取)

int* TopK(int k)
{int* retArr = (int*)malloc(sizeof(int) * k);//打开文件FILE* pf = fopen("data,txt", "r");if (pf == NULL) {perror("TopK:");exit(-1); }//前k个数据读入数组for (int i = 0; i < k; i++){fscanf(pf, "%d", &retArr[i]);}//数组建堆(小堆)for (int i = (k - 2) / 2; i >= 0; i--){AdjustDown(retArr, k, i);}//剩余N-k个数据,依次和堆顶数据比较for (int i = 0; i < N - k; i++) {int x;fscanf(pf, "%d", &x);if (x > retArr[0]){retArr[0] = x;AdjustDown(retArr, k, 0);}}fclose(pf);return retArr; 
}void testTopK()
{int* arr = TopK(10);for (int i = 0; i < 10; i++)printf("%d ", arr[i]);printf("\n");free(arr);
}

相关文章:

二叉树顺序存储结构

目录 1.二叉树顺序存储结构 2.堆的概念及结构 3.堆的相关接口实现 3.1 堆的插入及向上调整算法 3.1.1 向上调整算法 3.1.2 堆的插入 3.2 堆的删除及向下调整算法 3.2.1 向下调整算法 3.2.2 堆的删除 3.3 其它接口和代码实现 4.建堆或数组调堆的两种方式及复杂度分析…...

Apache HTTPD 多后缀解析漏洞复现

Apache HTTPD 支持一个文件拥有多个后缀&#xff0c;并为不同后缀执行不同的指令。比如&#xff0c;如下配置文件&#xff1a; AddType text/html .html AddLanguage zh-CN .cn 其给.html后缀增加了media-type&#xff0c;值为text/html&#xff1b;给.cn后缀增加了语言&…...

【深入浅出C#】章节10: 最佳实践和性能优化:内存管理和资源释放

一、 内存管理基础 1.1 垃圾回收机制 垃圾回收概述 垃圾回收&#xff08;Garbage Collection&#xff09;是一种计算机科学和编程领域的重要概念&#xff0c;它主要用于自动管理计算机程序中的内存分配和释放。垃圾回收的目标是识别和回收不再被程序使用的内存&#xff0c;以…...

我的创作纪念日——1个普通网安人的漫谈

机缘 大家好&#xff0c;我是zangcc。今天突然收到了一条私信&#xff0c;才发现来csdn已经1024天了&#xff0c;不知不觉都搞安全渗透2年半多了&#x1f414;&#xff0c;真是光阴似箭。 我写博客的初衷只是记录自己的学习历程&#xff0c;比如打打靶场&#xff0c;写一下通关…...

Linux中执行bash脚本报错/bin/bash^M: bad interpreter: No such file or directory

文章目录 参考博客&#xff1a; Linux中执行bash脚本报错/bin/bash^M: bad interpreter: No such file or directory 首先在此对这位博主表示感谢。 运行bash脚本会出现两个文件&#xff0c;1037.err和1037.out。 1037.err的文件内容如下&#xff1a; /data/home/user12/.lsbat…...

期权交易策略主要有哪些?期权交易策略指南

在学习更复杂的看涨和看跌期权策略之前&#xff0c;普通投资者应该彻底了解一些关于期权的基本知识&#xff0c;这样有助你后期的交易能力和理论知识水平提升有很大的帮助&#xff0c;下文科普期权交易策略主要有哪些&#xff1f;期权交易策略指南&#xff01;本文来自&#xf…...

算法通关村第十四关——解析堆在数组中找第K大的元素的应用

力扣215题&#xff0c; 给定整数数组nums和整数k&#xff0c;请返回数组中第k个最大的元素。 请注意&#xff0c;你需要找的是数组排序后的第k个最大的元素&#xff0c;而不是第k个不同的元素。 分析&#xff1a;按照“找最大用小堆&#xff0c;找最小用大堆&#xff0c;找中间…...

【报错】springboot3启动报错

报错内容&#xff1a;Cannot load driver class: org.h2.Driver Error starting ApplicationContext. To display the condition evaluation report re-run your application with debug enabled. 解决; 通过源码分析&#xff0c;druid-spring-boot-3-starter目前最新版本是1…...

阿里云服务器配置怎么选择?小白攻略

阿里云服务器配置选择_CPU内存/带宽/存储配置_小白指南&#xff0c;阿里云服务器配置选择方法包括云服务器类型、CPU内存、操作系统、公网带宽、系统盘存储、网络带宽选择、安全配置、监控等&#xff0c;阿小云分享阿里云服务器配置选择方法&#xff0c;选择适合自己的云服务器…...

关于 RK3568的linux系统killed用户应用进程(用户现象为崩溃) 的解决方法

若该文为原创文章&#xff0c;转载请注明原文出处 本文章博客地址&#xff1a;https://hpzwl.blog.csdn.net/article/details/132710642 红胖子网络科技博文大全&#xff1a;开发技术集合&#xff08;包含Qt实用技术、树莓派、三维、OpenCV、OpenGL、ffmpeg、OSG、单片机、软硬…...

EasyPHP-Devserver-17安装和配置mantisBT

文章目录 1、准备工作2、安装easyphp2.1 http://127.0.0.1 无法访问 3、安装mantisBT和phpMyAdmin3.1 配置浏览器的访问url和端口号&#xff08;配置局域网内可访问&#xff09;3.2 安装mantis 4、Administrator 注册新用户时设置登录密码5、附件上传6、邮件配置 文章参考自&am…...

Python打包教程 PyInstaller和cx_Freeze

当我们开发Python应用程序时&#xff0c;通常会将代码保存在.py文件中&#xff0c;然后通过Python解释器运行它。这对于开发和测试是非常方便的&#xff0c;但在将应用程序分享给其他人或在不同环境中部署时&#xff0c;可能会带来一些问题。为了解决这些问题&#xff0c;我们可…...

用两成数据也能训练出十成功力的模型,Jina Embeddings 这么做

句向量&#xff08;Sentence Embeddings&#xff09;模型在多模态人工智能领域起着至关重要的作用&#xff0c;它通过将句子编码为固定长度的向量表示&#xff0c;将语义信息转化为机器可以处理的形式&#xff0c;在 文本分类、信息检索和相似度计算 等多个方面有着广泛应用。 …...

SpringCloud Eureka搭建会员中心服务提供方-集群

&#x1f600;前言 本篇博文是关于SpringCloud Eureka搭建会员中心服务提供方-集群&#xff0c;希望你能够喜欢 &#x1f3e0;个人主页&#xff1a;晨犀主页 &#x1f9d1;个人简介&#xff1a;大家好&#xff0c;我是晨犀&#xff0c;希望我的文章可以帮助到大家&#xff0c;您…...

详解TCP/IP协议第二篇:OSI参考模型详解

文章目录 写给自己的话 一&#xff1a;协议分层与OSI参考模型 二&#xff1a;通过对话理解分层 三&#xff1a;OSI参考模型 写给自己的话 不从恶人的计谋&#xff0c;不站罪人的道路&#xff0c;不坐亵慢人的座位&#xff0c;惟喜爱耶和华的律法&#xff0c;昼夜思想&#…...

OpenGL 函数列表

//纹理头文件加载 #define STB_IMAGE_IMPLEMENTATION #include "stb_image.h" //线框模式(Wireframe Mode) //glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); //翻转y轴 stbi_set_flip_vertically_on_load(true); //声明鼠标滚轮回调函数 void scroll_call…...

【C语言】每日一题(半月斩)——day1

目录 &#x1f60a;前言 一.选择题 1.执行下面程序&#xff0c;正确的输出是&#xff08;c&#xff09; 2.以下不正确的定义语句是&#xff08; &#xff09; 3.test.c 文件中包括如下语句&#xff0c;文件中定义的四个变量中&#xff0c;是指针类型的变量为【多选】&a…...

Spring MVC 七 - Locale 本地化

Spring各模块都支持国际化&#xff0c;SpringMVC也同样支持。DispatcherServlet通过Locale Resovler自动根据客户端的Locale支持国际化。 request请求上来后&#xff0c;DispatcherServlet查找并设置Locale Resovler&#xff0c;我们可以通过RequestContext.getLocale()获取到…...

力扣(LeetCode)算法_C++——替换后的最长重复字符

给你一个字符串 s 和一个整数 k 。你可以选择字符串中的任一字符&#xff0c;并将其更改为任何其他大写英文字符。该操作最多可执行 k 次。 在执行上述操作后&#xff0c;返回包含相同字母的最长子字符串的长度。 示例 1&#xff1a; 输入&#xff1a;s “ABAB”, k 2 输出…...

unity 编辑器时读取FairyGUI图集单个图像

原因 想要在编辑器扩展也能访问FairyGUI图集里面的小图&#xff0c;随便找了一下没有找到接口自己做一个 方法 使用UIPackage.GetItemByURL获得小图信息。从图集中复制出小图&#xff0c;如果有旋转就逆旋转90度即可 图集里面的小图是有可能旋转的&#xff0c;可以通过访问 …...

[特殊字符] 智能合约中的数据是如何在区块链中保持一致的?

&#x1f9e0; 智能合约中的数据是如何在区块链中保持一致的&#xff1f; 为什么所有区块链节点都能得出相同结果&#xff1f;合约调用这么复杂&#xff0c;状态真能保持一致吗&#xff1f;本篇带你从底层视角理解“状态一致性”的真相。 一、智能合约的数据存储在哪里&#xf…...

业务系统对接大模型的基础方案:架构设计与关键步骤

业务系统对接大模型&#xff1a;架构设计与关键步骤 在当今数字化转型的浪潮中&#xff0c;大语言模型&#xff08;LLM&#xff09;已成为企业提升业务效率和创新能力的关键技术之一。将大模型集成到业务系统中&#xff0c;不仅可以优化用户体验&#xff0c;还能为业务决策提供…...

python/java环境配置

环境变量放一起 python&#xff1a; 1.首先下载Python Python下载地址&#xff1a;Download Python | Python.org downloads ---windows -- 64 2.安装Python 下面两个&#xff0c;然后自定义&#xff0c;全选 可以把前4个选上 3.环境配置 1&#xff09;搜高级系统设置 2…...

uni-app学习笔记二十二---使用vite.config.js全局导入常用依赖

在前面的练习中&#xff0c;每个页面需要使用ref&#xff0c;onShow等生命周期钩子函数时都需要像下面这样导入 import {onMounted, ref} from "vue" 如果不想每个页面都导入&#xff0c;需要使用node.js命令npm安装unplugin-auto-import npm install unplugin-au…...

汽车生产虚拟实训中的技能提升与生产优化​

在制造业蓬勃发展的大背景下&#xff0c;虚拟教学实训宛如一颗璀璨的新星&#xff0c;正发挥着不可或缺且日益凸显的关键作用&#xff0c;源源不断地为企业的稳健前行与创新发展注入磅礴强大的动力。就以汽车制造企业这一极具代表性的行业主体为例&#xff0c;汽车生产线上各类…...

postgresql|数据库|只读用户的创建和删除(备忘)

CREATE USER read_only WITH PASSWORD 密码 -- 连接到xxx数据库 \c xxx -- 授予对xxx数据库的只读权限 GRANT CONNECT ON DATABASE xxx TO read_only; GRANT USAGE ON SCHEMA public TO read_only; GRANT SELECT ON ALL TABLES IN SCHEMA public TO read_only; GRANT EXECUTE O…...

Android15默认授权浮窗权限

我们经常有那种需求&#xff0c;客户需要定制的apk集成在ROM中&#xff0c;并且默认授予其【显示在其他应用的上层】权限&#xff0c;也就是我们常说的浮窗权限&#xff0c;那么我们就可以通过以下方法在wms、ams等系统服务的systemReady()方法中调用即可实现预置应用默认授权浮…...

Android Bitmap治理全解析:从加载优化到泄漏防控的全生命周期管理

引言 Bitmap&#xff08;位图&#xff09;是Android应用内存占用的“头号杀手”。一张1080P&#xff08;1920x1080&#xff09;的图片以ARGB_8888格式加载时&#xff0c;内存占用高达8MB&#xff08;192010804字节&#xff09;。据统计&#xff0c;超过60%的应用OOM崩溃与Bitm…...

React---day11

14.4 react-redux第三方库 提供connect、thunk之类的函数 以获取一个banner数据为例子 store&#xff1a; 我们在使用异步的时候理应是要使用中间件的&#xff0c;但是configureStore 已经自动集成了 redux-thunk&#xff0c;注意action里面要返回函数 import { configureS…...

云原生安全实战:API网关Kong的鉴权与限流详解

&#x1f525;「炎码工坊」技术弹药已装填&#xff01; 点击关注 → 解锁工业级干货【工具实测|项目避坑|源码燃烧指南】 一、基础概念 1. API网关&#xff08;API Gateway&#xff09; API网关是微服务架构中的核心组件&#xff0c;负责统一管理所有API的流量入口。它像一座…...