【头歌】循环队列及链队列的基本操作

news2024/9/29 9:21:03

第1关:循环队列的基本操作

任务描述

本关任务是实现循环队列的基本操作函数,以实现判断队列是否为满、是否为空、求队列元素个数、进队和出队等功能。

相关知识

队列的基本概念

队列(简称队)也是一种运算受限的线性表,在这种线性表上,插入限定在表的某一端进行,删除限定在表的另一端进行。

队列的插入操作称为进队,删除操作称为出队

允许插入的一端称为队尾,允许删除的一端称为队头

新插入的元素只能添加到队尾,被删除的只能是排在队头的元素。

一个队列的示意图:

队列通常有两种存储结构,即顺序存储结构和链式存储结构。

队列的顺序存储结构简称为顺序队列,它由一个一维数组(用于存储队列中元素)及两个分别指示队头和队尾的变量组成,这两个变量分别称为“队头指针”和“队尾指针”。

通常约定队尾指针指示队尾元素的当前位置,队头指针指示队头元素的前一个位置

循环队列的类型定义
#define MAX_QSIZE 5 // 最大队列长度+1struct SqQueue{   QElemType *base; // 初始化的动态分配存储空间   int front; // 头指针,若队列不空,指向队列头元素   int rear; // 尾指针,若队列不空,指向队列尾元素的下一个位置};

使用顺序队列时会出现“假溢出现象”,为了能够充分地使用数组中的存储空间,可以把数组的前端和后端连接起来,形成一个环形的表,即把存储队列元素的表从逻辑上看成一个环。这个环形的表叫做循环队列

一个循环队列示意图:

队头队尾指针进1的操作为:

  • 队头指针进1:front=(front+1) MOD MaxSize

  • 队尾指针进1:rear=(rear+1) MOD MaxSize

为了在循环队列中区分队空和队满,规定:

  • 设置队空条件为front==rear。

  • 设置队满条件为(rear+1) MOD MaxSize==front。也就是说,当rear指到front的前一位置时就认为队列满了。

显然在这样设置的队满条件下,队满条件成立时队中还有一个空闲单元,也就是说这样的队中最多只能进队MaxSize-1个元素。

编程要求

根据提示,在右侧编辑器补充代码,编写循环队列的基本操作函数。

void InitQueue(SqQueue &Q); // 构造一个空队列Q
void DestroyQueue(SqQueue &Q); // 销毁队列Q,Q不再存在
void ClearQueue(SqQueue &Q); // 将Q清为空队列
int QueueEmpty(SqQueue Q); // 若队列Q为空队列,则返回TRUE;否则返回FALSE
int QueueLength(SqQueue Q); // 返回Q的元素个数,即队列的长度
int GetHead(SqQueue Q,QElemType &e); // 若队列不空,则用e返回Q的队头元素,并返回OK;否则返回ERROR
int EnQueue(SqQueue &Q,QElemType e); // 插入元素e为Q的新的队尾元素
int DeQueue(SqQueue &Q,QElemType &e); // 若队列不空,则删除Q的队头元素,用e返回其值,并返回OK;否则返回ERROR
void QueueTraverse(SqQueue Q,void(*vi)(QElemType)); // 从队头到队尾依次对队列Q中每个元素调用函数vi()  

测试说明

平台会对你编写的代码进行测试:

测试输入:

10 20 30 40 50

60

预期输出:

队列长度为: 4

现在队列中元素:

10 20 30 40

删除的元素是10

删除的元素是20

队列长度为: 3

现在队列中元素:

30 40 60

现在队头元素为:30


开始你的任务吧,祝你成功!

代码示例

#include <stdio.h>
#include<stdlib.h>
#include <iostream>
using namespace std;

 // 函数结果状态代码
#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0
#define OVERFLOW -1
typedef int QElemType;

#define MAX_QSIZE 5 // 最大队列长度+1

struct SqQueue
{
   QElemType *base; // 初始化的动态分配存储空间
   int front; // 头指针,若队列不空,指向队列头元素
   int rear; // 尾指针,若队列不空,指向队列尾元素的下一个位置
};

