[数据结构] 栈 (C语言)

栈的概念

栈(stack)是一种特殊的线性表存储结构,其一端可以进行插入和弹出的操作,而另一端是封死的。

可以把栈想象成是一个柱状的容器。就比如一个乒乓球筒,我们只能在筒的一段进行乒乓球的放入和取出。

栈顶和栈的两种操作

栈顶就是栈的开口端,每次都是在栈顶处插入元素和删除元素。
(1)入栈:将新元素存入栈中,并作为新的栈顶元素;
(2)出栈:将栈顶元素弹出,并将其下面的元素作为新的栈顶元素。

栈的特性

栈有着先进先出的特性。假如入栈元素依次是 1、2、3 ,且中途没有元素出栈,那么最后所有元素出栈的顺序是 3、2、1



顺序栈

顺序栈基本概念

顺序栈是用数组来实现栈的存储结构,一般会定义一个栈顶 top,初始情况下 top 值为-1,表示栈为空,此时栈中无任何元素。
每当有元素入栈,top+1 ; 有元素出栈, top-1

顺序栈的入栈操作

顺序栈入栈操作图解

初始情况下的栈

元素1入栈

元素2入栈

元素3入栈

顺序栈入栈操作代码

//元素入栈
void push(SqStack *s, Elemtype x){
    if(s->top == MAXSIZE - 1) return;  //栈满
    s->data[++s->top] = x;
}


顺序栈的出栈操作

顺序栈出栈操作图解

元素3出栈

元素2出栈

元素1出栈

顺序栈出栈操作代码

//元素出栈
void pop(SqStack *s, Elemtype *x){
    if(s->top == -1) return;  //栈空
    *x = s->data[s->top--];
}


顺序栈完整程序

源代码

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define MAXSIZE 1000

typedef int Elemtype;
typedef struct{

    Elemtype data[MAXSIZE];
    int top;                //栈顶指针

}SqStack;

//初始化栈
void Init_SqStack(SqStack *s){
    s->top = -1;
}

//判断栈是否为空
bool IsEmpty(SqStack *s){
    return s->top == -1;
}

//元素入栈
void push(SqStack *s, Elemtype x){
    if(s->top == MAXSIZE - 1) return;
    s->data[++s->top] = x;
}

//元素出栈
void pop(SqStack *s, Elemtype *x){
    if(s->top == -1) return;
    *x = s->data[s->top--];
}

//取栈顶元素
Elemtype top(SqStack *s){
    if(IsEmpty(s)){
	printf("栈为空\n");
	return -1;
    }
    return s->data[s->top];
}

int main(){
    SqStack mystack;
    Init_SqStack(&mystack);

    for(int i = 1; i <= 5; i++)
	push(&mystack, i);
    printf("当前栈顶元素为: %d\n", top(&mystack));

    int e;
    pop(&mystack, &e);
    printf("出栈元素为: %d\n", e);
    printf("当前栈顶元素为: %d\n", top(&mystack));

    printf("全部元素出栈:\n");
    while(!IsEmpty(&mystack)){
    	printf("%d ", top(&mystack));
    	pop(&mystack, &e);
    }
}

顺序栈运行测试



链栈

链栈基本概念

链栈是用链式存储结构实现的,在实现过程中,需要定义一个 top 指针保持指向当前栈顶。操作过程和链表有些相似。

链栈的入栈操作

链栈入栈操作图解

初始情况下的链栈

元素1入栈

元素2入栈

元素3入栈

链栈入栈操作代码

//入栈
void LinkStack_push(LinkStack *S, ElemType e){
    LinkStacknode *node;            
    node = (LinkStacknode *) malloc(sizeof(LinkStack));
    node->data = e;            
    node->next = S->top;       //新节点的next指向此时的top
    S->top = node;             //top指针指向新的节点

    S->length++;
}



链栈的出栈操作

链栈出栈操作图解

元素3出栈

元素2出栈

元素1出栈

链栈出栈操作代码

//出栈
void LinkStack_pop(LinkStack *S, ElemType *e){
    if(IsEmpty(S))               //栈空
        return;                  
    LinkStacknode *del = S->top; 
    *e = del->data;              
    S->top = del->next;          //top跳过出栈节点,指向出栈节点的下一节点

    S->length--;
    free(del);                   //释放内存
}


链栈完整程序

源代码

#include <stdio.h>
#include <stdlib.h>

