DevC++ easyx实现图片拖动,一种悬浮窗实现原理与完整代码

 

翻出来之前写的代码,

EasyxDevC++开发地图编辑和游戏编辑代码工程文件附注释_哔哩哔哩_bilibili

每次把代码备份下来,等着有一天能够复用代码,产生新的价值。 

结果最近这几天才来回顾记录emm

“这是怎么搓出来的?”从10行代码到400行代码的小工程,无中生有的各版本备份——EasyxDevC++开发地图编辑和游戏编辑代码开发过程代码附注释_哔哩哔哩_bilibili

虽然视频简介里把资源代码网盘链接传了,鄙人的CDSN主页也一块上传了相同的资源。 但是没有讲解,素材硬看也是消耗比较大的,价值再次产生和无中生有价值,这两个讲解方式应该不同。一个是面向穷举,一个是马后炮解释和背景思路介绍。

使用方式如视频“这是怎么搓出来的?”从10行代码到400行代码的小工程,无中生有的各版本备份——EasyxDevC++开发地图编辑和游戏编辑代码开发过程代码附注释_哔哩哔哩_bilibili

视频简介里的各种链接都已经提出相应问题的解决方案。

这次来实现一个悬浮窗,这是在开发绘图板的两周共30小时,解决生成的瓦片图片要拖动指定区域的问题。这就是自热而然的背景。

操作:

长按鼠标左键,点亮黄色的像素点。

按住Ctrl+鼠标左键,长按点击黑色图片就能拖动图片了。

效果如图

 

原理:放置原像,扫描保存,粘贴新像。

上代码,看注释,具体说明 

完整代码,新建项目,复制粘贴直接跑。代码出处是图中序号9.的文件(9.拖动而且能画画)

#include<stdio.h>
#include<conio.h>
#include<graphics.h>//void draw(struct Exmessage m){
//
//}
void move(struct ExMessage m) {static	IMAGE img2;
//	getimage(&img2,100,100,200,200);
//	检测static	IMAGE img3;static	int x=100,y=100;static  int px=0,py=0;static int flag=0;if(flag==1) {BeginBatchDraw();putimage(x,y,&img3);
//			在原位置恢复底层getimage(&img3,m.x+px,m.y+py,200,200);
//			获取原位置和将要覆盖区域的底色   px+m.x=100+m.x2-m.x1;=100+kx,相对位移同鼠标
//			getimage(m.x,m.y,&img3);putimage(m.x+px,m.y+py,&img2);
//			覆盖x=m.x+px;y=m.y+py;//			保存这次位置,成为下次的原位置,找到痕迹EndBatchDraw();
//			一次绘图出来,没有屏闪了} else if(flag==2)putpixel(m.x,m.y,RGB(255,155,4));
//			批量绘制,不会闪烁了
//			Sleep(1);switch(m.message) {case WM_LBUTTONDOWN:if(m.x>x&&m.x<x+200&&m.y>y&&m.y<y+200&&m.ctrl) {flag=1;
//					启动批复制粘贴getimage(&img2,x,y,200,200);
//					putimage(200, 200, &img1);
//					按动了就出现白块px=x-m.x;py=y-m.y;
//					记录鼠标和图片左上角的差值} else  {flag=2;}break;case WM_LBUTTONUP:flag=0;break;}
}
int main() {initgraph(640,640);setbkcolor(WHITE);cleardevice();setfillcolor(BLACK);setlinecolor(BLACK);//	这是初始图片左上角位置,以后都是新图片左上角的位置//	模的增量位移保存fillrectangle(100,100,300,300);
//	参考按钮while(1) {ExMessage m;m=getmessage(EX_MOUSE|EX_KEY);move(m);}closegraph();return 0;
}

这是第一代运行的版本,代码方面的别扭就是未来开发,移植函数的时候不好移植,因为画点的函数putpixel()也在这个拖动函数里。于是分离

分离之后的新版本

完整代码,对应序号10.bug分析......文件。主函数里用两个if和标志位实现原函数的功能分离。