void print(QElemType i)
{
   printf("%d ",i);
}
void InitQueue(SqQueue &Q); // 构造一个空队列Q
void DestroyQueue(SqQueue &Q); // 销毁队列Q,Q不再存在
void ClearQueue(SqQueue &Q); // 将Q清为空队列
int QueueEmpty(SqQueue Q); // 若队列Q为空队列,则返回TRUE;否则返回FALSE
int QueueLength(SqQueue Q); // 返回Q的元素个数,即队列的长度
int GetHead(SqQueue Q,QElemType &e); // 若队列不空,则用e返回Q的队头元素,并返回OK;否则返回ERROR
int EnQueue(SqQueue &Q,QElemType e); // 插入元素e为Q的新的队尾元素
int DeQueue(SqQueue &Q,QElemType &e); // 若队列不空,则删除Q的队头元素,用e返回其值,并返回OK;否则返回ERROR
void QueueTraverse(SqQueue Q,void(*vi)(QElemType)); // 从队头到队尾依次对队列Q中每个元素调用函数vi()  

int main()
{
   int j;
   int i=0,l;
   QElemType d;
   SqQueue Q;
   InitQueue(Q);
   for(i=0;i<MAX_QSIZE;i++)
   {
     scanf("%d",&d);     
     EnQueue(Q,d);
   };
   printf("队列长度为: %d\n",QueueLength(Q));
   printf("现在队列中元素:\n");
   QueueTraverse(Q,print);
   DeQueue(Q,d);
   printf("删除的元素是%d\n",d);
   DeQueue(Q,d);
   printf("删除的元素是%d\n",d);
   scanf("%d",&d);
   EnQueue(Q,d);
    printf("队列长度为: %d\n",QueueLength(Q));
   printf("现在队列中元素:\n");
   QueueTraverse(Q,print);
   j=GetHead(Q,d);
   if(j)
     printf("现在队头元素为:%d\n",d);
   ClearQueue(Q);
   DestroyQueue(Q);
}
// 循环队列的基本操作(9个)
void InitQueue(SqQueue &Q)
{ // 构造一个空队列Q
   /********** Begin **********/ 
 	Q.base = new QElemType[MAX_QSIZE];
   if(!Q.base) exit(OVERFLOW); // 存储分配失败
   Q.front = Q.rear = 0;

    
	/********** End **********/  
}

void DestroyQueue(SqQueue &Q)
{ // 销毁队列Q,Q不再存在
   /********** Begin **********/ 
   free(Q.base);
   Q.base=NULL;
   Q.front=Q.rear=0;
 
	/********** End **********/  
}

void ClearQueue(SqQueue &Q)
{ // 将Q清为空队列
    /********** Begin **********/ 
     Q.front=Q.rear=0;
	/********** End **********/  
}

int QueueEmpty(SqQueue Q)
{ // 若队列Q为空队列,则返回TRUE;否则返回FALSE
   /********** Begin **********/ 
   if(Q.front==Q.rear)
      return TRUE;
   else
      return FALSE;
	/********** End **********/  
 }

int QueueLength(SqQueue Q)
{ // 返回Q的元素个数,即队列的长度
   /********** Begin **********/ 
   return (Q.rear-Q.front+MAX_QSIZE)%MAX_QSIZE;

	/********** End **********/  
 }

 int GetHead(SqQueue Q,QElemType &e)
 { // 若队列不空,则用e返回Q的队头元素,并返回OK;否则返回ERROR
   /********** Begin **********/ 
 if(Q.front==Q.rear) // 队列空
     return ERROR;
   e=Q.base[Q.front];
   return OK;
 /********** End **********/  
}

int EnQueue(SqQueue &Q,QElemType e)
{ // 插入元素e为Q的新的队尾元素
   /********** Begin **********/ 
     if((Q.rear+1)%MAX_QSIZE==Q.front)
      return ERROR;
   Q.base[Q.rear]=e;
   Q.rear=(Q.rear+1)%MAX_QSIZE;
   return OK;
	/********** End **********/  
 }

int DeQueue(SqQueue &Q,QElemType &e)
{ // 若队列不空,则删除Q的队头元素,用e返回其值,并返回OK;否则返回ERROR
   /********** Begin **********/ 
    if(Q.front==Q.rear)
      return ERROR;
   e=Q.base[Q.front];
   Q.front=(Q.front+1)%MAX_QSIZE;
   return OK;
	/********** End **********/  
}

