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 AnimatorPatterm
{
static class StartSetGenerator
{
private static List<int> myList;
public static IEnumerable<int> GetStartSet()
{
const int n = 200; //how many values to generate
if (myList == null)
{
List<int> list = new List<int>();
Random rnd = new Random();
List<int> range = new List<int>();
for (int i = 0; i < n; i++)
range.Add(i);
while (range.Count > 0)
{
int item = range[rnd.Next(range.Count )];
list.Add(item);
range.Remove(item);
}
myList = list;
}
return myList;
}
}
class StrategyView<T> : Form where T : IComparable<T>
{
PictureBox pb;
Func<IEnumerable<T>> Generator;
public StrategyView(Func<IEnumerable<T>> generator)
{
this.Generator = generator;
this.Text = "Sort Comparer";
this.pb = new PictureBox();
pb.Dock = DockStyle.Fill;
pb.BackColor = Color.White;
pb.BorderStyle = BorderStyle.Fixed3D;
this.Controls.Add(pb);
TableLayoutPanel p = new TableLayoutPanel();
p.RowCount = 1;
p.ColumnCount = 3;
p.Dock = DockStyle.Top;
this.Controls.Add(p);
Button b = new Button();
b.Name = "LargeItems";
b.Click += new EventHandler(ButtonClick);
b.Text = "Objects";
p.Controls.Add(b);
b = new Button();
b.Name = "SmallItems";
b.Click += new EventHandler(ButtonClick);
b.Text = "Primitive";
p.Controls.Add(b);
b = new Button();
b.Name = "ReversedList";
b.Click += new EventHandler(ButtonClick);
b.Text = "Reversed";
p.Controls.Add(b);
p.Height = b.Height + 4;
this.DoubleBuffered = true;
this.ResumeLayout(true);
}
public void DrawGraph(IEnumerable<T> list)
{
if (pb.Image == null)
pb.Image = new Bitmap(pb.Width, pb.Height);
Graphics g = Graphics.FromImage(pb.Image);
g.Clear(Color.White);
g.DrawRectangle(Pens.Blue, 19, 19, 202, 202);
g.Dispose();
Bitmap b = pb.Image as Bitmap;
int listSize = list.Count();
int x = 0;
foreach (T item in list)
{
int? val = item as int?;
if (!val.HasValue)
val = 0;
b.SetPixel(x + 20, 20 + 200 - ((int)val), Color.Black);
x++;
}
this.Refresh();
Thread.Sleep(100);
Application.DoEvents();
}
void ButtonClick(object sender, EventArgs e)
{
Button control = sender as Button;
ISortStrategy<T> strategy = null;
strategy = SelectStrategy(control.Name, strategy);
IEnumerable<T> newList = Generator();
DrawGraph(newList);
if (strategy == null)
return;
strategy.UpdatedUI += new Action<IEnumerable<T>>(DrawGraph);
strategy.Sort(newList);
}
private static ISortStrategy<T> SelectStrategy(string name, ISortStrategy<T> strategy)
{
switch (name)
{
case "LargeItems":
strategy = new MergeSorter<T>();
break;
case "SmallItems":
strategy = new QuickSorter<T>();
break;
case "ReversedList":
strategy = new MergeSorter<T>();
break;
}
return strategy;
}
}
interface ISortStrategy<T> where T : IComparable<T>
{
event Action<IEnumerable<T>> UpdatedUI;
void Sort(IEnumerable<T> input);
}
class MergeSorter<T> : ISortStrategy<T> where T : IComparable<T>
{
public event Action<IEnumerable<T>> UpdatedUI;
List<T> aux;
int opCount = 0;
public void Sort(IEnumerable<T> input)
{
UpdatedUI(input);
opCount++;
List<T> sorteditems = new List<T>(input);
aux = new List<T>(sorteditems.Count);
for (int i = 0; i < sorteditems.Count; i++)
aux.Add(default(T));
MergeSort(ref sorteditems, 0, sorteditems.Count - 1);
UpdatedUI(sorteditems);
}
private void Merge(ref List<T> a, int l, int m, int r)
{
int i;
int j;
for (i = m + 1; i > l; i--)
{
aux[i - 1] = a[i - 1];
opCount++;
}
for (j = m; j < r; j++)
{
aux[r + m - j] = a[j + 1];
opCount++;
}
for (int k = l; k <= r; k++)
{
if (aux[j].CompareTo(aux[i]) == -1)
a[k] = aux[j--];
else
a[k] = aux[i++];
opCount++;
}
}
private void MergeSort(ref List<T> a, int l, int r)
{
if (r <= l) return;
int m = (r + l) / 2;
MergeSort(ref a, l, m);
if (opCount > 50)
{
UpdatedUI(a);
opCount -= 50;
}
MergeSort(ref a, m+1, r);
if (opCount > 50)
{
UpdatedUI(a);
opCount -= 50;
}
Merge(ref a , l,m,r);
if (opCount > 50)
{
UpdatedUI(a);
opCount -= 50;
}
}
}
class QuickSorter<T> : ISortStrategy<T>
where T : IComparable<T>
{
public event Action<IEnumerable<T>> UpdatedUI;
int opCount = 0;
public void Sort(IEnumerable<T> input)
{
UpdatedUI(input);
opCount++;
List<T> sorteditems = new List<T>(input);
QuickSort(ref sorteditems, 0, sorteditems.Count - 1);
UpdatedUI(sorteditems);
}
private int Partition(ref List<T> a, int l, int r)
{
T tmp;
int i = l - 1;
int j = r;
T v = a[r];
for (; ; )
{
while (a[++i].CompareTo(v) == -1)
{
opCount++;
}
while (j>=2 && v.CompareTo(a[--j]) == -1)
{
opCount++;
//if(j==1)break ;//bug,因为恰当j=1,进入while循环时,就会出错!
}
if (i >= j) break;
tmp = a[i];
a[i] = a[j];
a[j] = tmp;
opCount++;
}
a[r] = a[i];
a[i] = v;
if (opCount > 50)
{
UpdatedUI(a);
opCount -= 50;
}
return i;
}
private void QuickSort(ref List<T> a, int l, int r)
{
opCount++;
if (r <= l) return;
int i = Partition(ref a, l, r);
QuickSort(ref a, l, i - 1);
QuickSort(ref a, i + 1, r);
}
}
class Program
{
static void Main(string[] args)
{
//Application.EnableVisualStyles();
//Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new StrategyView<int>(StartSetGenerator.GetStartSet));
}
}
}