#include<stdio.h>
#include<conio.h>
#include<graphics.h>void draw(struct ExMessage m,int *flag1,int *qx,int *qy) {int x=*qx,y=*qy;int flag=*flag1;if(flag==2)putpixel(m.x,m.y,RGB(255,155,4));switch(m.message) {case WM_LBUTTONDOWN:if(m.x>x&&m.x<x+200&&m.y>y&&m.y<y+200&&m.ctrl) {} else  {flag=2;}
//			flag=2;
//			bug和移动函数问题break;case WM_LBUTTONUP:flag=0;break;}*flag1=flag;
}void check(struct ExMessage m,int *flag1,int *qx,int*qy) {static	IMAGE img2;
//	getimage(&img2,100,100,200,200);
//	检测static	IMAGE img3;static	int x=*qx,y=*qy;static  int px=0,py=0;static int flag=*flag1;if(flag==1) {BeginBatchDraw();putimage(x,y,&img3);
//			在原位置恢复底层getimage(&img3,m.x+px,m.y+py,200,200);
//			获取原位置和将要覆盖区域的底色   px+m.x=100+m.x2-m.x1;=100+kx,相对位移同鼠标
//			getimage(m.x,m.y,&img3);putimage(m.x+px,m.y+py,&img2);
//			覆盖x=m.x+px;y=m.y+py;//			保存这次位置,成为下次的原位置,找到痕迹EndBatchDraw();
//			一次绘图出来,没有屏闪了}switch(m.message) {case WM_LBUTTONDOWN:if(m.x>x&&m.x<x+200&&m.y>y&&m.y<y+200&&m.ctrl) {flag=1;
//					启动批复制粘贴getimage(&img2,x,y,200,200);
//					putimage(200, 200, &img1);
//					按动了就出现白块px=x-m.x;py=y-m.y;
//					记录鼠标和图片左上角的差值}break;case WM_LBUTTONUP:flag=0;break;}*flag1=flag;*qx=x;*qy=y;
}//
//
//void move(struct ExMessage m) {
//
//	static	IMAGE img2;getimage(&img2,100,100,200,200);检测
//	static	IMAGE img3;
//	static	int x=100,y=100;
//	static  int px=0,py=0;
//	static int flag=0;
//	if(flag==1) {
//		BeginBatchDraw();
//		putimage(x,y,&img3);在原位置恢复底层
//		getimage(&img3,m.x+px,m.y+py,200,200);获取原位置和将要覆盖区域的底色   px+m.x=100+m.x2-m.x1;=100+kx,相对位移同鼠标getimage(m.x,m.y,&img3);
//		putimage(m.x+px,m.y+py,&img2);覆盖
//		x=m.x+px;
//		y=m.y+py;
//		//			保存这次位置,成为下次的原位置,找到痕迹
//		EndBatchDraw();一次绘图出来,没有屏闪了
//	} else if(flag==2)
//		putpixel(m.x,m.y,RGB(255,155,4));批量绘制,不会闪烁了Sleep(1);
//
//	switch(m.message) {
//
//		case WM_LBUTTONDOWN:
//
//			if(m.x>x&&m.x<x+200&&m.y>y&&m.y<y+200&&m.ctrl) {
//				flag=1;启动批复制粘贴
//				getimage(&img2,x,y,200,200);putimage(200, 200, &img1);按动了就出现白块
//				px=x-m.x;
//				py=y-m.y;记录鼠标和图片左上角的差值
//			} else  {
//				flag=2;
//
//			}
//			break;
//		case WM_LBUTTONUP:
//			flag=0;
//			break;
//	}
//}
int main() {initgraph(640,640);setbkcolor(WHITE);cleardevice();setfillcolor(BLACK);setlinecolor(BLACK);//	这是初始图片左上角位置,以后都是新图片左上角的位置//	模的增量位移保存fillrectangle(100,100,300,300);
//	参考按钮
//	int qx=100;
//	int qy=100;
//	int flag=0;while(1) {ExMessage m;m=getmessage(EX_MOUSE|EX_KEY);static int qx=100;static int qy=100;static int flag=0;if(flag==0||flag==2)draw(m,&flag,&qx,&qy);if(flag==0||flag==1)check(m,&flag,&qx,&qy);
//		move(m);}closegraph();return 0;
}

 

 

 后来发现还有个bug,就是原来位置的贴图还在,这样拖动,原来的图片没有受到影响,相当于是复制粘贴了,所以还要想办法把原图清除掉。