void QueueTraverse(SqQueue Q,void(*vi)(QElemType))
{ // 从队头到队尾依次对队列Q中每个元素调用函数vi()
   /********** Begin **********/ 
   int i=Q.front;
   while(i!=Q.rear){
      vi(Q.base[i]);
      i=(i+1)%MAX_QSIZE;
   }
   printf("\n");
	/********** End **********/  
}

第2关:链队列的基本操作

任务描述

本关任务是实现链队列的基本操作函数,以实现判断队列是否为满、是否为空、求队列元素个数、进队和出队等功能。

相关知识

链队列的基本概念

队列的链式存储结构简称为链队列

这里采用的链队是一个同时带有队头指针front队尾指针rear的单链表。

队头指针指向队头结点,队尾指针指向队尾结点即单链表的尾结点,并将队头和队尾指针结合起来构成链队结点,

链队列逻辑示意图:

下面给出一种链队列的实现方案。

链队列的类型定义
typedef struct QNode
{
   QElemType data;
   QNode *next;
}*QueuePtr;
struct LinkQueue
{
   QueuePtr front,rear; // 队头、队尾指针
};

编程要求

根据提示,在右侧编辑器补充代码,编写链队列的基本操作函数。

void InitQueue(LinkQueue &Q); // 构造一个空队列Q
void DestroyQueue(LinkQueue &Q); // 销毁队列Q,Q不再存在
void ClearQueue(LinkQueue &Q); // 将Q清为空队列
int QueueEmpty(LinkQueue Q); // 若队列Q为空队列,则返回TRUE;否则返回FALSE
int QueueLength(LinkQueue Q); // 返回Q的元素个数,即队列的长度
int GetHead(LinkQueue Q,QElemType &e); // 若队列不空,则用e返回Q的队头元素,并返回OK;否则返回ERROR
int EnQueue(LinkQueue &Q,QElemType e); // 插入元素e为Q的新的队尾元素
int DeQueue(LinkQueue &Q,QElemType &e); // 若队列不空,则删除Q的队头元素,用e返回其值,并返回OK;否则返回ERROR
void QueueTraverse(LinkQueue Q,void(*vi)(QElemType)); // 从队头到队尾依次对队列Q中每个元素调用函数vi() 

测试说明

平台会对你编写的代码进行测试:

测试输入:

10 20 30 40 50

60

预期输出:

队列长度为: 5

`现在队列中元素:

10 20 30 40 50

删除的元素是10

`删除的元素是20

队列长度为: 4

现在队列中元素:

30 40 50 60

现在队头元素为:30


开始你的任务吧,祝你成功!

代码示例

#include <stdio.h>
#include<stdlib.h>
#include <iostream>
using namespace std;

 // 函数结果状态代码
 #define TRUE 1
 #define FALSE 0
 #define OK 1
 #define ERROR 0 
 #define OVERFLOW -1
 typedef int QElemType;
 
typedef struct QNode
{
   QElemType data;
   QNode *next;
}*QueuePtr;
struct LinkQueue
{
   QueuePtr front,rear; // 队头、队尾指针
};

void print(QElemType i)
{
   printf("%d ",i);
}
void InitQueue(LinkQueue &Q); // 构造一个空队列Q
void DestroyQueue(LinkQueue &Q); // 销毁队列Q,Q不再存在
void ClearQueue(LinkQueue &Q); // 将Q清为空队列
int QueueEmpty(LinkQueue Q); // 若队列Q为空队列,则返回TRUE;否则返回FALSE
int QueueLength(LinkQueue Q); // 返回Q的元素个数,即队列的长度
int GetHead(LinkQueue Q,QElemType &e); // 若队列不空,则用e返回Q的队头元素,并返回OK;否则返回ERROR
int EnQueue(LinkQueue &Q,QElemType e); // 插入元素e为Q的新的队尾元素
int DeQueue(LinkQueue &Q,QElemType &e); // 若队列不空,则删除Q的队头元素,用e返回其值,并返回OK;否则返回ERROR
void QueueTraverse(LinkQueue Q,void(*vi)(QElemType)); // 从队头到队尾依次对队列Q中每个元素调用函数vi()  

