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

WPF 实现冒泡排序可视化

WPF 实现冒泡排序可视化


实现冒泡排序代码就不过多讲解,主要是实现动画效果思路,本demo使用MVVM模式编写,读者可自行参考部分核心代码,即可实现如视频所示效果。
对于新手了解算法相关知识应该有些许帮助,至于其它类型排序,也可按该思路自行修改实现。
直接上代码,页面布局.xaml代码如下:

<UserControl x:Class="Wpf_MetroListBox.Views.Test.CanvasLabelMove"xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:local="clr-namespace:Wpf_MetroListBox.Views.Test"mc:Ignorable="d" d:DesignHeight="450" d:DesignWidth="800"><Grid><Grid.RowDefinitions><RowDefinition Height="380"></RowDefinition><RowDefinition Height="*"></RowDefinition></Grid.RowDefinitions><Canvas x:Name="canvas" Grid.Row="0" Background="White"></Canvas><Grid Grid.Row="1"><Grid.ColumnDefinitions><ColumnDefinition></ColumnDefinition><ColumnDefinition></ColumnDefinition></Grid.ColumnDefinitions><Button Content="创建序列" HorizontalAlignment="Center"  Grid.Column="0" Width="70" Height="35" Command="{Binding CommitCommand}" Style="{DynamicResource btn-info-m}"></Button><Button  Content="执行排序" HorizontalAlignment="Center"  Grid.Column="1" Width="70" Height="35" Command="{Binding QueryCommand}" Style="{DynamicResource btn-info-m}"></Button></Grid></Grid></UserControl>

逻辑代码实现如下:

public partial class CanvasLabelMove : UserControl{CanvasLabelMoveViewModel vm;private Random random = new Random();private List<Label> labels = new List<Label>();private int[] array;private int delay = 1000; // 动画延迟时间(毫秒)public CanvasLabelMove(){InitializeComponent();vm = new CanvasLabelMoveViewModel();this.DataContext = vm;this.Publish(EventNames.MainWindowLoadControlEvent, "排序可视化");this.Subscriber<string>(EventNames.DataGridFocusChangedEvent, async contentStr =>{  if (contentStr.Equals("1")){InitializeArrayAndLabels();}else if (contentStr.Equals("2")){StartBubbleSortAnimation();}});}private void InitializeArrayAndLabels(){int size = 18; // 数组大小 控制标签个数array = new int[size];labels.Clear();canvas.Children.Clear();HashSet<int> randomNumbers = new HashSet<int>();Random random = new Random();//生成不重复随机数while (randomNumbers.Count < size){int nextNumber = random.Next(22, 200);randomNumbers.Add(nextNumber);}int j = 0;foreach (int number in randomNumbers){array[j] = number;j++;}for (int i = 0; i < size; i++){Label label = new Label{Content = array[i].ToString(),FontSize = 12,Width = 35,Height = array[i],Margin = new Thickness(50, 0, 0, 0),Foreground = Brushes.Black,Background = Brushes.BlanchedAlmond,VerticalContentAlignment = VerticalAlignment.Center,HorizontalContentAlignment = HorizontalAlignment.Center};             Canvas.SetLeft(label, i * 50); // 设置Label的X坐标Canvas.SetBottom(label, (canvas.ActualHeight / 2) - 100); // 设置Label的Y坐标在中间canvas.Children.Add(label);labels.Add(label);}}private async void StartBubbleSortAnimation(){for (int j = 0; j <= array.Length - 1; j++){for (int i = 0; i <= array.Length - 2; i++){if (array[i] > array[i + 1]){Swap(i, i + 1);// 更新Label位置AnimateSwap(i, i + 1);await Task.Delay(delay);}}}}private void Swap(int i, int j){int temp = array[i];array[i] = array[j];array[j] = temp;}private async void AnimateSwap(int i, int j){// 临时存储Label的位置double label1X = Canvas.GetLeft(labels[i]);double label2X = Canvas.GetLeft(labels[j]);await Task.Delay(delay / 10); // 控制动画速度var animation1 = new DoubleAnimation(label2X, TimeSpan.FromSeconds(0.5));var animation2 = new DoubleAnimation(label1X, TimeSpan.FromSeconds(0.5));labels[i].BeginAnimation(Canvas.LeftProperty, animation1);labels[j].BeginAnimation(Canvas.LeftProperty, animation2);// 最终位置//Canvas.SetLeft(labels[i], label2X);//Canvas.SetLeft(labels[j], label1X);Label tempLabel = labels[i];labels[i] = labels[j];labels[j] = tempLabel;}}public class CanvasLabelMoveViewModel : BaseValidViewModel{public CanvasLabelMoveViewModel(){}protected override void ExecuteCommitCommand(){this.Publish(EventNames.DataGridFocusChangedEvent, "1");}protected override void ExecuteQueryCommand(){this.Publish(EventNames.DataGridFocusChangedEvent, "2");}}

相关文章:

WPF 实现冒泡排序可视化

WPF 实现冒泡排序可视化 实现冒泡排序代码就不过多讲解&#xff0c;主要是实现动画效果思路&#xff0c;本demo使用MVVM模式编写&#xff0c;读者可自行参考部分核心代码&#xff0c;即可实现如视频所示效果。 对于新手了解算法相关知识应该有些许帮助&#xff0c;至于其它类型…...

Claude 3.5 新功能 支持对 100 页的PDF 图像、图表和图形进行可视化分析

Claude 3.5 Sonnet发布PDF图像预览新功能&#xff0c;允许用户分析长度不超过100页的PDF中的视觉内容。 此功能使用户能够轻松上传文档并提取信息&#xff0c;特别适用于包含图表、图形和其他视觉元素的研究论文和技术文档。 视觉PDF分析&#xff1a;用户现在可以从包含各种视觉…...

正式开源:从 Greenplum 到 Cloudberry 迁移工具 cbcopy 发布

Cloudberry Database 作为 Greenplum 衍生版本和首选开源替代&#xff0c;由 Greenplum 原始团队成员创建&#xff0c;与 Greenplum 保持原生兼容&#xff0c;并能实现无缝迁移&#xff0c;且具备更新的 PostgreSQL 内核和更丰富的功能。GitHub: https://github.com/cloudberry…...

Python如何读写文件?

1. 文件读取 &#xff08;1&#xff09;使用open()函数打开文件 基本语法是file_object open(file_name, mode)&#xff0c;其中file_name是要打开的文件的名称&#xff08;包括路径&#xff0c;如果文件不在当前目录下&#xff09;&#xff0c;mode是打开文件的模式。例如&a…...

100种算法【Python版】第38篇——Boyer-Moore算法

本文目录 1 算法说明2 算法示例3 python代码1 算法说明 Boyer-Moore算法由Robert S. Boyer和J. Strother Moore于1977年提出,旨在提高字符串匹配的效率。该算法在寻找固定模式的过程中,利用模式本身的信息,优化搜索过程,特别适合长文本中的模式查找。 算法原理 Boyer-Moo…...

贪心算法---java---黑马

贪心算法 1)Greedy algorithm 称之为贪心算法或者贪婪算法&#xff0c;核心思想是 将寻找最优解的问题分为若干个步骤每一步骤都采用贪心原则&#xff0c;选取当前最优解因为未考虑所有可能&#xff0c;局部最优的堆叠不一定得到最终解最优 贪心算法例子 Dijkstra while …...

程序员的减压秘籍:高效与健康的平衡艺术

引言 在当今竞争激烈的科技行业中&#xff0c;程序员常常面临着极高的精神集中要求和持续的创新压力。这种工作性质让许多程序员在追求高效和创新的过程中&#xff0c;感到精疲力竭&#xff0c;面临身心健康的挑战。因此&#xff0c;找到有效的方法来缓解工作压力&#xff0c;…...

2024 年 QEMU 峰会纪要

2024 年 QEMU 峰会已于 10 月 31 日在 KVM 论坛召开&#xff0c;这是一个仅对项目中最活跃的维护者和子维护者开放的邀请会议。 出席者&#xff1a; Dan Berrang Cdric Le Goater Kevin Wolf Michael S. Tsirkin Stefan Hajnoczi Philippe Mathieu-Daud Markus Armbruster Th…...

C++/list

目录 1.list的介绍 2.list的使用 2.1list的构造 2.2list iterator的使用 2.3list capacity 2.4list element access 2.5list modifers 2.6list的迭代器失效 3.list的模拟实现 4.list与vector的对比 欢迎 1.list的介绍 list的文档介绍 cplusplus.com/reference/list/li…...

刘艳兵-DBA015-对于属于默认undo撤销表空间的数据文件的丢失,哪条语句是正确的?

