Don't think you are, know you are

博客园 首页 新随笔 管理

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
                        );
                }


   }
  }

 }

 
}

posted on 2011-05-30 01:18  炭炭  阅读(1481)  评论(0编辑  收藏  举报