Python + uiautomator2 手机自动化控制教程

Python + uiautomator2 手机自动化控制教程

简介

uiautomator2 是比 ADB 更强大的 Android 自动化框架,支持元素定位、控件操作、应用管理等高级功能。本教程适合需要更精细控制的开发者。

一、环境准备

1.1 前置要求

  • Python 3.6 或更高版本
  • Android 手机(需开启开发者模式和 USB 调试)
  • USB 数据线
  • 已安装 ADB 工具(参考第一篇教程)

1.2 检查 Python 环境

python --version # 应显示 Python 3.6 或更高版本

1.3 检查 ADB 连接

adb devices # 应显示已连接的设备

二、安装 uiautomator2

2.1 安装 Python 库

pip install uiautomator2 

使用国内镜像加速:

pip install uiautomator2 -i https://pypi.tuna.tsinghua.edu.cn/simple 

2.2 初始化手机环境

重要步骤: 首次使用需要在手机上安装 ATX-Agent 和 uiautomator 服务。

# 方法一:使用命令行工具初始化 python -m uiautomator2 init # 方法二:使用 Python 脚本初始化 python >>>import uiautomator2 as u2 >>> u2.connect_usb()# 会自动安装必要组件>>> exit()

初始化过程:

  1. 会在手机上安装两个 APK:
    • ATXAgent.apk - 核心服务
    • app-uiautomator.apkapp-uiautomator-test.apk - UI 自动化服务
  2. 安装过程需要 1-3 分钟
  3. 手机上会弹出安装提示,点击"安装"

2.3 验证安装

创建测试文件 test_u2.py

import uiautomator2 as u2 # 连接设备 d = u2.connect()# 自动连接 USB 设备print("设备信息:", d.info)print("✅ uiautomator2 安装成功!")

运行测试:

python test_u2.py 

成功会显示设备信息(型号、分辨率、Android 版本等)。

三、uiautomator2 核心功能

3.1 设备连接方式

import uiautomator2 as u2 # 方式1:自动连接(推荐) d = u2.connect()# 方式2:通过 USB 连接 d = u2.connect_usb()# 方式3:通过设备序列号连接 d = u2.connect('device_serial')# 方式4:通过 WiFi 连接(需先配置) d = u2.connect('192.168.1.100')

3.2 基础操作

# 获取设备信息print(d.info)# 获取屏幕分辨率 width, height = d.window_size()print(f"分辨率: {width}x{height}")# 截图 d.screenshot("screen.png")# 点击坐标 d.click(500,1000)# 滑动 d.swipe(500,1500,500,500,0.3)# 从下往上滑# 长按 d.long_click(500,1000)# 输入文本 d.send_keys("Hello World")# 按键操作 d.press("home")# 返回主屏幕 d.press("back")# 返回键

3.3 应用管理

# 启动应用 d.app_start("com.ss.android.ugc.aweme")# 停止应用 d.app_stop("com.ss.android.ugc.aweme")# 清除应用数据 d.app_clear("com.ss.android.ugc.aweme")# 检查应用是否运行if d.app_current().get('package')=="com.ss.android.ugc.aweme":print("抖音正在运行")# 获取当前应用信息 current = d.app_current()print(f"当前应用: {current['package']}")

四、编写自动化脚本

4.1 基础滑动脚本

创建 u2_basic_swipe.py

""" uiautomator2 基础滑动脚本 功能:自动滑动视频 """import uiautomator2 as u2 import time defmain():# 连接设备 d = u2.connect()print(f"✅ 已连接设备: {d.info['productName']}")# 获取屏幕尺寸 width, height = d.window_size()print(f"📱 屏幕分辨率: {width}x{height}")# 配置参数 interval =5# 滑动间隔(秒) count =0print(f"⏰ 每 {interval} 秒滑动一次")print("按 Ctrl+C 停止\n")try:whileTrue: count +=1# 从屏幕下方滑到上方# 使用相对坐标,自适应不同分辨率 d.swipe( width //2,# x: 屏幕中央 height *0.8,# y1: 屏幕 80% 位置 width //2,# x: 保持在中央 height *0.2,# y2: 屏幕 20% 位置0.3# 滑动持续时间(秒))print(f"[{count}] {time.strftime('%H:%M:%S')} ✅ 滑动成功") time.sleep(interval)except KeyboardInterrupt:print(f"\n⏹️ 已停止,共执行 {count} 次滑动")except Exception as e:print(f"\n❌ 发生错误: {e}")if __name__ =="__main__": main()

