首页 前端知识 WPF 实现冒泡排序可视化

WPF 实现冒泡排序可视化

2024-11-04 09:11:06 前端知识 前端哥 329 531 我要收藏

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");
        }
    }
转载请注明出处或者链接地址:https://www.qianduange.cn//article/19899.html
标签
评论
发布的文章
大家推荐的文章
会员中心 联系我 留言建议 回顶部
复制成功!