int main()
{
   int j;
   int i=0,l;
   QElemType d;
   LinkQueue Q;
   InitQueue(Q);
   for(i=0;i<5;i++)
   {
     scanf("%d",&d);     
     EnQueue(Q,d);
   };
   printf("队列长度为: %d\n",QueueLength(Q));
   printf("现在队列中元素:\n");
   QueueTraverse(Q,print);
   DeQueue(Q,d);
   printf("删除的元素是%d\n",d);
   DeQueue(Q,d);
   printf("删除的元素是%d\n",d);
   scanf("%d",&d);
   EnQueue(Q,d);
    printf("队列长度为: %d\n",QueueLength(Q));
   printf("现在队列中元素:\n");
   QueueTraverse(Q,print);
   j=GetHead(Q,d);
   if(j)
     printf("现在队头元素为:%d\n",d);
   ClearQueue(Q);
   DestroyQueue(Q);
 }
// 链队列的基本操作(9个)
void InitQueue(LinkQueue &Q)
 { // 构造一个空队列Q
  /********** Begin **********/ 
   Q.front=Q.rear=(QueuePtr)malloc(sizeof(QNode));
  if(!Q.front) 
  exit(OVERFLOW);
  Q.front->next=NULL;
 
  /********** End **********/  
}

void DestroyQueue(LinkQueue &Q)
{ // 销毁队列Q(无论空否均可)
   /********** Begin **********/ 
   while(Q.front){
    Q.rear=Q.front->next;
    free(Q.front);
    Q.front=Q.rear;
  }

  /********** End **********/  
}

void ClearQueue(LinkQueue &Q)
{ // 将Q清为空队列
	/********** Begin **********/ 
   QueuePtr p=Q.front,q;
  Q.front=Q.rear;
  while(p->next!=NULL){
    q=p;
    p=p->next;
    free(q);
  }


	/********** End **********/  
 }

int QueueEmpty(LinkQueue Q)
 { // 若Q为空队列,则返回TRUE,否则返回FALSE
   /********** Begin **********/ 
  if(Q.front->next==NULL)
    return TRUE;
  else
    return FALSE;
	/********** End **********/  
}

int QueueLength(LinkQueue Q)
{ // 求队列的长度
   /********** Begin **********/ 
  QueuePtr p=Q.front;
  int i=0;
  while(p!=Q.rear){
    i++;
    p=p->next;
  }
  return i;
	/********** End **********/  
}

int GetHead(LinkQueue Q,QElemType &e)
{ // 若队列不空,则用e返回Q的队头元素,并返回OK,否则返回ERROR
   /********** Begin **********/ 
   QueuePtr p;
  if(Q.front==Q.rear)
    return ERROR;
  p=Q.front->next;
  e=p->data;
  return OK;

	/********** End **********/  
 }

int EnQueue(LinkQueue &Q,QElemType e)
{ // 插入元素e为Q的新的队尾元素
  /********** Begin **********/ 
   QueuePtr p=(QueuePtr)malloc(sizeof(QNode));
  if(!p) exit(OVERFLOW);
  p->data=e;
  p->next=NULL;
  Q.rear->next=p;
  Q.rear=p;

  /********** End **********/  
}

int DeQueue(LinkQueue &Q,QElemType &e)
{ // 若队列不空,删除Q的队头元素,用e返回其值,并返回OK,否则返回ERROR
  /********** Begin **********/ 
  QueuePtr p;
  if(Q.front==Q.rear)
    return ERROR;
  p=Q.front->next;
  e=p->data;
  Q.front->next=p->next;
  if(Q.rear==p)
    Q.rear=Q.front;
  free(p);
  return OK;
  /********** End **********/  
}

void QueueTraverse(LinkQueue Q,void(*vi)(QElemType))
{ // 从队头到队尾依次对队列Q中每个元素调用函数vi()
  /********** Begin **********/ 
  QueuePtr p=Q.front->next;
  while(p!=NULL){
    vi(p->data);
    p=p->next;
  }
  printf("\n");

	/********** End **********/  
 }

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

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

相关文章

Kubernetes集群搭建 (未完待续)