//定义数据类型
typedef int ElemType;

//链栈的节点结构
typedef struct LinkStacknode
{

    ElemType data;              //存数据
    struct LinkStacknode *next; //存下个节点的地址

} LinkStacknode;

//链栈的整体结构  
typedef struct {

    LinkStacknode *top;
    int length;
    
} LinkStack;


//初始化链栈
void Create_LinkStack(LinkStack *S){
    S->top = NULL;
    S->length = 0;
}

//判断栈为空
bool IsEmpty(LinkStack *S){
    return S->length == 0;
}

//入栈
void LinkStack_push(LinkStack *S, ElemType e){
    LinkStacknode *node;            
    node = (LinkStacknode *) malloc(sizeof(LinkStack));
    node->data = e;            
    node->next = S->top;       //新节点的next指向此时的top
    S->top = node;             //top指针指向新的节点

    S->length++;
}

//出栈
void LinkStack_pop(LinkStack *S, ElemType *e){
    if(IsEmpty(S))               //栈空
        return;                  
    LinkStacknode *del = S->top; 
    *e = del->data;              
    S->top = del->next;          //top跳过出栈节点,指向出栈节点的下一节点

    S->length--;
    free(del);                   //释放内存
}

//取栈顶
ElemType LinkStack_getTop(LinkStack *S){
    if(IsEmpty(S)){
        printf("栈为空\n");
        return -1;
    }
    return S->top->data;
}

int main(){
    LinkStack S;
    Create_LinkStack(&S);

    ElemType e;
    ElemType a[5] = {3,6,7,9,10};
    for(int i = 0; i < 5; i++)
        LinkStack_push(&S, a[i]);

    printf("栈顶元素:%d\n", LinkStack_getTop(&S));

    LinkStack_pop(&S, &e);
    printf("出栈元素:%d\n", e);   

    printf("全部元素出栈:\n");
    while(!IsEmpty(&S)){
        printf("%d ", LinkStack_getTop(&S));
        LinkStack_pop(&S, &e);
    }
    return 0;
}

链栈运行测试



一切都是命运石之门的选择,本文章来源于博客园,作者:Amαdeus,出处:http://www.cnblogs.com/MAKISE004/p/17062088.html,未经允许严禁转载

本文转载于网络 如有侵权请联系删除