运行:

python u2_basic_swipe.py 

4.2 高级功能脚本

创建 u2_advanced_swipe.py

""" uiautomator2 高级自动化脚本 功能: 1. 启动指定应用 2. 智能检测页面状态 3. 支持多种滑动模式 4. 异常处理和自动恢复 """import uiautomator2 as u2 import time import random from datetime import datetime classVideoAutomation:def__init__(self, package_name, interval=5, total_count=None):""" 初始化视频自动化控制器 参数: package_name: 应用包名 interval: 滑动间隔(秒) total_count: 总滑动次数(None=无限次) """ self.package_name = package_name self.interval = interval self.total_count = total_count self.device =None self.count =0 self.width =0 self.height =0defconnect(self):"""连接设备"""try: self.device = u2.connect() self.width, self.height = self.device.window_size()print(f"✅ 已连接设备: {self.device.info.get('productName','Unknown')}")print(f"📱 分辨率: {self.width}x{self.height}")print(f"🤖 Android 版本: {self.device.info.get('version','Unknown')}")returnTrueexcept Exception as e:print(f"❌ 连接设备失败: {e}")returnFalsedefstart_app(self):"""启动应用"""try:print(f"🚀 正在启动应用: {self.package_name}") self.device.app_start(self.package_name) time.sleep(3)# 等待应用启动# 验证应用是否启动成功 current = self.device.app_current()if current.get('package')== self.package_name:print(f"✅ 应用启动成功")returnTrueelse:print(f"⚠️ 启动的应用不匹配,当前: {current.get('package')}")returnFalseexcept Exception as e:print(f"❌ 启动应用失败: {e}")returnFalsedefcheck_app_running(self):"""检查应用是否在前台运行"""try: current = self.device.app_current()return current.get('package')== self.package_name except:returnFalsedefswipe_up(self):"""向上滑动(下一个视频)"""try:# 使用屏幕中央位置滑动 x = self.width //2 y1 =int(self.height *0.75)# 起始位置:75% y2 =int(self.height *0.25)# 结束位置:25% self.device.swipe(x, y1, x, y2,0.3) self.count +=1returnTrueexcept Exception as e:print(f"❌ 滑动失败: {e}")returnFalsedefswipe_down(self):"""向下滑动(上一个视频)"""try: x = self.width //2 y1 =int(self.height *0.25) y2 =int(self.height *0.75) self.device.swipe(x, y1, x, y2,0.3)returnTrueexcept Exception as e:print(f"❌ 滑动失败: {e}")returnFalsedefrandom_swipe(self):"""随机滑动(模拟人类行为)"""# 90% 概率向上,10% 概率向下if random.random()<0.9:return self.swipe_up()else:print(" ↓ 随机向下滑动")return self.swipe_down()defshould_continue(self):"""判断是否继续执行"""if self.total_count isNone:returnTruereturn self.count < self.total_count defget_random_interval(self):"""获取随机间隔时间(模拟人类)"""# 在设定间隔基础上 ±20% 浮动 variation = self.interval *0.2return self.interval + random.uniform(-variation, variation)defrun(self):"""运行自动化任务"""ifnot self.connect():returnifnot self.start_app():returnprint(f"\n⏰ 平均滑动间隔: {self.interval} 秒(随机波动)")if self.total_count:print(f"🎯 目标次数: {self.total_count} 次")else:print(f"🔄 持续运行(按 Ctrl+C 停止)")print("-"*50) start_time = time.time()try:while self.should_continue():# 检查应用是否还在前台ifnot self.check_app_running():print("⚠️ 应用不在前台,尝试重新启动...")ifnot self.start_app():break# 执行滑动 current_time = datetime.now().strftime('%H:%M:%S')print(f"[{self.count +1}] {current_time} ", end="")if self.random_swipe():print("✅")else:print("❌ 失败,继续...")# 等待随机间隔if self.should_continue(): wait_time = self.get_random_interval() time.sleep(wait_time)except KeyboardInterrupt:print("\n\n⏹️ 用户停止")except Exception as e:print(f"\n❌ 发生错误: {e}")finally: elapsed = time.time()- start_time self.print_statistics(elapsed)defprint_statistics(self, elapsed_time):"""打印统计信息"""print(f"\n{'='*50}")print(f"📊 运行统计:")print(f" - 总滑动次数: {self.count}")print(f" - 运行时长: {int(elapsed_time)} 秒 ({int(elapsed_time/60)} 分钟)")if self.count >0:print(f" - 平均间隔: {elapsed_time/self.count:.1f} 秒")print(f"{'='*50}")defmain():import argparse # 解析命令行参数 parser = argparse.ArgumentParser(description='uiautomator2 视频自动化脚本') parser.add_argument('package',help='应用包名,如: com.ss.android.ugc.aweme') parser.add_argument('-i','--interval',type=float, default=5.0,help='滑动间隔(秒),默认5秒') parser.add_argument('-n','--count',type=int, default=None,help='滑动次数,不指定则无限循环') args = parser.parse_args()# 创建并运行自动化任务 automation = VideoAutomation( package_name=args.package, interval=args.interval, total_count=args.count ) automation.run()if __name__ =="__main__": main()

