最近在 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# 排序算法可视化的更多相关文章

  1. 【Unity3D自学记录】可视化对照十多种排序算法(C#版)

    在这篇文章中.我会向大家展示一些排序算法的可视化过程.我还写了一个工具.大家可对照查看某两种排序算法. 下载源代码 – 75.7 KB 下载演示样例 – 27.1 KB 引言 首先,我觉得是最重要的是 ...

  2. 基于Qt5的排序算法简单可视化

    之前写了几个排序算法,然后看到别人将排序算法的过程可视化出来,所以就想尝试一下,然后就用Qt简单写了个界面,用QImage和QPainter来画图显示,代码比较简单. 我的想法是画图的时候,图像的X轴 ...

  3. Rxjs入门实践-各种排序算法排序过程的可视化展示

    Rxjs入门实践-各种排序算法排序过程的可视化展示 这几天学习下<算法>的排序章节,具体见对排序的总结,想着做点东西,能将各种排序算法的排序过程使用Rxjs通过可视化的方式展示出来,正好练 ...

  4. 八大排序算法的 Python 实现

    转载: 八大排序算法的 Python 实现 本文用Python实现了插入排序.希尔排序.冒泡排序.快速排序.直接选择排序.堆排序.归并排序.基数排序. 1.插入排序 描述 插入排序的基本操作就是将一个 ...

  5. 排序算法总结(一)插入排序【Insertion Sort】

    最近在忙着找工作,以前看的排序算法都忘记了,悲剧啦T  T现在来回顾一下吧. 这边推荐一个算法可视化的网站,非常有用.http://visualgo.net/ 一.插入排序的思想(Wikipedia) ...

  6. [读书笔记]算法(Sedgewick著)·第二章.初级排序算法

    本章开始学习排序算法 1.初级排序算法 先从选择排序和插入排序这两个简单的算法开始学习排序算法.选择排序就是依次找到当前数组中最小的元素,将其和第一个元素交换位置,直到整个数组有序. public s ...

  7. js排序算法汇总

    JS家的排序算法   十大经典算法排序总结对比 一张图概括: 主流排序算法概览 名词解释: n: 数据规模k:“桶”的个数In-place: 占用常数内存,不占用额外内存Out-place: 占用额外 ...

  8. 基本排序算法<二>

    归并排序 归并排序,顾名思义,就是通过将两个有序的序列合并为一个大的有序的序列的方式来实现排序.合并排序是一种典型的分治算法:首先将序列分为两部分,然后对每一部分进行循环递归的排序,然后逐个将结果进行 ...

  9. 排序算法的JS实现

    排序算法是基础算法,虽然关键在于算法的思想而不是语言,但还是决定借助算法可视化工具结合自己常用的语言实现一下 1.冒泡排序 基本思路:依次比较两两相邻的两个数,前面数比后面数小,不变.前面数比后面数大 ...

随机推荐

  1. 【题解】A Horrible Poem

    题目大意 给出一个由小写英文字母组成的字符串 S,再给出 q 个询问,要求回答 S 某个子串的最短循环节. 如果字符串 B 是字符串 A 的循环节,那么 A 可以由 B 重复若干次得到. 输入格式 第 ...

  2. C# DataTable转json 时间格式化

    1.NewTonSoft.json public static string DataTableToJson(DataTable dt) { ) { return ""; } el ...

  3. ES6几大特性,让你的代码更优美

    1.Default Parameters(默认参数) in ES6 还记得我们以前不得不通过下面方式来定义默认参数:   var link = function (height, color, url ...

  4. [fw]How to use DISM to install a hotfix from within Windows

    How to use DISM to install a hotfix from within Windows Jeff Hughes (CORE) 15 Feb 2011 10:10 AM 22 H ...

  5. shell条件测试语句

  6. go语言从例子开始之Example2.类型

    Go 拥有各值类型,包括字符串,整形,浮点型,布尔型等.下面是一些基本的例子. Example: values.go package main import "fmt" func ...

  7. KVM主机迁移

    目录 新主机kvm初始环境的部署 I.检查主机cpu是否支持虚拟化 II.宿主机软件安装 III.检查kvm模块是否加载 IV.网桥的搭建 V.查看宿主机网络 迁移kvm主机数据 I.查看宿主机上现有 ...

  8. codeblocks编译调试C语言二级指针小记

    夜已深,暂时附上一个截图,后面慢慢道来. 下图时用codeblocks调试C语言的界面,codeblocks版本是17.12nosetup版,也为继承mingw,我用的编程器是tdm-gcc-5.1. ...

  9. 一次峰回路转的getshell

    扫目录发现 http://www.xxx.test.cn/bak/以及/bak/upload.jsp

  10. 【Shell】ps -ef 和ps aux

    两者没太大差别 追溯到Unix系统中的两种风格,System V风格和BSD 风格,ps aux最初用到Unix Style中,而ps -ef被用在System V Style中,两者输出略有不同.现 ...