后来想当然就想着在第一步移动之前覆盖图片,然后画白色矩形,但是想用原来的函数试试,相当于提前拖动一步。结果代码插入位置错误,甚至拖动也不能拖动,原因是间接使得控制变量共用,导致变量第一步死锁,后续不能修改变量。变量变成常数,失去了变化分类作用,就不能实现由不拖动到拖动的转换。

试了试几次,不得不人脑一行一行读check代码,发现一开始的旧图img3是空的。第一步img2读取黑色,第二步img3粘贴空的,第三步img3读取黑色作为下次粘贴,恢复原貌,第四步img2粘贴,完成一次拖动循环。

原来穷举清楚代码步骤就能自然而然地发现问题,黑色旧图没有消失,就是第三步img3读取的是黑色,旧地方应该放上白色,就是这四个阶段里插入一个只执行一次覆盖的代码。然后实际上是img2读取完黑色,图片就存起来了,原来地方的图片就可以不用了,就在img2执行完加上一块画矩形的代码,然后再增加参数,限制只使用一次,以后都不用了。

其实这说明实现拖动功能的函数控制变量的不安全性,函数结束,时,控制变量不一定复位。复位功能和其他参数绑定,导致其他参数没有作用时自己运行导致死锁。想办法增加一个检测if语句,如果有类似这种情况,就进行复位。

这就是矛盾中进步,无中生有bug,无中生有的复位。

后续可能新开发方向:多个悬浮图片。

当然后续发现拖动多个图片,由于函数内部暂存变量,导致多个图片共用同一个函数,变量一对多,导致记录对不上图片。想办法一个图片有自己独有的变量,就是一堆小弟。而这个群体的概念就是结构体,而这些参数可以再次包装,一个函数传入一个结构体,这个结构体包含被拖动图片的全部信息,这样就能实现多个图片拖动。图片的数据归结进各自的结构体。

这里没有封装结构体,因为封装了,面目全非,真正投入使用的成品代码可以详见EasyxDevC++开发地图编辑和游戏编辑代码工程文件附注释_哔哩哔哩_bilibili

本节最终完整代码:不带结构体封装的,原地图片被拖走的代码

效果图:

#include<stdio.h>
#include<conio.h>
#include<graphics.h>void draw(struct ExMessage m,int *flag1,int *qx,int *qy) {int x=*qx,y=*qy;int flag=*flag1;if(flag==2)putpixel(m.x,m.y,RGB(255,155,4));switch(m.message) {case WM_LBUTTONDOWN:if(m.x>x&&m.x<x+200&&m.y>y&&m.y<y+200&&m.ctrl) {} else  {flag=2;}
//			flag=2;
//			bug和移动函数问题break;case WM_LBUTTONUP:flag=0;break;}*flag1=flag;
}void check(struct ExMessage m,int *flag1,int *qx,int*qy) {static	IMAGE img2;
//	getimage(&img2,100,100,200,200);
//	检测static	IMAGE img3;
//	static  int one=1;
//	if(one==1) {
//		setfillcolor(WHITE);
//		fillrectangle(100-1,100-1,300,300);
//		one==0;
//	}static	int x=*qx,y=*qy;static  int px=0,py=0;static int flag=*flag1;if(flag==1) {BeginBatchDraw();putimage(x,y,&img3);
//			在原位置恢复底层getimage(&img3,m.x+px,m.y+py,200,200);
//			获取原位置和将要覆盖区域的底色   px+m.x=100+m.x2-m.x1;=100+kx,相对位移同鼠标
//			getimage(m.x,m.y,&img3);putimage(m.x+px,m.y+py,&img2);
//			覆盖x=m.x+px;y=m.y+py;//			保存这次位置,成为下次的原位置,找到痕迹EndBatchDraw();
//			一次绘图出来,没有屏闪了}switch(m.message) {case WM_LBUTTONDOWN:if(m.x>x&&m.x<x+200&&m.y>y&&m.y<y+200&&m.ctrl) {flag=1;
//					启动批复制粘贴getimage(&img2,x,y,200,200);
//					putimage(200, 200, &img1);
//					按动了就出现白块//				静态变量只做一次,此后永不执行 static  int one=1;if(one==1) {setfillcolor(WHITE);fillrectangle(100-1,100-1,300,300);one==0;}//				这里把之前的图片覆盖,当然由于矩形框的颜色没有设置成白色,于是留出来黑色的矩形框没有覆盖 px=x-m.x;py=y-m.y;
//					记录鼠标和图片左上角的差值}break;case WM_LBUTTONUP:flag=0;break;}*flag1=flag;*qx=x;*qy=y;
}//
//
//void move(struct ExMessage m) {
//
//	static	IMAGE img2;getimage(&img2,100,100,200,200);检测
//	static	IMAGE img3;
//	static	int x=100,y=100;
//	static  int px=0,py=0;
//	static int flag=0;
//	if(flag==1) {
//		BeginBatchDraw();
//		putimage(x,y,&img3);在原位置恢复底层
//		getimage(&img3,m.x+px,m.y+py,200,200);获取原位置和将要覆盖区域的底色   px+m.x=100+m.x2-m.x1;=100+kx,相对位移同鼠标getimage(m.x,m.y,&img3);
//		putimage(m.x+px,m.y+py,&img2);覆盖
//		x=m.x+px;
//		y=m.y+py;
//		//			保存这次位置,成为下次的原位置,找到痕迹
//		EndBatchDraw();一次绘图出来,没有屏闪了
//	} else if(flag==2)
//		putpixel(m.x,m.y,RGB(255,155,4));批量绘制,不会闪烁了Sleep(1);
//
//	switch(m.message) {
//
//		case WM_LBUTTONDOWN:
//
//			if(m.x>x&&m.x<x+200&&m.y>y&&m.y<y+200&&m.ctrl) {
//				flag=1;启动批复制粘贴
//				getimage(&img2,x,y,200,200);putimage(200, 200, &img1);按动了就出现白块
//				px=x-m.x;
//				py=y-m.y;记录鼠标和图片左上角的差值
//			} else  {
//				flag=2;
//
//			}
//			break;
//		case WM_LBUTTONUP:
//			flag=0;
//			break;
//	}
//}
int main() {initgraph(640,640);setbkcolor(WHITE);cleardevice();setfillcolor(BLACK);setlinecolor(BLACK);//	这是初始图片左上角位置,以后都是新图片左上角的位置//	模的增量位移保存fillrectangle(100,100,300,300);
//	参考按钮
//	int qx=100;
//	int qy=100;
//	int flag=0;while(1) {ExMessage m;m=getmessage(EX_MOUSE|EX_KEY);static int qx=100;static int qy=100;static int flag=0;if(flag==0||flag==2)draw(m,&flag,&qx,&qy);if(flag==0||flag==1)check(m,&flag,&qx,&qy);
//		move(m);}closegraph();return 0;
}

 附带:用.h头文件封装后的完整代码,复制粘贴引用才能跑

.h完整代码如下:

封装结构体:

orilx,orily分别是初始位置左上角位置坐标

a,h分别是图片长度,高度

m1x,m1y分别是上一次粘贴图片的位置左上角坐标

drawflag就是之前的控制从不拖动转换为拖动的转换变量

img2是

struct pircle {IMAGE img2;IMAGE img3;int orilx,orily;int nowlx,nowly;int a,h;
//	原有图片的左上角坐标int m1x=0,m1y=0;int  putflag=0;int  drawflag=0;struct skline b;
} save;

 结构体参数下的拖动函数样子,函数顺序有所调整:


void movecheck(struct ExMessage m,struct pircle *save) {if(save->putflag==0&&m.message==WM_LBUTTONDOWN) {if(save->m1x==0&&save->m1y==0&&m.x>save->orilx&&m.x<save->orilx+save->a&&m.y>save->orily&&m.y<save->orily+save->h) {getimage(&save->img2,save->orilx,save->orily,save->a,save->h);getimage(&save->img3,save->orilx,save->orily,save->a,save->h);save->m1x=m.x;save->m1y=m.y;save->putflag=true;printf("2222\n");} else if(m.x>save->nowlx&&m.x<save->nowlx+save->a&&m.y>save->nowly&&m.y<save->nowly+save->h) {save->putflag=true;getimage(&save->img2,save->orilx,save->orily,save->a,save->h);save->m1x=m.x;save->m1y=m.y;
//			printf("11111\n");}} else if(save->putflag==true) {BeginBatchDraw();putimage(save->nowlx,save->nowly,&save->img3);save->nowlx=save->nowlx+m.x-save->m1x;save->nowly=save->nowly+m.y-save->m1y;save->m1x=m.x;save->m1y=m.y;getimage(&save->img3,save->nowlx,save->nowly,save->a,save->h);putimage(save->nowlx,save->nowly,&save->img2);EndBatchDraw();if(m.message==WM_LBUTTONUP) {save->putflag=0;}
//			一次绘图出来,没有屏闪了}putimage(save->nowlx,save->nowly,&save->img2);}

 

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

虚拟机安装

带你解密Linux的【Vm】-CSDN博客https://blog.csdn.net/lz17267861157/article/details/134031133

音画欣赏|《同杯万古尘》

《同杯万古尘》 尺寸&#xff1a;69x35cm 陈可之2023年绘 《拟古十二首-其九》 李白 生者为过客&#xff0c;死者为归人。 天地一逆旅&#xff0c;同悲万古尘。 月兔空捣药&#xff0c;扶桑已成薪。 白骨寂无言&#xff0c;青松岂知春。 前后更叹息&#xff0c;浮荣安足珍&am…

如何在Windows上搭建WebDAV服务并通过内网穿透实现公网访问

文章目录 前言1. 安装IIS必要WebDav组件2. 客户端测试3. 使用cpolar内网穿透&#xff0c;将WebDav服务暴露在公网3.1 安装cpolar内网穿透3.2 配置WebDav公网访问地址 4. 映射本地盘符访问 前言 在Windows上如何搭建WebDav&#xff0c;并且结合cpolar的内网穿透工具实现在公网访…

基于python的excel检查和读写软件

软件版本&#xff1a;python3.6 窗口和界面gui代码&#xff1a; class mygui:def _init_(self):passdef run(self):root Tkinter.Tk()root.title(ExcelRun)max_w, max_h root.maxsize()root.geometry(f500x500{int((max_w - 500) / 2)}{int((max_h - 300) / 2)}) # 居中显示…

Linux 一键部署二进制Gitea

gitea 前言 Gitea 是一个轻量级的 DevOps 平台软件。从开发计划到产品成型的整个软件生命周期,他都能够高效而轻松的帮助团队和开发者。包括 Git 托管、代码审查、团队协作、软件包注册和 CI/CD。它与 GitHub、Bitbucket 和 GitLab 等比较类似。 Gitea 最初是从 Gogs 分支而来…

Qt WebAssembly开发环境配置

目录 前言1、下载Emscripten SDK2、 安装3、环境变量配置4、QtCreator配置5、运行示例程序总结 前言 本文主要介绍 Qt WebAssembly 开发环境的配置。Qt for Webassembly 可以使Qt应用程序在Web上运行。WebAssembly&#xff08;简称Wasm&#xff09;是一种能够在虚拟机中执行的…

使用Java语言中的算法输出杨辉三角形

一、算法思想 创建一个名为YanghuiTest的类,然后创建二维数组&#xff0c;然后遍历二维数组的第一层&#xff0c;然后初始化第二层数组的大小&#xff0c;然后遍历第二层数组&#xff0c;然后将两侧的数组元素赋为1&#xff0c;然后其它数值通过公式计算&#xff0c;最后可以输…

【昆明*线上同步】最新ChatGPT/GPT4科研实践应用与AI绘图技术及论文高效写作

详情点击查看福利&#xff1a;【昆明*线上同步】最新ChatGPT/GPT4科研实践应用与AI绘图技术及论文高效写作 目标&#xff1a; 1、熟练掌握ChatGPT提示词技巧及各种应用方法&#xff0c;并成为工作中的助手。 2、通过案例掌握ChatGPT撰写、修改论文及工作报告&#xff0c;提供…

高级数据结构 <二叉搜索树>

本文已收录至《数据结构(C/C语言)》专栏&#xff01; 作者&#xff1a;ARMCSKGT 目录 前言正文二叉搜索树的概念二叉搜索树的基本功能实现二叉搜索树的基本框架插入节点删除节点查找函数中序遍历函数析构函数和销毁函数(后序遍历销毁)拷贝构造和赋值重载(前序遍历创建)其他函数…

Leetcode 435 无重叠区间

题意理解&#xff1a; 给定一个区间的集合 intervals 要求需要移除区间&#xff0c;使剩余区间互不重叠 目标&#xff1a;最少需要移除几个区间。 解题思路&#xff1a; 采用贪心思路解题&#xff0c;什么是全局最优解&#xff0c;什么是局部最优解。 全局最优解&#xff0c;删…

【华为鸿蒙系统学习】- 如何利用鸿蒙系统进行App项目开发|自学篇

&#x1f308;个人主页: Aileen_0v0 &#x1f525;热门专栏: 华为鸿蒙系统学习|计算机网络|数据结构与算法 &#x1f4ab;个人格言:"没有罗马,那就自己创造罗马~" 目录 创建鸿蒙第一个App项目 项目创建 工程目录区 预览区 运行Hello World 基本工程目录 ws:工…

[node]Node.js 模块系统

[node]模块系统 Node.js中的模块系统模块的使用模块的导入模块的导出导出多个值导出默认值导出可传参的函数 文件查找策略从文件模块缓存中加载从原生模块加载从文件加载 Node.js中的模块系统 为了让Node.js的文件可以相互调用&#xff0c;Node.js提供了一个简单的模块系统。 …

docker容器内 获取宿主机ip

可以使用命令 --add-host jargatewayip:192.168.0.47 \ 需要注意,这里不能是 127.0.0.1 ,所以要找到服务器局域网的ip 命令示例 docker run -it \-p 80:80 \-p 443:443 \--name nginx \--network app --hostname nginx \-e TZAsia/Shanghai \--add-host jargatewayip:192.16…

modbus异常错误码说明

异常错误码说明 其中物理离散量输入和输入寄存器只能有I/O系统提供的数据类型&#xff0c;即只能是由I/O系统改变离散量输入和输入寄存器的数值&#xff0c;而上位机程序不能改变的数据类型&#xff0c;在数据读写上表现为只读&#xff0c;而内部比特或者物理线圈和内部寄存器或…

图灵日记之java奇妙历险记--数据类型与变量运算符

目录 数据类型与变量字面常量数据类型变量语法格式整型变量浮点型变量字符型变量希尔型变量类型转换自动类型转换(隐式)强制类型转换(显式) 类型提升不同数据类型的运算小于4字节数据类型的运算 字符串类型 运算符算术运算符关系运算符逻辑运算符逻辑与&&逻辑或||逻辑非…

蚂蚁集团5大开源项目获开放原子 “2023快速成长开源项目”

12月16日&#xff0c;在开放原子开源基金会主办的“2023开放原子开发者大会”上&#xff0c;蚂蚁集团主导开源的图数据库TuGraph、时序数据库CeresDB、隐私计算框架隐语SecretFlow、前端框架OpenSumi、数据域大模型开源框架DB-GPT入选“2023快速成长开源项目”。 &#xff08;图…

MySQL数据库 视图

目录 视图概述 语法 检查选项 视图的更新 视图作用 案例 视图概述 视图(View)是一种虚拟存在的表。视图中的数据并不在数据库中实际存在&#xff0c;行和列数据来自定义视图的查询中使用的表&#xff0c;并且是在使用视图时动态生成的。 通俗的讲&#xff0c;视图只保存…

React学习计划-React16--React基础(四)生命周期和diffing算法,key的作用

1. 生命周期 1. 声命周期的三个阶段&#xff08;旧&#xff09; 初始化阶段&#xff1a;由ReactDOM.render()触发—初次渲染 1. constructor() 2. componentWillMount() 3. render() 4. componentDidMount() > 常用一般在这个钩子中做一些初始化的事情&#xff0c;例如&am…

SpringBoot Elasticsearch全文搜索

文章目录 概念全文搜索相关技术Elasticsearch概念近实时索引类型文档分片(Shard)和副本(Replica) 下载启用SpringBoot整合引入依赖创建文档类创建资源库测试文件初始化数据创建控制器 问题参考 概念 全文搜索&#xff08;检索&#xff09;&#xff0c;工作原理&#xff1a;计算…

数据结构和算法-二叉排序树(定义 查找 插入 删除 时间复杂度)

文章目录 二叉排序树总览二叉排序树的定义二叉排序树的查找二叉排序树的插入二叉排序树的构造二叉排序树的删除删除的是叶子节点删除的是只有左子树或者只有右子树的节点删除的是有左子树和右子树的节点 查找效率分析查找成功查找失败 小结 二叉排序树 总览 二叉排序树的定义 …