4.3 智能元素定位脚本

创建 u2_smart_control.py

""" 基于 UI 元素的智能控制脚本 功能:通过识别页面元素来智能操作 """import uiautomator2 as u2 import time classSmartController:def__init__(self, package_name): self.package_name = package_name self.device = u2.connect()defstart(self):"""启动应用""" self.device.app_start(self.package_name) time.sleep(2)defwait_and_click(self, text=None, description=None, timeout=10):"""等待元素出现并点击"""try:if text:# 通过文本查找并点击 self.device(text=text).click(timeout=timeout)print(f"✅ 点击了: {text}")returnTrueelif description:# 通过描述查找并点击 self.device(description=description).click(timeout=timeout)print(f"✅ 点击了: {description}")returnTrueexcept u2.exceptions.UiObjectNotFoundError:print(f"⚠️ 未找到元素")returnFalsedefswipe_if_video_exists(self):"""如果检测到视频元素就滑动"""# 示例:检测特定 ID 的视频容器if self.device(resourceId="video_container").exists: width, height = self.device.window_size() self.device.swipe(width//2, height*0.8, width//2, height*0.2,0.3)print("✅ 检测到视频,已滑动")returnTruereturnFalsedefauto_handle_popups(self):"""自动处理弹窗"""# 常见弹窗按钮文本 close_texts =["关闭","取消","不感兴趣","跳过","我知道了"]for text in close_texts:if self.device(text=text).exists: self.device(text=text).click()print(f"✅ 关闭弹窗: {text}") time.sleep(0.5)returnTruereturnFalse# 使用示例if __name__ =="__main__": controller = SmartController("com.ss.android.ugc.aweme") controller.start()# 自动处理启动页弹窗 time.sleep(2) controller.auto_handle_popups()# 持续滑动for i inrange(10): controller.swipe_if_video_exists() time.sleep(5)

五、运行指南

5.1 基础脚本运行

# 运行基础滑动脚本 python u2_basic_swipe.py 

5.2 高级脚本运行

抖音自动刷视频(每5秒一次):

python u2_advanced_swipe.py com.ss.android.ugc.aweme 

快手自动刷视频(每8秒一次,共50次):

python u2_advanced_swipe.py com.smile.gifmaker -i 8 -n 50

B站自动刷视频(每3秒一次):

python u2_advanced_swipe.py tv.danmaku.bili -i 3

5.3 查看帮助

python u2_advanced_swipe.py -h 

六、WiFi 无线连接配置

6.1 配置步骤

1. 确保手机和电脑在同一 WiFi 网络

2. 通过 USB 启用 WiFi 调试:

# 查看手机 IP 地址 adb shell ip addr show wlan0 # 启用 WiFi ADB(端口 5555) adb tcpip 5555# 记下手机 IP 地址(如 192.168.1.100)

3. 连接 WiFi:

# 断开 USB 线 adb connect 192.168.1.100:5555 

4. 在脚本中使用 WiFi 连接:

import uiautomator2 as u2 # 使用 IP 地址连接 d = u2.connect('192.168.1.100')

6.2 WiFi 连接优势

  • 无需 USB 线,更自由
  • 可以同时控制多台手机
  • 适合长时间运

七、UI 元素定位技巧

7.1 查看页面元素

安装 weditor(UI 查看器):

pip install weditor 

启动 weditor:

python -m weditor 

浏览器会自动打开 http://localhost:17310

使用方法:

  1. 输入设备 IP 或序列号,点击 Connect
  2. 点击 Dump Hierarchy 获取当前页面结构
  3. 点击元素查看属性(text、resourceId、className 等)
  4. 可以实时测试定位表达式