Kubernetes集群搭建 目录 前言前期准备K8S集群安装 虚拟机设置安装K8S集群k8s部署Nginx 附录1 Docker安装附录2 yum k8s 问题附录3 k8s start问题附录4 k8s master init 前言 本文指定Docker与K8s版本&#xff0c;保证兼容性&#xff0c;可供参考 Docker‐ce‐3:19.03.9‐3…

推荐7个高质量图片素材网站

这期给大家分享7个免费、高质量图片素材网站&#xff0c;而且无版权&#xff0c;不用担心侵权&#xff01;建议收藏。 1、潮点视频 https://shipin520.com/shipin-tp/0-1329-0-0-0-0-0-0-0-1.html?from_code2510 网站主要以提供高质量视频素材为主&#xff0c;但也有大量的配…

基于FPGA的啸叫检测与抑制系统设计与实现verilog

针对啸叫的问题,本文设计了一种基于移频算法的啸叫抑制器。采用高性能音频编解码芯片对音频信号采样,移频器对采样所得的音频信号进行移频,移频频率范围为0~8Hz,再用音频芯片输出,采用FFT算法计算出啸叫点频率值,显示在LCD1602上,此移频器可达到快速有效的啸叫抑制效果。…

【JVM】垃圾回收之对象已死

文章目录1. 概述2. 引用计数算法3. 可达性分析算法4. 引用的分类4.1 软引用的应用本文参考&#xff1a;深入理解Java虚拟机&#xff1a;JVM高级特性与最佳实践&#xff08;第3版&#xff09; 1. 概述 总所周知&#xff0c;垃圾收集器的任务就是将“死去”的对象回收。 那么&a…

自动驾驶感知——毫米波雷达

文章目录1. 雷达的基本概念1.1 毫米波雷达分类1.2 信息的传输1.3 毫米波雷达的信号频段1.4 毫米波雷达工作原理1.4.1 毫米波雷达测速测距的数学原理1.4.2 毫米波雷达测角度的数学原理1.4.3 硬件接口1.4.4 关键零部件1.4.5 数据的协议与格式1.5 车载毫米波雷达的重要参数1.6 车载…

94. BERT以及BERT代码实现

1. NLP里的迁移学习 使用预训练好的模型来抽取词、句子的特征 例如word2vec 或语言模型 不更新预训练好的模型需要构建新的网络来抓取新任务需要的信息 Word2vec忽略了时序信息&#xff0c;语言模型只看了一个方向Word2vec只是抽取底层的信息&#xff0c;作为embedding层&…

数据太多?3款免费数据分析软件,分分钟解决

本文分享下我在做数据分析时用过的几个简单易上手的数据可视化软件。 先放上目录&#xff1a; 数据统计收集类——简道云数据图表美化类——图表秀数据开发类——Echart 01 简道云 https://www.jiandaoyun.com/ 适用于&#xff1a;想要“简单易上手”适合业务人员&#xff0…

TF-A源码移植的过程

1.解压标准 tf-a 源码包&#xff1a; tar xfz tf-a-stm32mp-2.2.r2-r0.tar.gz 2.将 ST 官方补丁文件打到 tf-a 源码中&#xff1a; 3.配置交叉编译工具链&#xff1a; 进入~/FSMP1A/tf-a-stm32mp-2.2.r2-r0$ 目录下&#xff0c;打开Makefile.sdk 将如下内容进行更改 4.复制设…

【前端设计】监控顺序返回型总线超时的计时器模块设计

前言 总线超时检查机制是系统中必要的模块设计&#xff0c;用于在总线无法返回response时能够及时上报中断。从理论上分析&#xff0c;如果总线发生了诸如挂死或者物理损坏等超时行为&#xff0c;无论计时器上报timeout的时间偏大还是偏小&#xff0c;都是一定可以上报中断的。…

Xilinx MicroBlaze系列教程(适用于ISE和Vivado开发环境)

本文是Xilinx MicroBlaze系列教程的第0篇文章。这个系列文章是我个人最近两年使用Xilinx MicroBlaze软核的经验和笔记,以Xilinx ISE 14.7和Spartan-6,以及Vivado 2018.3和Artix-7为例,介绍MicroBlaze软核、AXI系列IP核的软硬件使用,希望能帮助到更多的人。 MicroBlaze是Xil…

什么是有限元分析?能用来干什么

