c# 排序算法可视化
最近在 b 站上看了一个排序算法的动画,所以想自己写一个类似的项目。
项目使用 Graphics 在 winform 的窗体上绘图。(新建项目时选择控制台项目,注意添加引用:System.Drawing, System.Windows.Forms)
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms; namespace Sort
{
/// <summary>
/// 排序算法
/// </summary>
class Program
{
static void Main(string[] args)
{
FrmSort frm = new FrmSort();
frm.ShowDialog();
}
} class FrmSort : Form
{
private const int length = ; //待排序集合的宽度
private const int width = ; //绘图时每个柱子的宽度
private const int height = ; //绘图时每个柱子的高度放大倍数 public FrmSort()
{
this.BackColor = Color.White;
this.Width = ;
this.Height = ;
this.Shown += new System.EventHandler(this.Frm_Shown);
} private void Frm_Shown(object sender, EventArgs e)
{
Insert();
HalfInsert();
SelectSort();
BubbleSort();
ShellSort();
MergeSort();
} //获得随机数组
static List<int> GetRandomList()
{
Random rnd = new Random();
List<int> listOriginal = new List<int>();
for (int i = ; i < (length + ); i++)
{
listOriginal.Add(i);
}
List<int> list = new List<int>();
foreach (int item in listOriginal)
{
list.Insert(rnd.Next(list.Count), item);
}
return list;
} static int[] GetRandomArray()
{
return GetRandomList().ToArray();
} // 绘图
private void Draw(List<int> valueList, List<int> reDrawIndexList, Graphics g, int xBase, int yBase)
{
for (int i = ; i < reDrawIndexList.Count; i++)
{
int xIndex = reDrawIndexList[i];
Pen whitePen = new Pen(Brushes.White, width);
Pen blackPen = new Pen(Brushes.Black, width);
Point point1 = new Point(xBase + xIndex * width, yBase);
Point point2 = new Point(xBase + xIndex * width, yBase + length * height);
Point point3 = new Point(xBase + xIndex * width, yBase + valueList[xIndex] * height);
g.DrawLine(whitePen, point1, point2);
g.DrawLine(blackPen, point1, point3);
}
} // 绘图
private void Draw(int[] valueList, List<int> reDrawIndexList, Graphics g, int xBase, int yBase)
{
for (int i = ; i < reDrawIndexList.Count; i++)
{
int xIndex = reDrawIndexList[i];
Pen whitePen = new Pen(Brushes.White, width);
Pen blackPen = new Pen(Brushes.Black, width);
Point point1 = new Point(xBase + xIndex * width, yBase);
Point point2 = new Point(xBase + xIndex * width, yBase + length * height);
Point point3 = new Point(xBase + xIndex * width, yBase + valueList[xIndex] * height);
g.DrawLine(whitePen, point1, point2);
g.DrawLine(blackPen, point1, point3);
}
} // 绘图
private void Draw(int myValue, int myIndex, Graphics g, int xBase, int yBase)
{
Pen whitePen = new Pen(Brushes.White, width);
Pen blackPen = new Pen(Brushes.Black, width);
Point point1 = new Point(xBase + myIndex * width, yBase);
Point point2 = new Point(xBase + myIndex * width, yBase + length * height);
Point point3 = new Point(xBase + myIndex * width, yBase + myValue * height);
g.DrawLine(whitePen, point1, point2);
g.DrawLine(blackPen, point1, point3);
} private void GetBasePoint(int index, out int xBase, out int yBase)
{
xBase = + (index % ) * width * length * / ;
yBase = + (index / ) * height * length * / ;
} //直接插入
//每一轮都保证左侧序列已排序, 右侧序列不断的往左侧序列中插入
private void Insert(int place)
{
int xBase, yBase;
GetBasePoint(place, out xBase, out yBase);
int[] intArray = GetRandomArray();
using (Graphics g = this.CreateGraphics())
{
List<int> listIndex = new List<int>();
for (int i = ; i < intArray.Length; i++)
{
listIndex.Add(i);
}
Draw(intArray, listIndex, g, xBase, yBase);
for (int i = ; i < intArray.Length; i++)
{
for (int j = i - ; (j >= ) && (intArray[j + ] < intArray[j]); j--)
{
int temp = intArray[j + ];
intArray[j + ] = intArray[j];
intArray[j] = temp;
Draw(intArray[j], j, g, xBase, yBase);
Draw(intArray[j + ], j + , g, xBase, yBase);
}
}
}
} //折半插入
//对直接插入进行优化,在左侧找到最佳的插入点后再插入,而不是按顺序逐个尝试
private void HalfInsert(int place)
{
int xBase, yBase;
GetBasePoint(place, out xBase, out yBase);
List<int> list = GetRandomList();
using (Graphics g = this.CreateGraphics())
{
List<int> listIndex = new List<int>();
for (int i = ; i < list.Count; i++)
{
listIndex.Add(i);
}
Draw(list, listIndex, g, xBase, yBase); for (int i = ; i < list.Count; i++)
{
int temp = list[i];
int low = ;
int high = i - ;
while (low <= high)
{
int mid = (low + high) / ;
if (temp < list[mid])
{
high = mid - ;
}
else
{
low = mid + ;
}
Draw(temp, mid, g, xBase, yBase);
Thread.Sleep();
Draw(list[mid], mid, g, xBase, yBase);
}
int myValue = list[i];
list.RemoveAt(i);
list.Insert(low, myValue);
listIndex.Clear();
for (int j = low; j <= i; j++)
{
listIndex.Add(j);
}
Draw(list, listIndex, g, xBase, yBase);
}
}
} //选择排序
//找出list[0- 99]中的最小值换到list[0]上
//找出list[1- 99]中的最小值换到list[1]上
//最后一轮:找出list[98- 99]中的最小值换到list[98]上
private void SelectSort(int place)
{
int xBase, yBase;
GetBasePoint(place, out xBase, out yBase);
List<int> list = GetRandomList();
using (Graphics g = this.CreateGraphics())
{
List<int> listIndex = new List<int>();
for (int i = ; i < list.Count; i++)
{
listIndex.Add(i);
}
Draw(list, listIndex, g, xBase, yBase);
for (int i = ; i < list.Count; i++)
{
//找出后面的最小值
int miniIndex = i;
int miniValue = list[i];
for (int j = i; j < list.Count; j++)
{
if (list[j] < miniValue)
{
miniIndex = j;
miniValue = list[j];
}
}
//重绘
if (miniIndex > i)
{
list.RemoveAt(miniIndex);
list.Insert(i, miniValue);
for (int j = i; j < miniIndex; j++)
{
Draw(list[j], j, g, xBase, yBase);
}
}
}
}
} //冒泡排序
//第一轮:intArray[0] > intArray[1] ? 交换 : 不变。intArray[1] > intArray[2] ..... intArray[98] > intArray[99] ?
//第二轮:intArray[0] > intArray[1] ? 交换 : 不变。intArray[1] > intArray[2] ..... intArray[97] > intArray[98] ?
//最后一轮:intArray[0] > intArray[1] ?
private void BubbleSort(int place)
{
int xBase, yBase;
GetBasePoint(place, out xBase, out yBase);
int[] intArray = GetRandomArray();
using (Graphics g = this.CreateGraphics())
{
List<int> listIndex = new List<int>();
for (int i = ; i < intArray.Length; i++)
{
listIndex.Add(i);
}
Draw(intArray, listIndex, g, xBase, yBase);
for (int i = intArray.Length; i > ; i--)
{
for (int j = ; j < i - ; j++)
{
if (intArray[j] > intArray[j + ])
{
int temp = intArray[j];
intArray[j] = intArray[j + ];
intArray[j + ] = temp;
Draw(intArray[j], j, g, xBase, yBase);
Draw(intArray[j + ], j + , g, xBase, yBase);
Thread.Sleep();
}
}
}
}
} //希尔排序
private void ShellSort(int place)
{
int xBase, yBase;
GetBasePoint(place, out xBase, out yBase);
int[] intArray = GetRandomArray();
using (Graphics g = this.CreateGraphics())
{
List<int> listIndex = new List<int>();
for (int i = ; i < intArray.Length; i++)
{
listIndex.Add(i);
}
Draw(intArray, listIndex, g, xBase, yBase);
for (int step = intArray.Length / ; step >= ; step = step / ) //增量递减到1使完成排序
{
for (int i = step; i < intArray.Length; i++) //插入排序的一轮
{
int temp = intArray[i];
int j = ;
for (j = i - step; (j >= ) && (intArray[j] > temp); j = j - step)
{
intArray[j + step] = intArray[j];
Draw(intArray[j + step], j + step, g, xBase, yBase);
Thread.Sleep();
}
intArray[j + step] = temp;
Draw(intArray[j + step], j + step, g, xBase, yBase);
}
}
}
} #region 归并排序
public void MergeSort(int place)
{
int xBase, yBase;
GetBasePoint(place, out xBase, out yBase);
int[] intArray = GetRandomArray();
using (Graphics g = this.CreateGraphics())
{
List<int> listIndex = new List<int>();
for (int i = ; i < intArray.Length; i++)
{
listIndex.Add(i);
}
Draw(intArray, listIndex, g, xBase, yBase);
MergeSort(intArray, , intArray.Length - , g, xBase, yBase);
}
} private void MergeSort(int[] array, int p, int r, Graphics g, int xBase, int yBase)
{
if (p < r)
{
int q = (p + r) / ;
MergeSort(array, p, q, g, xBase, yBase);
MergeSort(array, q + , r, g, xBase, yBase);
Merge(array, p, q, r, g, xBase, yBase);
}
} private void Merge(int[] array, int p, int q, int r, Graphics g, int xBase, int yBase)
{
int[] L = new int[q - p + ];
int[] R = new int[r - q + ];
L[q - p + ] = int.MaxValue;
R[r - q] = int.MaxValue; for (int i = ; i < q - p + ; i++)
{
L[i] = array[p + i];
} for (int i = ; i < r - q; i++)
{
R[i] = array[q + + i];
} int j = ;
int k = ;
for (int i = ; i < r - p + ; i++)
{
if (L[j] <= R[k])
{
array[p + i] = L[j];
j++;
}
else
{
array[p + i] = R[k];
k++;
}
Draw(array[p + i], p + i, g, xBase, yBase);
Thread.Sleep();
}
}
#endregion
}
}
c# 排序算法可视化的更多相关文章
- 【Unity3D自学记录】可视化对照十多种排序算法(C#版)
在这篇文章中.我会向大家展示一些排序算法的可视化过程.我还写了一个工具.大家可对照查看某两种排序算法. 下载源代码 – 75.7 KB 下载演示样例 – 27.1 KB 引言 首先,我觉得是最重要的是 ...
- 基于Qt5的排序算法简单可视化
之前写了几个排序算法,然后看到别人将排序算法的过程可视化出来,所以就想尝试一下,然后就用Qt简单写了个界面,用QImage和QPainter来画图显示,代码比较简单. 我的想法是画图的时候,图像的X轴 ...
- Rxjs入门实践-各种排序算法排序过程的可视化展示
Rxjs入门实践-各种排序算法排序过程的可视化展示 这几天学习下<算法>的排序章节,具体见对排序的总结,想着做点东西,能将各种排序算法的排序过程使用Rxjs通过可视化的方式展示出来,正好练 ...
- 八大排序算法的 Python 实现
转载: 八大排序算法的 Python 实现 本文用Python实现了插入排序.希尔排序.冒泡排序.快速排序.直接选择排序.堆排序.归并排序.基数排序. 1.插入排序 描述 插入排序的基本操作就是将一个 ...
- 排序算法总结(一)插入排序【Insertion Sort】
最近在忙着找工作,以前看的排序算法都忘记了,悲剧啦T T现在来回顾一下吧. 这边推荐一个算法可视化的网站,非常有用.http://visualgo.net/ 一.插入排序的思想(Wikipedia) ...
- [读书笔记]算法(Sedgewick著)·第二章.初级排序算法
本章开始学习排序算法 1.初级排序算法 先从选择排序和插入排序这两个简单的算法开始学习排序算法.选择排序就是依次找到当前数组中最小的元素,将其和第一个元素交换位置,直到整个数组有序. public s ...
- js排序算法汇总
JS家的排序算法 十大经典算法排序总结对比 一张图概括: 主流排序算法概览 名词解释: n: 数据规模k:“桶”的个数In-place: 占用常数内存,不占用额外内存Out-place: 占用额外 ...
- 基本排序算法<二>
归并排序 归并排序,顾名思义,就是通过将两个有序的序列合并为一个大的有序的序列的方式来实现排序.合并排序是一种典型的分治算法:首先将序列分为两部分,然后对每一部分进行循环递归的排序,然后逐个将结果进行 ...
- 排序算法的JS实现
排序算法是基础算法,虽然关键在于算法的思想而不是语言,但还是决定借助算法可视化工具结合自己常用的语言实现一下 1.冒泡排序 基本思路:依次比较两两相邻的两个数,前面数比后面数小,不变.前面数比后面数大 ...
随机推荐
- Linux 环境下安装rlwrap工具
rlwrap项目是一个“readline包装器”,它使用GNU readline库来编辑任何其他命令的键 盘输入.通过rlwrap可以进行命令的上下切换,类似历史命令. 1.下载rlwrap rpm ...
- Php 十六进制短浮点数转十进制,带符号位
/** * 十六进制浮点型转为十进制 * @param String $strHex 十六进制浮点数 * @return 十进制 */ public static function hexToDecF ...
- Docker镜像仓库的搭建--> Harbor篇
简介 Harbor是VMware公司开源的一个企业级Docker Registry项目,项目地址:https://github.com/goharbor/harbor Harbor作为一个企业级私有R ...
- Jquery查找界面Html元素的方法(持续更新)
1. 根据id来获取:$("#id") 2.根据class来获取:$(".class") 3.根据name来获取:$("[name=??]" ...
- 最长上升子序列(LIS)长度及其数量
例题51Nod-1376,一个经典问题,给出一个序列问该序列的LIS以及LIS的数量. 这里我学习了两种解法,思路和代码都是参考这两位大佬的: https://www.cnblogs.com/reve ...
- Codeforces 1178E
题意:给你一个长度为n的字符串,只包含a, b, c3种字符,字符串中相邻字符一定不同,问是否存在一个长度为n / 2(向下取整)的子序列是回文的,有就输出. 思路:相邻的字符一定不同,并且一共只有3 ...
- 【转】Git的安装与使用
Git作为分布式的版本控制器有其独特的优势,可以不依赖与网络而进行版本控制,而SVN则必须有网才可以.今天咱们不讨论Git与SVN的具体区别.咱们先看看Git这个分布式版本控制器是怎么玩的.下面的内容 ...
- 第10篇用 ConfigMap 管理配置
一.ConfigMap介绍管理配置: ConfigMap介绍 Secret 可以为 Pod 提供密码.Token.私钥等敏感数据:对于一些非敏感数据,比如应用的配置信息,则可以用 Config ...
- tomcat manager 禁止外网访问 只容许内网访问
参考:http://tomcat.apache.org/tomcat-7.0-doc/manager-howto.html A default Tomcat installation includes ...
- JavaSE---Runtime类
1.概述 1.1 Runtime类 代表 java程序运行时环境: 1.2 Runtime类 提供的类方法: getRuntime():获取Runtime实例: gc():通知垃圾回收器回收资源: ...