对于属于默认undo撤销表空间的数据文件的丢失&#xff0c;哪条语句是正确的&#xff1f; A 所有未提交的交易都将丢失。 B 数据库实例中止。 C 数据库处于MOUNT状态&#xff0c;需要恢复才能打开。 D 数据库保持打开状态以供查询&#xff0c;但除具有SYSDBA特权的用…...

树莓派基本设置--10.使用MIPI摄像头

树莓派5将以前的CSI和DSI接口合并成两个两用的CSI/DSI&#xff08;MIPI&#xff09;端口。 一、配置摄像头 使用树莓派摄像头或第三方相机可以按照下面表格修改相机配置&#xff1a; 摄像头模块文件位于&#xff1a;/boot/firmware/config.txtV1 相机 &#xff08;OV5647&am…...

【ARCGIS实验】地形特征线的提取

目录 一、提取不同位置的地形剖面线 二、将DEM转化为TIN 三、进行可视分析 四、进行山脊、山谷等特征线的提取 1、正负地形提取&#xff08;用于校正&#xff09; 2、山脊线提取 3、山谷线的提取 4、河网的提取 5、流域的分割 五、鞍部点的提取 1、背景 2、目的 3…...

HTML 基础标签——表格标签<table>

文章目录 1. `<table>` 标签:定义表格2. `<tr>` 标签:定义表格行3. `<th>` 标签:定义表头单元格4. `<td>` 标签:定义表格单元格5. `<caption>` 标签:为表格添加标题6. `<thead>` 标签:定义表格头部7. `<tbody>` 标签:定义表格…...

线程函数和线程启动的几种不同形式

线程函数和线程启动的几种不同形式 在C中&#xff0c;线程函数和线程启动可以通过多种形式实现。以下是几种常见的形式&#xff0c;并附有相应的示例代码。 1. 使用函数指针启动线程 最基本的方式是使用函数指针来启动线程。 示例代码&#xff1a; #include <iostream&g…...

数组排序简介-基数排序(Radix Sort)

基本思想 将整数按位数切割成不同的数字&#xff0c;然后从低位开始&#xff0c;依次到高位&#xff0c;逐位进行排序&#xff0c;从而达到排序的目的。 算法步骤 基数排序算法可以采用「最低位优先法&#xff08;Least Significant Digit First&#xff09;」或者「最高位优先…...

进程间通信(命名管道 共享内存)

文章目录 命名管道原理命令创建命名管道函数创建命名管道 共享内存原理shmgetFIOK 代码应用&#xff1a;premsnattch 命名管道 用于两个毫无关系的进程间的通信。 原理 Linux文件的路径是多叉树&#xff0c;故文件的路径是唯一的。 让内核缓冲区不用刷新到磁盘中&#xff0c…...

Python 网络爬虫教程:从入门到高级的全面指南

Python 网络爬虫教程&#xff1a;从入门到高级的全面指南 引言 在信息爆炸的时代&#xff0c;网络爬虫&#xff08;Web Scraping&#xff09;成为了获取数据的重要工具。Python 以其简单易用的特性&#xff0c;成为了网络爬虫开发的首选语言。本文将详细介绍如何使用 Python …...

深度学习:正则化(Regularization)详细解释

正则化&#xff08;Regularization&#xff09;详细解释 正则化&#xff08;Regularization&#xff09;是机器学习和统计建模领域中用以防止模型过拟合同时增强模型泛化能力的一种技术。通过引入额外的约束或惩罚项到模型的损失函数中&#xff0c;正则化能够有效地限制模型的…...

Freertos学习日志(1)-基础知识

目录 1.什么是Freertos&#xff1f; 2.为什么要学习RTOS&#xff1f; 3.Freertos多任务处理的原理 1.什么是Freertos&#xff1f; RTOS&#xff0c;即&#xff08;Real Time Operating System 实时操作系统&#xff09;&#xff0c;是一种体积小巧、确定性强的计算机操作系统…...

CentOS9 Stream 支持输入中文

CentOS9 Stream 支持输入中文 方法一&#xff1a;确保 gnome-control-center 和相关组件已更新方法二&#xff1a;手动添加输入法源配置方法三&#xff1a;配置 .xinputrc 文件方法四&#xff1a;检查语言包 进入centos9 stream后&#xff0c;点击右上角电源键&#xff0c;点击…...

[2025CVPR]DeepVideo-R1:基于难度感知回归GRPO的视频强化微调框架详解