您是否想过工程师和制造商如何测试他们设计的耐用性、强度和安全性&#xff1f;如果您看过汽车广告&#xff0c;您可能会相信工程师和设计师不断地破坏他们的产品以测试其强度。您可能会得出结论&#xff0c;制造商会重复此过程&#xff0c;直到设计能够承受巨大的损坏并达到可…

夜游经济:夜景“亮化”,形象“美化”,经济“活化”

复杂的国际形势之下&#xff0c;扩大国内消费需求&#xff0c;激发消费市场潜力&#xff0c;堪称疫后经济复苏振兴的“金钥匙”。这一背景下&#xff0c;大力发展夜游经济&#xff0c;成为提振国内消费需求、促进城乡居民就业、拉动经济复苏增长的重要突破口。去年以来&#xf…

无法超越的100米_百兆以太网传输距离_网线有哪几种?

对网络比较了解的朋友&#xff0c;都知道双绞线有一个“无法逾越”的“100米”传输距离。无论是10M传输速率的三类双绞线&#xff0c;还是100M传输速率的五类双绞线&#xff0c;甚至1000M传输速率的六类双绞线&#xff0c;最远有效传输距离为100米。在综合布线规范中&#xff0…

Qt下实现欧姆龙PLC 串口发送HOSTLINK(FINS)模式

文章目录前言一、HOSTLINK协议说明二、校验码&#xff08;FCS&#xff09;计算三、示例完整代码四、下载链接总结前言 本文讲述了Qt下模拟串口调试工具发送HOSTLINK&#xff08;FINS&#xff09;模式&#xff0c;主要进行了HR保持区的字和位的读写&#xff0c;对HOSTLINK协议中…

记一次CPU飚高以及排查过程

一.cpu突然飚高 收到系统频发的cpu超过90%的告警.虽然是在非线上环境出现.接到告警后第一反应还是去重启了机器,重启后cpu如期的下降了下来.以为能高枕无忧,不过一会儿还是收到了告警. 二.排查 2.1 top 指令查看物理机进程id 申请了堡垒机权限登上机器 top指令后.如下确实发…

微服务,Docker, k8s,Cloud native 云原生的简易发展史

微服务发展史 2005年&#xff1a;Dr. PeterRodgers在Web ServicesEdge大会上提出了“Micro-Web-Services”的概念。2011年&#xff1a;一个软件架构工作组使用了“microservice”一词来描述一种架构模式。2012年&#xff1a;同样是这个架构工作组&#xff0c;正式确定用“micr…

万字详解 C 语言文件操作

目录 一、什么是文件&#xff1f; 1.1 - 文件和流的基本概念 1.2 - 文件的分类 1.3 - 文件名 二、缓冲文件系统和非缓冲文件系统 三、文件指针类型 四、文件的打开和关闭 4.1 - fopen 4.2 - fclose 五、文件的顺序读写 5.1 - 字符输出函数 fputc 5.2 - 字符输入函数…

【Kubernetes 企业项目实战】06、基于 Jenkins+K8s 构建 DevOps 自动化运维管理平台(上)

目录 一、k8s 助力 DevOps 在企业落地实践 1.1 传统方式部署项目为什么发布慢&#xff0c;效率低&#xff1f; 1.2 上线一个功能&#xff0c;有多少时间被浪费了&#xff1f; 1.3 如何解决发布慢&#xff0c;效率低的问题呢&#xff1f; 1.4 什么是 DevOps&#xff1f; …

【JavaScript】原型链

文章目录构造函数原型对象访问机制内置构造函数一切皆对象原型链构造函数 - 本质还是一个函数- 和 new 关键字连用- 特点1. 自动创建一个对象2. 自动返回一个对象3. 让函数的this指向这个对象 书写构造函数的时候1. 属性写在函数内2. 方法写在原型上构造函数的不合理 把方法写在…

Android studio 护眼模式配置、字体大小设置、内存大小设置等各类疑难杂症

Android studio 4.1 1、左边目录栏颜色配置&#xff1a; 2、代码编辑区域背景色设置 3、控制台背景色设置 4、菜单栏、工具栏、左边栏字体大小设置 5、编码区字体大小设置 6、修改内存大小、显示内存 例如&#xff1a;修改android-studio/bin/studio.vmoptions studio64.vmop…