C# 多线程排序Demo
时间:2011-05-30 来源:炭炭
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
namespace AlgorithmSort
{
public partial class Form1 : Form
{
int[] Array1, Array2, Array3;
CSort QuicklySort ;
CSort ShellSort;
CSort BubbleSort;
System.Threading.Thread theQuicklySortThread;
System.Threading.Thread theShellSortThread;
System.Threading.Thread theBubbleSortThread;
System.Threading.Thread theDeamonThread;
public Form1()
{
InitializeComponent();
Array1 = new int[100];
Array2 = new int[100];
Array3 = new int[100];
InitializeData(ref Array1);
Array.Copy(Array1,Array2,Array2.Length);
Array.Copy(Array1,Array3,Array3.Length);
QuicklySort = new CSort(panel3);
ShellSort = new CSort(panel2);
BubbleSort = new CSort(panel1);
}
/// <summary>
/// 用随机数初始化数组A的每一成员
/// </summary>
/// <param name="A">通过引用的方式,返回数组A中的数据</param>
private void InitializeData(ref int[] A)
{
System.Random Randomer = new System.Random();
for (int i = 0; i < A.Length;i++ )
{
A[i] = Randomer.Next() % A.Length;
}
}
/// <summary>
/// 根据指定数组每一组数据的大小,在Panel上画红线,数据越大,线越长
/// 注,初始化数组时,使用数组的长度做为数据取值的最大值
/// </summary>
/// <param name="thePanel">画线的区域控件</param>
/// <param name="Array">数据数组</param>
private void ShowData(System.Windows.Forms.Panel thePanel, int[] theArray)
{
System.Drawing.Graphics theGraph = thePanel.CreateGraphics();
System.Drawing.Pen thePen = new System.Drawing.Pen(System.Drawing.Color.Red);
System.Drawing.Pen theEraser = new System.Drawing.Pen(thePanel.BackColor);
for (int i = 0; i < theArray.Length; i++)
{
theGraph.DrawLine(thePen, 0,
i * thePanel.ClientRectangle.Height / theArray.Length,
theArray[i] * thePanel.ClientRectangle.Width / theArray.Length,
i * thePanel.ClientRectangle.Height / theArray.Length
);
theGraph.DrawLine(theEraser,
theArray[i] * thePanel.ClientRectangle.Width / theArray.Length,
i * thePanel.ClientRectangle.Height / theArray.Length,
thePanel.ClientRectangle.Width,
i * thePanel.ClientRectangle.Height / theArray.Length
);
}
}
public void BubbleSortProc(Object SortObj)
{
if (SortObj is CSort)
{
CSort ASortObj = SortObj as CSort;
ASortObj.BubbleSort(ref Array1);
}
}
public void QuicklySortProc( Object SortObj )
{
if (SortObj is CSort)
{
CSort ASortObj = SortObj as CSort;
ASortObj.QuickSort(ref Array3, 0, Array3.Length, Array3.Length);
}
}
public void ShellSortProc(Object SortObj)
{
if (SortObj is CSort)
{
CSort ASortObj = SortObj as CSort;
ASortObj.ShellSort(ref Array2);
}
}
/// <summary>
/// 三个排序线程的守护线程
/// </summary>
public void DeamonProc()
{
//等待快速排序线程结束
while ((theQuicklySortThread != null)
&& (theQuicklySortThread.ThreadState == System.Threading.ThreadState.Running)
)
{
System.Threading.Thread.Sleep(1);
}
//等待希尔排序线程结束
while ((theShellSortThread != null)
&& (theShellSortThread.ThreadState == System.Threading.ThreadState.Running)
)
{
System.Threading.Thread.Sleep(1);
}
//等待冒泡排序线程结束
while ((theBubbleSortThread != null)
&& (theBubbleSortThread.ThreadState == System.Threading.ThreadState.Running)
)
{
System.Threading.Thread.Sleep(1);
}
//所有线程排序结束
//允许下次重新开始
System.Windows.Forms.Control.CheckForIllegalCrossThreadCalls = false;
this.btnQuit.Enabled = true;
this.btnRefresh.Enabled = true;
this.btnStart.Enabled = true;
}
/// <summary>
/// “数据刷新”按钮的处理函数,重新初始化三个数据数组,并刷新界面显示
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void btnRefresh_Click(object sender, EventArgs e)
{
if( (theQuicklySortThread.ThreadState== System.Threading.ThreadState.Running)
||(theShellSortThread.ThreadState == System.Threading.ThreadState.Running)
||(theBubbleSortThread.ThreadState == System.Threading.ThreadState.Running)
)
{
return ;
}
InitializeData(ref Array1);
Array.Copy(Array1, Array2, Array2.Length);
Array.Copy(Array1, Array3, Array3.Length);
ShowData(panel1, Array1);
ShowData(panel2, Array2);
ShowData(panel3, Array3);
btnStart.Enabled = true;
btnRefresh.Enabled = false;
}
/// <summary>
/// 启动 排序进程按钮 的处理函数
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void BtnStart_Click(object sender, EventArgs e)
{
theQuicklySortThread = new System.Threading.Thread(this.QuicklySortProc);
theShellSortThread = new System.Threading.Thread(this.ShellSortProc);
theBubbleSortThread = new System.Threading.Thread(this.BubbleSortProc);
theDeamonThread = new System.Threading.Thread(this.DeamonProc);
theBubbleSortThread.Start(BubbleSort);
theShellSortThread.Start(ShellSort);
theQuicklySortThread.Start(QuicklySort);
//启动看护线程
theDeamonThread.Start();
btnStart.Enabled = false;
btnRefresh.Enabled = false;
btnQuit.Enabled = false;
}
//窗体重画事件处理函数
private void Form1_Paint(object sender, PaintEventArgs e)
{
ShowData(panel1, Array1);
ShowData(panel2, Array2);
ShowData(panel3, Array3);
}
/// <summary>
/// 窗体关闭前事件处理函数,如果排序线程没有完成,则不让关闭
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
if (theBubbleSortThread == null)
return;
if ((theBubbleSortThread.ThreadState == System.Threading.ThreadState.Running)
|| (theShellSortThread.ThreadState == System.Threading.ThreadState.Running)
|| (theQuicklySortThread.ThreadState == System.Threading.ThreadState.Running)
)
{
e.Cancel = true; //不允许退出;
}
}
private void btnQuit_Click(object sender, EventArgs e)
{
this.Close();
}
}
public class CSort
{
private Panel m_Panel;
public CSort(Panel newPanel)
{
m_Panel = newPanel;
}
//根据数据画线
public void DrawData(int nPos, int nValue,int nMax)
{
System.Drawing.Pen thePen = new System.Drawing.Pen(System.Drawing.Color.Red);
System.Drawing.Pen theEraser = new System.Drawing.Pen(m_Panel.BackColor);
System.Drawing.Graphics theGraph = m_Panel.CreateGraphics();
theGraph.DrawLine(thePen, 0,
nPos * m_Panel.ClientRectangle.Height / nMax,
nValue * m_Panel.ClientRectangle.Width / nMax,
nPos * m_Panel.ClientRectangle.Height / nMax
);
theGraph.DrawLine(theEraser, nValue * m_Panel.ClientRectangle.Width / nMax,
nPos * m_Panel.ClientRectangle.Height / nMax,
m_Panel.ClientRectangle.Width,
nPos * m_Panel.ClientRectangle.Height / nMax
);
}
/// <summary>
/// 交换两个对象引用指向的内容
/// </summary>
/// <param name="A"> 交换引用1 </param>
/// <param name="B"> 交换引用2 </param>
///
public static void Exchange(ref int A, ref int B)
{
int tmp = A;
A = B;
B = tmp;
}
/// <summary>
/// 委托函数 Compare( object A,object B);
///比较对象 A,B 关键字大小,如果 A < B则返回 true,否则false
/// <param name="A">比较大小的参数1</param>
/// <param name="B">比较大小的参数2</param>
/// </summary>
//public delegate bool PCompare(int A, int B);
/// <summary>
/// 冒泡排序法,把对像数组A中的对象,按一定顺序排列,排列的次序取决于Compare函数的比较方案
/// </summary>
/// <param name="A"> 被排序的对象数组</param>
/// <param name="Compare"> 比较对象关键字大小的函数委托变量</param>
///
//此委托测试用,没实际价值
//public delegate void Sort(ref T[] A, PCompare Compare);
public void BubbleSort( ref int[] A)
{
bool bFinished = false;
while (!bFinished)
{
bFinished = true;
for(int i=0; i<A.Length-1; i++)
{
if(A[i] > A[i+1])
{
//交换
Exchange(ref A[i], ref A[i + 1]);
DrawData(i, A[i], A.Length);
DrawData(i + 1, A[i+1], A.Length);
//在m_Panel上同时画线
//T tmp = A[i];
//A[i] = A[i+1];
//A[i+1] = tmp;
bFinished = false;
}
}
}
}
/// <summary>
/// 希尔(或叫步长)排序法,把对像数组A中的对象,按一定顺序排列,排列的次序取决于Compare函数的比较方案
/// </summary>
/// <param name="A"> 被排序的对象数组</param>
/// <param name="Compare"> 比较对象关键字大小的函数委托变量</param>
///
public void ShellSort( ref int[] A)
{
int Step = A.Length / 2;
bool bSorted = false;
while ((Step > 1) || (bSorted==false))
{
bSorted = true;
for (int i = 0; i < A.Length - Step; i++)
{
if( A[i] > A[i+Step] )
{
Exchange(ref A[i],ref A[i + Step]);
DrawData(i, A[i], A.Length);
DrawData(i + Step, A[i + Step], A.Length);
bSorted = false;
}
}
if ((Step > 1) && (bSorted==true))
{
Step = Step / 2;
bSorted = false;
}
}
}
/// <summary>
/// 快速排序法,把对像数组A中的对象,按一定顺序排列,排列的次序取决于Compare函数的比较方案
/// </summary>
/// <param name="A"> 被排序的对象数组</param>
/// <param name="Compare">比较对象关键字大小的函数委托变量</param></param>
public void QuickSort( ref int[] A, int nPosStart,int nPosFinish, int nMax)
{
if( A.Length <=1 )
{
return ;
}
else
{
int[] A1,A2;
//把数组A分成两个子集 A1,A2
A1 = new int[(A.Length / 2)];
A2 = new int[(A.Length - A.Length/2)];
for(int i=0;i<A.Length/2;i++)
A1[i] = A[i];
for(int i=A.Length/2; i<A.Length;i++)
A2[i-A.Length/2] = A[i];
//两个子集数组分别排序
QuickSort(ref A1,nPosStart,nPosStart+ (int)System.Math.Round((nPosFinish-nPosStart)/2.0f) , nMax);
QuickSort(ref A2, (int)System.Math.Round((nPosFinish - nPosStart) / 2.0f) + 1, nPosFinish , nMax);
//合并两个子集
int index1=0;
int index2=0;
int index =0;
while ( (index1 <A1.Length) && (index2 <A2.Length))
{
if ( A1[index1] > A2[index2])
{
A[index++] = A2[index2++];
}
else
{
A[index++] = A1[index1++];
}
}
if (index1 <A1.Length)
{
while(index<A.Length)
{
A[index++] = A1[index1++];
}
}
else
{
while(index<A.Length)
{
A[index++] = A2[index2++];
}
}
//显示数据
System.Drawing.Graphics theGraph = m_Panel.CreateGraphics();
System.Drawing.Pen thePen = new System.Drawing.Pen(System.Drawing.Color.Red);
System.Drawing.Pen theEraser = new System.Drawing.Pen(m_Panel.BackColor);
for (int i = 0; i < A.Length; i++)
{
theGraph.DrawLine(thePen, 0,
(i + nPosStart) * m_Panel.ClientRectangle.Height / nMax,
A[i] * m_Panel.ClientRectangle.Width / nMax,
(i + nPosStart) * m_Panel.ClientRectangle.Height / nMax
);
theGraph.DrawLine(theEraser,
A[i] * m_Panel.ClientRectangle.Width / nMax,
(i + nPosStart) * m_Panel.Height / nMax,
m_Panel.ClientRectangle.Width,
(i + nPosStart) * m_Panel.ClientRectangle.Height / nMax
);
}
}
}
}
}