7.2 常用定位方法

import uiautomator2 as u2 d = u2.connect()# 通过文本定位 d(text="立即登录").click()# 通过文本包含 d(textContains="登录").click()# 通过 resourceId 定位 d(resourceId="com.app:id/button").click()# 通过 className 定位 d(className="android.widget.Button").click()# 通过 description 定位 d(description="确认按钮").click()# 组合定位 d(className="android.widget.Button", text="确认").click()# 索引定位(多个相同元素时) d(className="android.widget.Button")[0].click()# 第一个按钮 d(className="android.widget.Button")[1].click()# 第二个按钮

7.3 等待元素出现

# 等待元素出现(最多等待10秒) d(text="加载完成").wait(timeout=10)# 等待元素消失 d(text="加载中...").wait_gone(timeout=10)# 判断元素是否存在if d(text="登录").exists:print("找到登录按钮")# 获取元素信息 info = d(text="登录").info print(info)

八、高级功能示例

8.1 自动点赞脚本

""" 视频自动点赞脚本 """import uiautomator2 as u2 import time d = u2.connect() d.app_start("com.ss.android.ugc.aweme") time.sleep(3)for i inrange(10):# 双击屏幕点赞(适用于抖音) width, height = d.window_size() d.double_click(width//2, height//2)print(f"❤️ 点赞第 {i+1} 次") time.sleep(1)# 滑动到下一个视频 d.swipe(width//2, height*0.8, width//2, height*0.2,0.3) time.sleep(5)

8.2 自动关注脚本

""" 自动关注作者脚本 """import uiautomator2 as u2 import time d = u2.connect() d.app_start("com.ss.android.ugc.aweme") time.sleep(3)for i inrange(5):# 查找并点击关注按钮if d(text="关注").exists: d(text="关注").click()print(f"✅ 关注第 {i+1} 个作者")elif d(textContains="关注").exists: d(textContains="关注").click()print(f"✅ 关注第 {i+1} 个作者")else:print("⚠️ 未找到关注按钮") time.sleep(2)# 滑到下一个视频 width, height = d.window_size() d.swipe(width//2, height*0.8, width//2, height*0.2,0.3) time.sleep(5)

8.3 截图并保存

""" 定时截图脚本 """import uiautomator2 as u2 import time from datetime import datetime d = u2.connect() d.app_start("com.ss.android.ugc.aweme")for i inrange(10):# 生成带时间戳的文件名 timestamp = datetime.now().strftime("%Y%m%d_%H%M%S") filename =f"screenshot_{timestamp}.png"# 截图 d.screenshot(filename)print(f"📸 已保存截图: {filename}")# 滑动 width, height = d.window_size() d.swipe(width//2, height*0.8, width//2, height*0.2,0.3) time.sleep(5)

8.4 监控屏幕变化

""" 监控屏幕变化脚本 """import uiautomator2 as u2 import time d = u2.connect()# 获取初始截图 last_screen = d.screenshot()whileTrue: time.sleep(1) current_screen = d.screenshot()# 简单对比(可用图像相似度算法优化)if current_screen != last_screen:print("🔄 屏幕内容已变化") last_screen = current_screen 

九、故障排查

9.1 “ConnectionError: Unable to connect to device”

解决方案:

# 1. 检查 ADB 连接 adb devices # 2. 重新初始化 uiautomator2 python -m uiautomator2 init # 3. 检查 ATX-Agent 是否运行 adb shell ps|grep atx # 4. 重启 ATX-Agent adb shell am force-stop com.github.uiautomator python -m uiautomator2 init 

9.2 元素定位失败

解决方案:

  1. 使用 weditor 查看实际元素属性
  2. 检查元素是否在屏幕可见区域
  3. 增加等待时间
  4. 使用更精确的定位方式
# 添加等待 d(text="按钮").wait(timeout=10)# 尝试不同定位方式ifnot d(text="登录").exists: d(textContains="登录").click()

9.3 “UiObjectNotFoundError”

解决方案:

# 使用异常处理try: d(text="按钮").click()except u2.exceptions.UiObjectNotFoundError:print("元素不存在,跳过")# 或先判断if d(text="按钮").exists: d(text="按钮").click()

9.4 操作响应慢

解决方案:

# 设置操作超时时间 d.settings['operation_delay']=(0,0)# 点击前后延迟 d.settings['operation_delay_methods']=['click','swipe']# 设置 implicitly_wait d.implicitly_wait(10)# 隐式等待10秒

9.5 WiFi 连接断开

解决方案:

# 重新连接 adb connect <手机IP>:5555 # 保持连接 adb connect <手机IP>:5555 adb -s <手机IP>:5555 shell settings put global stay_on_while_plugged_in 7

十、性能优化

10.1 加快操作速度

# 关闭等待时间 d.settings['wait_timeout']=10# 全局等待超时 d.settings['operation_delay']=(0,0)# 操作延迟# 使用 shell 命令代替高级 API d.shell("input swipe 500 1500 500 500 100")# 更快

10.2 减少资源占用

# 不需要截图时关闭# 使用 shell 命令代替截图检查# 批量操作for i inrange(100): d.swipe(500,1500,500,500,0.1)# 减少滑动时间

10.3 异步操作

import asyncio import uiautomator2 as u2 asyncdefswipe_task(device, count):for i inrange(count): width, height = device.window_size() device.swipe(width//2, height*0.8, width//2, height*0.2,0.3)await asyncio.sleep(3)asyncdefmain(): d = u2.connect()await swipe_task(d,10) asyncio.run(main())

十一、完整项目结构

phone-automation-u2/ ├── test_u2.py # 测试连接 ├── u2_basic_swipe.py # 基础滑动 ├── u2_advanced_swipe.py # 高级滑动 ├── u2_smart_control.py # 智能控制 ├── screenshots/ # 截图目录 │ └── screenshot_*.png └── logs/ # 日志目录 └── automation.log 

十二、uiautomator2 vs ADB 对比

功能uiautomator2ADB
元素定位✅ 支持❌ 不支持
应用管理✅ 便捷⚠️ 需命令
WiFi 连接✅ 简单⚠️ 需配置
学习曲线⚠️ 中等✅ 简单
性能⚠️ 中等✅ 快速
功能丰富度✅ 丰富⚠️ 基础
配置复杂度⚠️ 需初始化✅ 简单

十三、实战案例

13.1 完整的抖音自动刷视频脚本

""" 抖音自动刷视频完整脚本 功能: - 自动启动抖音 - 智能跳过广告 - 随机间隔滑动 - 异常自动恢复 """import uiautomator2 as u2 import time import random from datetime import datetime classDouyinAutomation:def__init__(self): self.device = u2.connect() self.package ="com.ss.android.ugc.aweme" self.count =0defstart(self):"""启动抖音"""print("🚀 启动抖音...") self.device.app_start(self.package) time.sleep(3) self.handle_popups()defhandle_popups(self):"""处理启动弹窗""" close_buttons =["关闭","跳过","我知道了","取消"]for btn in close_buttons:if self.device(text=btn).exists: self.device(text=btn).click()print(f"✅ 关闭弹窗: {btn}") time.sleep(0.5)defswipe_next(self):"""滑到下一个视频""" width, height = self.device.window_size()# 添加轻微随机偏移 x = width //2+ random.randint(-50,50) y1 =int(height *0.75)+ random.randint(-20,20) y2 =int(height *0.25)+ random.randint(-20,20) duration = random.uniform(0.25,0.35) self.device.swipe(x, y1, x, y2, duration) self.count +=1defcheck_status(self):"""检查应用状态""" current = self.device.app_current()if current.get('package')!= self.package:print("⚠️ 应用不在前台,重新启动") self.start()returnFalsereturnTruedefrun(self, duration_minutes=30):"""运行指定时长""" self.start() end_time = time.time()+ duration_minutes *60print(f"🎬 开始刷视频,持续 {duration_minutes} 分钟")print("-"*50)try:while time.time()< end_time:ifnot self.check_status():continue# 滑动 timestamp = datetime.now().strftime('%H:%M:%S')print(f"[{self.count +1}] {timestamp} ✅") self.swipe_next()# 随机间隔 4-8 秒 interval = random.uniform(4,8) time.sleep(interval)except KeyboardInterrupt:print("\n⏹️ 用户停止")finally:print(f"\n📊 总共观看 {self.count} 个视频")if __name__ =="__main__": automation = DouyinAutomation() automation.run(duration_minutes=10)# 运行10分钟

十四、总结

恭喜完成 uiautomator2 教程!你现在已经掌握:

✅ uiautomator2 环境搭建和初始化
✅ 设备连接(USB 和 WiFi)
✅ 基础操作(点击、滑动、输入等)
✅ UI 元素定位技巧
✅ 应用管理和控制
✅ 高级功能实现
✅ 异常处理和优化

uiautomator2 优势:

  • 功能强大,支持复杂交互
  • 可以精确定位 UI 元素
  • 支持无线连接
  • Python API 友好

适用场景:

  • 需要元素定位的自动化
  • 复杂交互逻辑
  • 应用测试
  • UI 自动化操作

下一步建议:

  • 学习图像识别(OpenCV)
  • 研究 OCR 文字识别
  • 探索 AI 辅助自动化
  • 学习 Appium 实现跨平台自动化

参考资源:

  • uiautomator2 文档:https://github.com/openatx/uiautomator2
  • weditor 工具:https://github.com/alibaba/web-editor
  • Android UI 文档:https://developer.android.com/reference/android/support/test/uiautomator/package-summary

Read more

C++ ODB ORM 完全指南:从入门到实战应用

C++ ODB ORM 完全指南:从入门到实战应用

文章目录 * ODB基本概念 * ODB框架安装 * 常见操作 * ODB类与接口 * 测试示例 ODB基本概念 ODB 是一个针对 C++ 的对象关系映射(ORM)库,它允许开发者以面向对象的方式操作数据库,将C++ 对象与数据库表进行映射,从而避免直接编写 SQL 语句,简化数据库操作。 特点: * 对象 - 关系映射:将 C++ 类映射到数据库表,类的成员变量映射到表的字段,对象的创建、修改、删除等操作会自动转换为对应的数据库操作(如 INSERT、UPDATE、DELETE)。 * 代码生成机制:ODB 不依赖运行时反射(C++ 本身不支持),而是通过编译期代码生成实现映射:开发者使用特殊的注解(如 #pragma db object)标记需要持久化的类,然后通过 ODB 编译器生成与数据库交互的代码(

By Ne0inhk
C++ 入门必看:引用怎么用?inline 和 nullptr 是什么?

C++ 入门必看:引用怎么用?inline 和 nullptr 是什么?

目录 * 一、引用 * 1.1 引用的概念和定义 * 1.2 引用的特性 * 1.3 引用的使用 * 1.3.1 引用传参的使用 * 1.3.2 传引用返回的错误使用 * 1.3.3 传引用返回的正确使用 * 1.4 const引用 * 1.5 指针和引用的关系 * 二、inline * 三、nullptr * 总结 🎬 云泽Q:个人主页 🔥 专栏传送入口: 《C语言》《数据结构》《C++》《Linux》 ⛺️遇见安然遇见你,不负代码不负卿~ 在这篇文章开始之前,我想给大家推荐一个非常牛的人工智能学习网站。在近几年,大家也知道人工智能和 AI 技术的发展也是非常迅速,

By Ne0inhk
C++:模板的幻觉 —— 实例化、重定义与隐藏依赖势中

C++:模板的幻觉 —— 实例化、重定义与隐藏依赖势中

一、表象之下:模板真的“生成代码”吗? 很多人第一次学 C++ 模板时,会这样理解: “模板是一种代码生成机制,编译器在编译时会根据不同类型生成不同版本的函数或类。” 乍一看没错,比如: template<typename T> void print(T x) { std::cout << x << std::endl; } int main() { print(42); print("Hello"); } 似乎编译器确实“生成了两份函数”: print<int>(int) 与 print<const

By Ne0inhk
初学二叉搜索树踩坑多?C++ 从原理到代码,搞定增删查全流程

初学二叉搜索树踩坑多?C++ 从原理到代码,搞定增删查全流程

🎬 个人主页:Vect个人主页 🎬 GitHub:Vect的代码仓库 🔥 个人专栏: 《数据结构与算法》《C++学习之旅》《计算机基础》 ⛺️Per aspera ad astra. 文章目录 * 1. 二叉搜索树相关概念 * 2. 二叉搜索树的操作 * 2.1. 查找节点 * 2.2. 插入节点 * 2.3. 删除节点 * 3. 二叉搜索树的实现 * 4. 二叉搜索树的应用 * 4.1. K模型 * 4.2. KV模型 1. 二叉搜索树相关概念 如下图所示,二叉搜索树(binary search tree)满足下列条件: 1. 对于根节点,左子树中所有节点的值<根节点的值&

By Ne0inhk