突破视频大语言模型推理瓶颈,在多个视频基准上实现SOTA性能 一、核心问题与创新亮点 1.1 GRPO在视频任务中的两大挑战 ​安全措施依赖问题​ GRPO使用min和clip函数限制策略更新幅度,导致: 梯度抑制:当新旧策略差异过大时梯度消失收敛困难:策略无法充分优化# 传统GRPO的梯…...

Auto-Coder使用GPT-4o完成:在用TabPFN这个模型构建一个预测未来3天涨跌的分类任务

通过akshare库&#xff0c;获取股票数据&#xff0c;并生成TabPFN这个模型 可以识别、处理的格式&#xff0c;写一个完整的预处理示例&#xff0c;并构建一个预测未来 3 天股价涨跌的分类任务 用TabPFN这个模型构建一个预测未来 3 天股价涨跌的分类任务&#xff0c;进行预测并输…...

macOS多出来了:Google云端硬盘、YouTube、表格、幻灯片、Gmail、Google文档等应用

文章目录 问题现象问题原因解决办法 问题现象 macOS启动台&#xff08;Launchpad&#xff09;多出来了&#xff1a;Google云端硬盘、YouTube、表格、幻灯片、Gmail、Google文档等应用。 问题原因 很明显&#xff0c;都是Google家的办公全家桶。这些应用并不是通过独立安装的…...

Spring Boot+Neo4j知识图谱实战:3步搭建智能关系网络!

一、引言 在数据驱动的背景下&#xff0c;知识图谱凭借其高效的信息组织能力&#xff0c;正逐步成为各行业应用的关键技术。本文聚焦 Spring Boot与Neo4j图数据库的技术结合&#xff0c;探讨知识图谱开发的实现细节&#xff0c;帮助读者掌握该技术栈在实际项目中的落地方法。 …...

CMake控制VS2022项目文件分组

我们可以通过 CMake 控制源文件的组织结构,使它们在 VS 解决方案资源管理器中以“组”(Filter)的形式进行分类展示。 🎯 目标 通过 CMake 脚本将 .cpp、.h 等源文件分组显示在 Visual Studio 2022 的解决方案资源管理器中。 ✅ 支持的方法汇总(共4种) 方法描述是否推荐…...

html-<abbr> 缩写或首字母缩略词

定义与作用 <abbr> 标签用于表示缩写或首字母缩略词&#xff0c;它可以帮助用户更好地理解缩写的含义&#xff0c;尤其是对于那些不熟悉该缩写的用户。 title 属性的内容提供了缩写的详细说明。当用户将鼠标悬停在缩写上时&#xff0c;会显示一个提示框。 示例&#x…...

Typeerror: cannot read properties of undefined (reading ‘XXX‘)

最近需要在离线机器上运行软件&#xff0c;所以得把软件用docker打包起来&#xff0c;大部分功能都没问题&#xff0c;出了一个奇怪的事情。同样的代码&#xff0c;在本机上用vscode可以运行起来&#xff0c;但是打包之后在docker里出现了问题。使用的是dialog组件&#xff0c;…...

MySQL账号权限管理指南:安全创建账户与精细授权技巧

在MySQL数据库管理中&#xff0c;合理创建用户账号并分配精确权限是保障数据安全的核心环节。直接使用root账号进行所有操作不仅危险且难以审计操作行为。今天我们来全面解析MySQL账号创建与权限分配的专业方法。 一、为何需要创建独立账号&#xff1f; 最小权限原则&#xf…...

SiFli 52把Imagie图片,Font字体资源放在指定位置,编译成指定img.bin和font.bin的问题

分区配置 (ptab.json) img 属性介绍&#xff1a; img 属性指定分区存放的 image 名称&#xff0c;指定的 image 名称必须是当前工程生成的 binary 。 如果 binary 有多个文件&#xff0c;则以 proj_name:binary_name 格式指定文件名&#xff0c; proj_name 为工程 名&…...

AI+无人机如何守护濒危物种?YOLOv8实现95%精准识别

【导读】 野生动物监测在理解和保护生态系统中发挥着至关重要的作用。然而&#xff0c;传统的野生动物观察方法往往耗时耗力、成本高昂且范围有限。无人机的出现为野生动物监测提供了有前景的替代方案&#xff0c;能够实现大范围覆盖并远程采集数据。尽管具备这些优势&#xf…...