相关文章

  • Redis源码剖析之持久化

      Redis提供了两种持久化方式:RDB和AOF,下面,我们来看看上述两者的底层实现原理。一,RDB持久化  1.RDB文件的创建与载入  在Redis中,有两种方式可以生成RDB文件,一个是SAVE,另一个是BGSAVE  两者的主要区别是:SAVE命令在进行持久化操作的过程中,会阻塞Redis服务进行,也就是说,在以SAVE方式进行持久化操作的过程中,服务器不能再处理其他的命令请求,这个请求过程必须等到持久化操作结束;BGSAVE命令则是单独开启一个子进程来处理持久化操作。  上述过程用伪代码表现形式如下:defsave():   rdbSave()#将数据写入文件操作defbgsave():   #创建子进程  pid=fork()  ifpid==0:     #子进程负责创建RDB文件    rdbSave()     #完成之后向父进程发送信号    signal_parent()  elifpid>0:     #父进程继续处理命令请求,并通过轮询等待子进程信号    handle_request_and_wait_signal()   else:     #处理

  • 【每日SQL打卡】​​​​​​​​​​​​​​​DAY 5丨员工奖金【难度简单】

    难度简单SQL架构选出所有bonus<1000的员工的name及其bonus。Employee 表单+-------+--------+-----------+--------+ | empId |  name  | supervisor| salary | +-------+--------+-----------+--------+ |   1   | John   |  3        | 1000   | |   2   | Dan    |  3        | 2000   | |   3   | Brad   |  null     | 4000   | |   4   | Thomas |  3        | 4000   | +-------+--------+-----------+--------+ empId 是这张表单的主关键字复制Bonus 表单+-------+-------+ | empId | bonus | +-------+-------+ | 2     | 500   | | 4     | 2000  | +-------+--

  • 白话设计模式之代理模式

    代理模式介绍 代理模式,顾名思义,代理就是不自己做,让别人来帮忙做,现实中有很多例子,比如中介公司,婚介所,这些都是代理典型的代理机构,比如我想找一个女朋友,但是由于我的脸皮比较薄,不好意思和女孩子说话,更没有搭讪的勇气,于是乎,我找到了我的好朋友mikey老师,让他给我介绍一下,他答应了我的请求,于是我就去专心写代码了,女朋友的事情就交在他身上了,我不去瞎操心了。Java语言来表示这一过程定义一个接口publicinterfaceIPeople{ //找女朋友 voidfindGirlFriend(); }复制单身狗steakliu委托mikey老师帮忙找女朋友publicclassSteakimplementsIPeople{ privatefinalMikeyTeachermikeyTeacher; publicSteak(MikeyTeachermikeyTeacher){ this.mikeyTeacher=mikeyTeacher; } @Override publicvoidfindGirlFriend(){ System.out.println("steak:

  • Elastic 线下 Meetup 深圳站来了!

    Elastic中文社区联合腾讯云大数据,腾讯云+社区,将于2021年8月21日在腾讯滨海大厦举办本年度首次线下(线上同步直播)技术交流活动。本次活动的交流内容主要围绕ElasticStack产品(Elasticsearch、Logstash、Kibana和Beats)及周边技术,探讨在搜索、数据实时分析、日志分析、安全、APM等领域的实践与应用。 在信息爆炸的今天,人们的交流日渐频繁,商业公司逐渐由实体驱动变成信息驱动,这信息不仅包含我们看得到听得到的比如音视频,还有更重要的文本信息。这些文本信息有看得到的文字信息,还有看不见的用户行为以及计算机系统日志,怎样在这些信息找到自己需要的内容并进行分析,成为摆在每个有数据资产公司的面前的难题,大家都想要一个自己的搜索引擎。Elasticsearch的出现,让搭建自己搜索引擎的门槛变得非常低。Elasticsearch是一个基于Lucene的开源搜索服务器,可以实时搜索,稳定、可靠、快速,是目前最主要的企业搜索引擎。同时开源软件也意味着灵活,可以定制,当数据规模达到一定程度时,如何按照自己的业务需求去高效使用ES,很多场景无法照搬,我们需要多

  • 10个顶级Python实用库,推荐你试试!

    为什么我喜欢Python?对于初学者来说,这是一种简单易学的编程语言,另一个原因:大量开箱即用的第三方库,正是23万个由用户提供的软件包使得Python真正强大和流行。在本文中,我挑选了15个最有用的软件包,介绍它们的功能和特点。1.DashDash是一个用于构建基于Web的应用程序的Python库,无需JavaScript。Dash同时也是用于创建分析Web应用程序的用户界面库。那些使用Python进行数据分析、数据挖掘、可视化、建模、仪器控制和报告的人可以立即使用Dash。Dash建立在Plotly.js、React和Flask之上,将现代UI元素(如下拉列表、滑块和图形)与你的分析Python代码相结合。项目地址:https://github.com/plotly/dash复制2.PillowPillow专门用于处理图像,您可以使用该库创建缩略图,在文件格式之间转换,旋转,应用滤镜,显示图像等等。如果您需要对许多图像执行批量操作,这是理想的选择。为了快速了解它,看以下代码示例(加载并渲染图片):帮助文档:https://pillow-cn.readthedocs.io/zh_CN

  • 机器学习理论 | 大型神经语言模型的对抗训练

    作者|何文嘉 编辑|李仲深摘要1介绍2初步工作2.1输入表征2.2模型结构2.3自监督3ALUM(大型神经语言模型的对抗性训练)3.1标准训练目标3.2对抗训练3.3ALUM算法3.4算法分析4实验4.1泛化性的对比4.2鲁棒性的对比4.3综合对抗性预训练和微调参考文献摘要泛化性和鲁棒性是设计机器学习方法的关键。对抗性训练可以增强鲁棒性,但过去的研究经常发现它会损害泛化能力。在自然语言处理(NLP)中,预训练的大型神经语言模型(如BERT)在各种任务的泛化方面表现出了令人印象深刻的增益,而且通过对抗性微调还可以得到进一步的改进。然而,这些模型仍然容易受到对抗性攻击。在本文中,我们证明了对抗性预训练可以提高泛化性和鲁棒性。我们提出了一种通用算法ALUM(AdversarialtrainingforlargeneuralLangUageModels,大型神经语言模型的对抗性训练),它通过在嵌入空间中施加扰动使对抗性损失最大化来调整训练目标。我们首次全面研究了对抗性训练的各个阶段,包括从头开始的预训练、在训练有素的模式下持续的预训练以及特定任务中的微调。ALUM在各种NLP任务上都比BERT

  • 10.2【前端开发】图片文件格式:常见的图片格式对比有何优劣以及如何使用Google的webp格式?

    1、JPEG:①支持摄影图像或写实图像的高级压缩,并且可利用压缩比例控制图像文件大小;②有损压缩会使图像数据质量下降,③JPG不适合具有大块颜色相近的区域或亮度,适合差异十分明显的较简单的图片,④JPG在存储摄影或写实图像一般能达到最佳的压缩效果,比如网站的背景图,轮播图,用户头像等2、PNG的优缺点①能在保证最不失真的情况下尽可能压缩图像文件的大小。②PNG用来存储灰度图像时,灰度图像的深度可多到16位,存储彩色图像时,彩色图像的深度可多到48位。③对于需要高保真的较复杂的图像,PNG虽然能无损压缩,但图片文件较大,PNG8可以用来做小图标(icons),按钮,背景等。3、GIF图片是一种无损压缩的格式,GIF格式可以用来做动画总结一下,对于色彩与图像内容比较丰富,变化比较多端的,适合使用jpg,例如大型背景、头像、人物照片等。对于颜色单一,有大色块的图像,例如图标等,适合用png,压缩效率高,并且有透明。小动画可以使用gif,便不适合使用复杂的视频。Googlewebp格式图片网络中图片是占用流量较大的一部分,如何在保证图片视觉不失真前提下缩小体积,对于节省带宽和电池电量十分重要,

  • Docker常用软件安装之Redis

      本文我们来介绍下在Docker中如何安装Redis。1.dockerhub上搜索Redisdockersearchredis复制2.下载镜像  从dockerhub上下载4.0版本的Redisdockerpullredis:4.0复制3.运行容器  镜像下载好后,我们就可以执行如下命令来运行了dockerrun-p6379:6379-v/root/myredis/data:/data-v/root/myredis/conf/redis.conf:/usr/local/etc/redis/redis.conf-dredis:4.0redis-server/usr/local/etc/redis/redis.conf--appendonlyyes复制4.验证  我们首先需要在root/myredis/conf/redis.conf目录下创建redis.conf配置文件。#Redisconfigurationfileexample. # #Notethatinordertoreadtheconfigurationfile,Redismustbe #startedwiththefil

  • 10.Elasticsearch查询关键字1

    本文讲解几个查询时常用的关键字:match_all查询match查询multi_match查询range查询term查询terms查询exists查询和missing查询match_all查询match_all查询简单的匹配所有文档。在没有指定查询方式时,它是默认的查询:{"match_all":{}}复制它经常与filter结合使用–例如,检索收件箱里的所有邮件。所有邮件被认为具有相同的相关性,所以都将获得分值为1的中性_score。match查询无论你在任何字段上进行的是全文搜索还是精确查询,match查询是你可用的标准查询。如果你在一个全文字段上使用match查询,在执行查询前,它将用正确的分析器去分析查询字符串:{"match":{"tweet":"AboutSearch"}}复制如果在一个精确值的字段上使用它,例如数字、日期、布尔或者一个not_analyzed字符串字段,那么它将会精确匹配给定的值:{"match":{"age":26}} {"m

  • Swift学习:构造器(中)

    本篇继续对Swift中的构造器进行介绍,这里主要说到类的继承和构造。作为引用类型的类具有的继承特性,这使得类的构造过程较为复杂一些,因为涉及到很多细节性的问题。在使用之前,我们需要了解一些基本的问题:类中所有存储属性,包括继承父类的属性,都要在构造过程中设置初值Swift类的构造器分为指定构造器和便利构造器,确保完成构造过程一、指定构造器和便利构造器指定构造器:类的主要构造器,负责初始化类中所有属性,在继承关系中可调用父类链中的父类构造器每个类至少一个指定构造器。但是某些情况下,许多类是通过继承父类的指定构造器来满足这个条件便利构造器:辅助类型的构造器,调用同一个类中的指定构造器完成类的初始化操作便利构造器需要在init关键字之前添加convenience关键字,使用空格分开classFatherClass{ varvalueOne:Int //指定构造器 init(valueOne:Int){ self.valueOne=valueOne } } classChildClass:FatherClass{ varvalueTwo:Int//子类的新引入属性 //指定构造器 init(

  • 无人车烧钱大战升级:Waymo要新增500辆测试车

    李林编译整理 量子位报道|公众号QbitAI大洋彼岸的无人车军备竞赛,似乎进入了一种高端烧钱模式。昨天,Waymo宣布要再增加500辆测试车。这让量子位不禁想起了本月中旬的事:通用汽车在向美国联邦交通管理委员会(FCC)提交的文件中透露,这家公司可能从下月开始,要增加300辆搭载了近程和中程雷达的自动驾驶测试车。今年2月,更是有消息人士向路透社表示,通用汽车计划从2018年开始,部署上千辆自动驾驶测试车。我们先不说上千辆,等这300辆车上路,通用汽车就将取代Waymo(AKA谷歌无人车团队),成为美国规模最大的测试车队。可是5月还没到,Waymo就打碎了这个美梦。昨天,这家公司在宣布招募几百名志愿者试乘的同时,还轻描淡写地“扔了一个炸弹”:Waymo那个克莱斯勒Pacifica自动驾驶车队,再来500辆!Waymo官方博客中,没有明确地说这500辆车什么时候加,但是已经被不少西方媒体解读成不是这个月就是下个月。此前,Waymo拥有70辆雷克萨斯测试车,去年5月他们和克莱斯勒宣布合作时,也宣布要生产100辆自动驾驶Pacifica。目前,这100辆车已经陆续上路,Waymo也一直维持着北

  • android 4怎么打开usb调试?「建议收藏」

    大家好,又见面了,我是你们的朋友全栈君。手机连接电脑,刷机,等都需要打开手机USB调试模式,你才能进行操作的。所以买了手机建议都要打开这个USB调试,手机锁屏密码忘记也需要打开这个。这个比较重要。工具/原料手机安卓android系统方法/步骤 打开自己的手机找到《设置》点击,进入以下图例。 在点击《关于手机》 进入《关于手机》页面,找到(版本号)连续点击3-7次左右,直到提示您已处于开发模式。然后返回到设置页面 返回到设置页面之后,点击《其他》进入以下页面,选择《开发者选项》进入下一步操作 点击《开发者选项》之后,会进入图例页面,就会看到《USB调试》,打开即可完成。以上教程方法到此结束。 版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容,请发送邮件至举报,一经查实,本站将立刻删除。发布者:全栈程序员栈长,转载请注明出处:https://javaforall.cn/194498.html原文链接:https://javaforall.cn

  • 冒泡排序学习总结

    目录1、算法描述2、算法实现3、算法优化3.1减少内层循环比较次数3.2减少冒泡次数3.3进一步优化总结1、算法描述 这里有一个无序数组,接下来我要用冒泡的方式对其进行排序,冒泡排序的关键是相邻的两个元素进行比较。比如说刚开始索引0和索引1进行比较,如果是前一个小于后一个,它的位置可以不动。 这里3是大于2的所以交换位置。 然后比较索引1和索引2,3比4小不用交换位置,后面的以此类推。到这里我们就看到最大的7已经移到了数组的最后,相当于已经把最大的元素已经冒泡成功了,完成了一轮冒泡。接下来就是重复这个排序的动作,直到所有元素排序完成。2、算法实现packagecom.jie.bubbling; importjava.lang.reflect.Array; importjava.util.Arrays; /** *@description:冒泡排序 *@author:jie *@time:2022/2/819:44 */ publicclassBubbling{ publicstaticvoidmain(String[]args){ int[]a={5,9,3,7,2,1,8,4};

  • 一篇了解全MVCC

    一、什么是MVCC MVCC,全称Multi-VersionConcurrencyControl,即多版本并发控制,是一种并发控制的方法,一般用在数据库管理系统中,实现对数据库的并发访问,比如在MySQLInnoDB中主要是为了提高数据库并发性能,不用加锁,非阻塞并发读。MVCC多版本并发控制指的是维持一个数据的多个版本,使得读写操作没有冲突,快照读是MySQL为实现MVCC的一个非阻塞读功能。 二、解决的问题是什么 ​1、三种数据库并发场景: 读读:不会有问题,也不需要并发控制 ​读写:有线程安全问题,可能会造成事务隔离性问题,可能遇到脏读、幻读、不可重复读 ​写写:有线程安全问题,可能存在更新丢失问题 2、解决问题 ​MVCC是一种用来解决读写冲突的无锁并发控制,也就是为事务分配单项增长的时间戳,为每个修改保存一个版本,版本与事务时间戳关联,读操作只读该事务开始前的数据库的快照(隔离级别RC下),所以MVCC为数据库解决了以下问题: 在并发读写数据库时,可以做到在读操作时不用阻塞写操作,写操作也不用阻塞读操作,提高了数据库并发读写的性

  • this loop will spin, using 100% CPU (SA5002)go-staticcheck 自旋

           for{     } 搜索 复制

  • 用ndk-stack分析应用native程序异常crash掉

    adblogcat|"/home/hxl/bin/android-ndk-r10d/ndk-stack"-sym"/home/hxl/plu/BadGame/proj.android/obj/local/armeabi/obj/local/armeabi"     这几天在做android下的音频播放器,使用ffmpeg做解码器,过程中出现一个问题,执行的时候出现下面这个问题:  Java代码   03-24 15:05:37.094: I/DEBUG(3223): *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***   03-24 15:05:37.094: I/DEBUG(3223): Build fingerp

  • CIFAR10数据可视化

    一、数据准备 下载cifar-10-binary.tar.gz并解压,其中有多个bin文件,现对data_batch_1.bin进行可视化。   二、数据说明 该二进制文件存储的有10000张32X32的三通道图片以及对应的label。 具体存放方式为第一个字节先存该张图的label,即该张图属于哪一类,数值从0~9,接着3072(32X32X3)个字节存放对应的图片,图片降维成一维,按rgb的顺序进行存放。   三、matlab2016代码 在数据同目录下新建show_cifar10_data.m clear; clc; closeall; strings={ 'airplane' 'automobile' 'bird' 'cat' 'deer' 'dog' 'frog' 'horse' 'ship' 'truck' }; image_file_name='data_batch_1.bin'; fid1=fopen(image_file_name,'rb'); images_data=fread(fid1,'uint8'); fclose(fid1); ima

  • 使用AutoHotKey基本实现CapLock+

    起因 因为使用公司的电脑无法使用CapLock+这款插件,所以通过自己编写的AutoHotKey脚本去实现CapLock+这款插件的大概功能 脚本文件 编写脚本文件参考 capLock+.ahk #NoEnv;RecommendedforperformanceandcompatibilitywithfutureAutoHotkeyreleases. ;#Warn;Enablewarningstoassistwithdetectingcommonerrors. SendModeInput;Recommendedfornewscriptsduetoitssuperiorspeedandreliability. SetWorkingDir%A_ScriptDir%;Ensuresaconsistentstartingdirectory. ;上下左右 CapsLock&s:: Send{Left} return CapsLock&f:: Send{Right} return CapsLock&e:: Send{Up} return CapsLock

  • 理解依赖注入 for Zend framework 2

    依赖注入(DependencyInjection),也成为控制反转(InversionofControl),一种设计模式,其目的是解除类之间的依赖关系。 假设我们需要举办一个Party,Party需要主持人、厨师、灯光、音响、食品、酒水等等。那么Party对他们存在依赖关系。用程序语言表示如下: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 复制 //Party.php classParty{ //主持人 private$_host;   function__construct(){ include"./Host.php"; $this->_host=newHost(); }   functionstartParty(){ $this->_host->sayHello(); } }   //Host.php classHost{ private$_name; functionsayHello(){ echo"Mynameis".$th

  • Android开发——为移动的Paint元素指定图片的方法

        源 起     最近在写一个类似“围住神经猫”的应用,现在需要给一个可以移动的Paint元素指定一张图片,如下图,要把黄点改成其他图片;   Paint所在的类继承于SurfaceView,SurfaceView可以直接从内存等硬件接口获取图像数据,速度很快;然后再implements一个OnTouchListener接口来监听触摸事件;       过 程     最初找到很多方法,给playground添加图片、给Activity添加图片、另写一个工具类加载图片。。。都很繁琐,而且代码加进去运行的时候总是Crash,可能是自己操作存在问题,这些方法都没有实现想要的效果;   后来发现,只需要在redraw()函数中添加几行代码~   图像绘制函数redraw()的代码是这样写的,功能是设置路障圆点、路径圆点和一个移动圆点的颜色: publicvoidredraw(){ //绘制 Canvasc=getHolder().lockCanvas(); //c.drawColor(Color.LTGRAY);

  • A9 FlyMCU设置

相关推荐

推荐阅读