通用快速排序算法

前 注:

这是自己平时根据自己需要写的一些小代码,为了避免再次数据丢失,所以放到网上来,未必对各看官有用。另外,这是根据个人想法而写,未必严谨和符合设计原则,若有任何不妥之处,还请不吝赐教。

说 明:

对于排序或查找算法而言,这些代码复用的一个难点在于:算法逻辑和数据集操作的代码是耦合在一起的。导致即使算法逻辑一样,但因为数据集类型的差异,也不得不重新实现整个算法。而我们所想要的算法复用,其实是算法逻辑的复用。因此,要复用算法,关键在于把算法逻辑抽取出来。由于一般情况下,算法的结构是数据集操作嵌入到算法逻辑过程中,因此,若能为数据集操作抽象出统一的接口,则算法逻辑就可以通用了。
如何为数据集操作抽象一个接口,应该为数据集定义一个基类吗?显然不可行,虽然.NET有一些集合类型的基础接口,但这些接口基本上没有提供排序所需操作的方法。而且并非所有的类型都有相同的基类型。因此,要抽象操作数据的接口,必须换个角度。
对于大部排序算法来说,涉及对数据集的操作无外乎:一、比较数据集中两个值;二、交换数据集中的两个值。只需设计这两个操作的接口即可。显然,如何比较比较数据要依数据类型和业务要求而定,而如何交换数据的值则与数据集结构和数据类型有关。另一方面,其实算法所决定的只有一点:要比较或交换的数据的位置,算法所关心的也只有一点:比较操作的结果(即返回值)。
综上,可以抽象一个这样的数据操作接口:一、比较,接受两个索引,返回比较结果;二、交换,接受两个索引,无返回值。算法调用这两个接口并传入索引,调用方负责实现比较两个索引处的值和交换两个索引处的值。
对于C#而言,此接口可以使用委托实现,而对于Java,则只能使用Interface来实现。相对来说,委托实现简洁一点,使用方需要做的工作也少一点,效率也应该会高一点。

另外,对于快速排序,其实只需要一个数据源的双向迭代访问器即可,不过这样实现起来想来应该比上述方法要繁琐一点。

 

示 例:

    class QuickSortTest

    {

        static byte[] Array;



        static Random Random = new Random();



        static QuickSorter QuickSorter = new QuickSorter();



        public static void Swap(int IdxA, int IdxB)

        {

            byte Temp = Array[IdxA];

            Array[IdxA] = Array[IdxB];

            Array[IdxB] = Temp;

        }



        public static int Compare(int IdxA, int IdxB)

        {

            return Array[IdxA] - Array[IdxB];

        }



        public static void Test()

        {

            int TestTimes = 1000;



            while (--TestTimes > 0)

            {

                Array = new byte[Random.Next(50)];



                Random.NextBytes(Array);



                Console.Write("\r\nBefore Sort : ");



                foreach (byte Data in Array)

                {

                    Console.Write(Data.ToString() + '\t');

                }



                QuickSorter.QuickSort(0, Array.Length - 1, Compare, Swap);



                Console.Write("\r\nAfter Sort : ");



                foreach (byte Data in Array)

                {

                    Console.Write(Data.ToString() + '\t');

                }



                if (Array.Length <= 1) continue;



                for (int Idx = 0; Idx < Array.Length - 1; Idx++)

                {

                    if (Array[Idx] > Array[Idx + 1])

                        Console.Write("\r\nSort Error");

                }

            }

        }

    }

原 码:

    public class QuickSorter

    {

        public delegate int CompareDelegate(int IdxA, int IdxB);



        public delegate void SwapDelegate(int IdxA, int IdxB);



        private CompareDelegate Comparer;



        private SwapDelegate Swaper;



        public int QuickSort(int LBound, int UBound, CompareDelegate Comparer, SwapDelegate Swaper)

        {

            this.Comparer = Comparer;

            this.Swaper = Swaper;



            QuickSort(LBound, UBound);



            return 1;

        }



        private int QuickSort(int LBound, int UBound)

        {

            if (UBound - LBound < 1) return 0;



            int ForwardPointr = LBound, BackwardPointer = UBound + 1;



            //注:以第一个元素为参考



            while (ForwardPointr < BackwardPointer)

            {

                //从前往找第一个大于参考的数

                while (++ForwardPointr < BackwardPointer && Comparer(LBound, ForwardPointr) >= 0) ;



                //从后往找第一个小于等于参考的数

                while (--BackwardPointer > ForwardPointr && Comparer(LBound, BackwardPointer) < 0) ;



                //如果找到,则交换值

                if (ForwardPointr < BackwardPointer) Swaper(BackwardPointer, ForwardPointr);

            }



            //将参考值换到中间

            Swaper(LBound, --ForwardPointr);



            QuickSort(LBound, ForwardPointr - 1);

            QuickSort(ForwardPointr + 1, UBound);



            return 1;

        }

    }

你可能感兴趣的:(快速排序)