快速排序与堆排序效率对比(TimeSpan计时)

来源:互联网 发布:中国装束复原小组淘宝 编辑:程序博客网 时间:2024/06/05 13:10

 

//C# Codeusing System;using System.Collections.Generic;using System.Linq;using System.Text;namespace HeapSort{    public static class Heap    {        /// <summary>        /// 堆排序        /// </summary>        /// <param name="arr">数组</param>        public static void Sort(int[] arr)        {            //初始化堆            InitialHeap(arr);            //无序区递减            for (int i = arr.Length - 1; i > 0; --i)            {                //交换堆顶元素与无序区末端元素                Program.Swap(ref arr[0], ref arr[i]);                //堆化新无序区                Heapify(arr, 0, i);            }        }         /// <summary>        /// 初始化堆        /// </summary>        /// <param name="arr">数组</param>        private static void InitialHeap(int[] arr)        {            //堆化所有以非叶子节点为堆顶的数据            for (int i = arr.Length / 2 - 1; i >= 0; --i)            {                Heapify(arr, i, arr.Length);            }        }         /// <summary>        /// 以指定节点为堆顶,由上至下递归堆化其所有子节点        /// </summary>        /// <param name="arr">数组</param>        /// <param name="nodeIndex">堆顶节点索引</param>        /// <param name="heapSize">堆大小(这里指数组无序区大小)</param>        private static void Heapify(int[] arr, int nodeIndex, int heapSize)        {            //左右子节点索引            int leftIndex = nodeIndex * 2 + 1;            int rightIndex = nodeIndex * 2 + 2;            //最大值节点索引            int maxIndex = nodeIndex;             //左子节点存在,并且值大于最大值节点            if (leftIndex < heapSize && arr[leftIndex] > arr[maxIndex])                maxIndex = leftIndex;//调整最大值节点索引             //右节点存在,并且值大于最大值            if (rightIndex < heapSize && arr[rightIndex] > arr[maxIndex])                maxIndex = rightIndex;//调整最大值节点索引             //两次比较之后,堆顶节点值不是最大            if (maxIndex != nodeIndex)            {                //将最大值交换至堆顶                Program.Swap(ref arr[nodeIndex], ref arr[maxIndex]);                //堆结构发生变化,递归调整堆                Heapify(arr, maxIndex, heapSize);            }        }//end Method Heapify()    }//end class Heap     class Program    {        private static Random Seed = new Random();//随机种子         //交换        public static void Swap(ref int a, ref int b)        {            int t = a;            a = b;            b = t;        }         /// <summary>        /// 快速排序        /// </summary>        /// <param name="arr">数组</param>        /// <param name="begin">起始索引</param>        /// <param name="end">结束索引</param>        /// <param name="isRandomKey">是否随机取Key</param>        private static void QuickSort(int[] arr, int begin, int end, bool isRandomKey)        {            //起始索引小于结束索引,排序未完成            if (begin < end)            {                int i = begin - 1, j = end + 1, key;                if (!isRandomKey)                    key = arr[(begin + end) / 2];                else//随机取Key                    key = arr[Seed.Next(begin, end)];                 while (true)                {                    //第一个大于Key值的元素索引                    while (i < end && arr[++i] < key) ;                    //最后一个小于Key值的元素索引                    while (j > 0 && arr[--j] > key) ;                     //索引已无需交换                    if (i >= j)                        break;                    //交换元素                    Swap(ref arr[i], ref arr[j]);                }                 QuickSort(arr, begin, i - 1, isRandomKey);//左部分子递归                QuickSort(arr, j + 1, end, isRandomKey);//右部分子递归            }//end if(begin < end)        }//end QuickSort()         /// <summary>        /// 计算经过毫秒数        /// </summary>        /// <param name="dtStart">起始时间</param>        /// <param name="dtEnd">结束时间</param>        /// <returns>返回毫秒数</returns>        private static double GetMilliSecond(DateTime dtStart, DateTime dtEnd)        {            TimeSpan ts1 = new TimeSpan(dtStart.Ticks);            TimeSpan ts2 = new TimeSpan(dtEnd.Ticks);            TimeSpan ts = ts1.Subtract(ts2).Duration();            return ts.TotalMilliseconds;        }         //输出        static void Output(int[] arr)        {            foreach (var item in arr)                Console.Write(item + " ");             Console.WriteLine();        }        //入口        static void Main(string[] args)        {            int ArrLen = 0;//数组长度 ReInput://重新输入             Console.Write("请输入待测试数组长度:");            if (!int.TryParse(Console.ReadLine(), out ArrLen))            {                Console.WriteLine("输入错误!");                goto ReInput;            }             //数组1,测试快速排序            int[] NumArr = new int[ArrLen];            //数组2,测试堆排序            int[] NumArr_2 = new int[NumArr.Length];             Console.WriteLine("正在随机初始化数组元素……");            for (int i = 0; i < NumArr.Length; i++)//随机(-1000 ~ 1000)初始化数组元素                NumArr[i] = Seed.Next(-1000, 1000);             Console.WriteLine("初始化完成");             Console.WriteLine("\n复制元素值到数组2……");            for (int i = 0; i < NumArr.Length; i++)//复制元素值                NumArr_2[i] = NumArr[i];             Console.WriteLine("复制完成");            /*//取消该段注释,输出排序前数组            Console.Write("排序前:");            Output(NumArr);             */                         Console.Write("\n开始快速排序,请稍后……");            DateTime dtStart = DateTime.Now;            QuickSort(NumArr, 0, NumArr.Length - 1, false);            //            DateTime dtEnd = DateTime.Now;            Console.WriteLine("\n快速排序完成,用时:{0} 毫秒", GetMilliSecond(dtStart, dtEnd));             /*//取消该段注释,输出排序后数组            Console.Write("\n\n\n排序后:");            Output(NumArr);             */             //.............................................................................................             Console.Write("\n开始堆排序,请稍后……");            dtStart = DateTime.Now;            Heap.Sort(NumArr_2);            //            dtEnd = DateTime.Now;            Console.WriteLine("\n堆排序完成,用时:{0} 毫秒", GetMilliSecond(dtStart, dtEnd));             /*//取消该段注释,输出排序后数组            Console.Write("\n\n\n排序后:");            Output(NumArr_2);             */             Console.Write("按任意键退出……");            Console.ReadKey(true);        }//end Main()    }//end class Program}//end namespace //欢迎转载,请注明原创,感谢