ASP.NET----算法集(2)

本文深入探讨了多种排序算法,包括归并排序、基数排序、计数排序、堆排序等,详细介绍了各种排序算法的核心思想、实现步骤及时间复杂度。
6. 归并排序
using System;  
using System.Collections.Generic;  
using System.Linq;  
using System.Text;  
  
namespace Merge  
{  
    public class Function  
    {  
        private int Groups;  
        private int CopyGroups;  
        private int mergerows;  
        private int[] Array27;  
        private static Random ran = new Random();  
        public Function(int length)  
        {  
            Array27 = new int[length];  
            for (int i = 0; i < length; i++)  
                Array27[i] = ran.Next(1, 100);  
        }  
        //选择  
        public void ToMergeSort()  
        {  
            MergeSort(Array27);  
        }  
        public void ToRecursiveMergeSort()  
        {  
            RecursiveMergeSort(Array27, 0, Array27.Length - 1);  
        }  
        public void ToNaturalMergeSort()  
        {  
            NaturalMergeSort(Array27);  
        }  
  
        /// <summary>  
        /// 归并排序(递归)  
        ///    核心思想:(分治)  
        ///           将待排序元素(递归直至元素个数为1)分成左右两个大小大致相同的2个子集合,然后,  
        ///           分别对2个子集合进行排序,最终将排好序的子集合合并成为所要求的排好序的集合.    
        /// 核心算法时间复杂度:     
        ///           T(n)=O(nlogn)  
        /// </summary>  
        /// <param name="Array"></param>  
        /// <param name="left"></param>  
        /// <param name="right"></param>  
        public void RecursiveMergeSort(int[] Array, int left, int right)  
        {  
            int middle = (left + right) / 2;  
  
            if (left < right)  
            {  
                //对前半部分递归拆分  
                RecursiveMergeSort(Array, left, middle);  
                //对后半部分递归拆分  
                RecursiveMergeSort(Array, middle + 1, right);  
                MergeOne(Array, left, middle, right);  
            }  
        }  
        public void MergeOne(int[] Array, int left, int middle, int right)  
        {  
            int leftindex = left;  
            int rightindex = middle + 1;  
            //动态临时二维数组存放分割为两个小Array的数组排列顺序后的数据  
            int[] merge = new int[right + 1];  
            int index = 0;  
            //对两个小数组合并排序  
            while (leftindex <= middle && rightindex <= right)  
                merge[index++] = (Array[leftindex] - Array[rightindex]) >= 0 ? Array[rightindex++] : Array[leftindex++];  
            //有一侧子数列遍历完后,将另外一侧子数列剩下的数依次放入暂存数组中(有序)  
            if (leftindex <= middle)  
            {  
                for (int i = leftindex; i <= middle; i++)  
                    merge[index++] = Array[i];  
            }  
            if (rightindex <= right)  
            {  
                for (int i = rightindex; i <= right; i++)  
                    merge[index++] = Array[i];  
            }  
            //将有序的数列 写入目标数组 ,即原来把Array数组分为两个小Array数组后重新有序组合起来(覆盖原数组)  
            index = 0;  
            for (int i = left; i <= right; i++)  
                Array[i] = merge[index++];  
        }  
  
        /// <summary>  
        /// 归并排序(非递归)  
        ///     核心思想:(分治)  
        ///           对n个数的数列每相邻两个元素排序,组成n/2个或(n+1)/2个子数组,单个的不比了直接进入下一轮。  
        ///     然后对每个相邻的子数组再排序,以此类推最后得到排好序的数列   
        ///  forexample:  59 35 54 28 52   
        ///   排序And分:  35 59. 28 54. 52  
        ///   排序And分:  28 35 54 59. 52  
        ///        结果:  28 35 52 54 59  
        /// 核心算法时间复杂度:     
        ///           T(n)=O(nlogn)  
        /// </summary>  
        /// <param name="Array"></param>  
        public void MergeSort(int[] Array)  
        {  
            //index固定的数组  
            int[] merge = new int[Array.Length];  
            int P = 0;  
            while (true)  
            {  
                int index = 0;  
                //子数组元素的个数  
                int ENumb = (int)Math.Pow(2, P);  
                //一个子数组中的元素个数与数组的一半元素个数比较大小  
                //最糟糕的情况最右边的数组只有一个元素  
                if (ENumb < Array.Length)  
                {  
                    while (true)  
                    {  
                        int TorFAndrightindex = index;  
                        //最后一个子数组的第一个元素的index与数组index相比较  
                        if (TorFAndrightindex <= Array.Length - 1)  
                            MergeTwo(Array, merge, index, ENumb);  
                        else  
                            break;  
                        index += 2 * ENumb;  
                    }  
                }  
                else  
                    break;  
                P++;  
            }  
        }  
        public void MergeTwo(int[] Array, int[] merge, int index, int ENumb)  
        {  
            //换分两个子数组的index(千万不能用middle = (right + left) / 2划分)  
            // 1  
            int left = index;  
            int middle = left + ENumb - 1;  
            //(奇数时)  
            //排除middleindex越界  
            if (middle >= Array.Length)  
            {  
                middle = index;  
            }  
            //同步化merge数组的index  
            int mergeindex = index;  
            // 2  
            int right;  
            int middleTwo = (index + ENumb - 1) + 1;  
            right = index + ENumb + ENumb - 1;  
            //排除最后一个子数组的index越界.  
            if (right >= Array.Length - 1)  
            {  
                right = Array.Length - 1;  
            }  
            //排序两个子数组并复制到merge数组  
            while (left <= middle && middleTwo <= right)  
            {  
                merge[mergeindex++] = Array[left] >= Array[middleTwo] ? Array[middleTwo++] : Array[left++];  
            }  
            //两个子数组中其中一个比较完了(Array[middleTwo++] 或Array[left++]),  
            //把其中一个数组中剩下的元素复制进merge数组。  
            if (left <= middle)  
            {  
                //排除空元素.  
                while (left <= middle && mergeindex < merge.Length)  
                    merge[mergeindex++] = Array[left++];  
            }  
            if (middleTwo <= right)  
            {  
                while (middleTwo <= right)  
                    merge[mergeindex++] = Array[middleTwo++];  
            }  
            //判断是否合并至最后一个子数组了  
            if (right + 1 >= Array.Length)  
                Copy(Array, merge);  
        }  
  
        /// <summary>  
        /// 自然归并排序:  
        ///      对于初始给定的数组,通常存在多个长度大于1的已自然排好序的子数组段.  
        /// 例如,若数组a中元素为{4,8,3,7,1,5,6,2},则自然排好序的子数组段  
        /// 有{4,8},{3,7},{1,5,6},{2}.  
        /// 用一次对数组a的线性扫描就足以找出所有这些排好序的子数组段.  
        /// 然后将相邻的排好序的子数组段两两合并,  
        /// 构成更大的排好序的子数组段({3,4,7,8},{1,2,5,6}).  
        /// 继续合并相邻排好序的子数组段,直至整个数组已排好序.  
        /// 核心算法时间复杂度:  
        ///        T(n)=○(n);  
        /// </summary>  
        public void NaturalMergeSort(int[] Array)  
        {  
            //得到自然划分后的数组的index组(每行为一个自然子数组)  
            int[,] PointsSymbol = LinearPoints(Array);  
            //子数组只有一个。  
            if (PointsSymbol[0, 1] == Array.Length - 1)  
                return;  
            //多个(至少两个子数组)...  
            else  
                //可以堆栈调用吗?  
                NaturalMerge(Array, PointsSymbol);  
  
        }  
        public void NaturalMerge(int[] Array, int[,] PointsSymbol)  
        {  
            int left;  
            int right;  
            int leftend;  
            int rightend;  
  
            mergerows = GNumberTwo(Groups);  
            CopyGroups = Groups;  
            //固定状态  
            int[] TempArray = new int[Array.Length];  
            //循环取每个自然子数组的index  
            while (true)  
            {  
                // int Temprow = 1;  
                //只记录合并后的子数组(”《应该为》“动态的)    
                int[,] TempPointsSymbol = new int[mergerows, 2];  
  
                int row = 0;  
                do  
                {  
                    //最重要的判断:最后(一组子数组)是否可配对  
                    if (row != CopyGroups - 1)  
                    { //以上条件也可以含有(& 和&&的区别)短路运算  
                        //参考:http://msdn.microsoft.com/zh-cn/library/2a723cdk(VS.80).aspx  
                        left = PointsSymbol[row, 0];  
                        leftend = PointsSymbol[row, 1];  
                        right = PointsSymbol[row + 1, 0];  
                        rightend = PointsSymbol[row + 1, 1];  
                        MergeThree(Array, TempArray, left, leftend, right, rightend);  
                        MergePointSymbol(PointsSymbol, TempPointsSymbol, row);  
                    }  
                    else  
                    {  
                        ////默认剩下的单独一个子数组已经虚拟合并。然后Copy进TempArray。  
                        int TempRow = PointsSymbol[row, 0];  
                        int TempCol = PointsSymbol[row, 1];  
                        while (TempRow <= TempCol)  
                            TempArray[TempRow] = Array[TempRow++];  
                        //TempPointSymbol完整同步  
                        TempPointsSymbol[row / 2, 0] = PointsSymbol[row, 0];  
                        TempPointsSymbol[row / 2, 1] = PointsSymbol[row, 1];  
                        break;//重新开始新一轮循环。  
                    }  
                    row += 2;  
                    // Temprow++;  
                    //合并到只有一个子数组时结束循环  
                    if (TempPointsSymbol[0, 1] == Array.Length - 1)  
                        break;  
                }//判断别进入越界循环(可以进孤单循环)这里指的是PointsSymbol的子数组个数  
                while (row <= CopyGroups - 1);  
                //  
                Copy(Array, TempArray);  
                //更新子数组index,row为跳出循环的条件(最后单个子数组或下一个越界的第一个)  
                UpdatePointSymbol(PointsSymbol, TempPointsSymbol, row);  
                //改变TempPointsSymbol的行数(合并后子数组数)  
                mergerows = GNumber(mergerows);  
                CopyGroups = GNumberTwo(CopyGroups);  
                //合并到只有一个子数组时结束循环  
                if (PointsSymbol[0, 1] == Array.Length - 1)  
                    break;  
            }  
            //输出  
        }  
        public int GNumber(int Value)  
        {  
            if (Value % 2 == 0)  
                Value /= 2;  
            else  
                Value -= 1;  
  
            return Value;  
        }  
        public int GNumberTwo(int Value)  
        {  
            if (Value % 2 == 0)  
                mergerows = Value / 2;  
            else  
                mergerows = Value / 2 + 1;  
            return mergerows;  
        }  
        public void MergeThree(int[] Array, int[] Temp, int left, int leftend, int right, int rightend)  
        {  
            //合并语句  
            int index = left;  
            while (left <= leftend && right <= rightend)  
                Temp[index++] = Array[left] >= Array[right] ? Array[right++] : Array[left++];  
            while (left <= leftend)  
                Temp[index++] = Array[left++];  
            while (right <= rightend)  
                Temp[index++] = Array[right++];  
        }  
        public void MergePointSymbol(int[,] PointsSymbol, int[,] TempPointsSymbol, int row)  
        {  
            int rowindex = row / 2;  
            TempPointsSymbol[rowindex, 0] = PointsSymbol[row, 0];  
            TempPointsSymbol[rowindex, 1] = PointsSymbol[row + 1, 1];  
        }  
        public void UpdatePointSymbol(int[,] PointsSymbol, int[,] TempPointsSymbol, int rows)  
        {  
            int row = 0;  
            //if (mergerows % 2 == 0)  
            //{  
            for (; row < TempPointsSymbol.GetLength(0); row++)  
            {  
                for (int col = 0; col < 2; col++)  
                    PointsSymbol[row, col] = TempPointsSymbol[row, col];  
            }  
            //后面的清零  
            for (; row < PointsSymbol.GetLength(0); row++)  
            {  
                for (int col2 = 0; col2 < 2; col2++)  
                    PointsSymbol[row, col2] = 0;  
            }  
            //}  
            ////补剩下的index组,  
            //else  
            //{  
            //    for (int row2 = 0; row2 < TempPointsSymbol.GetLength(0); row2++)  
            //    {  
            //        for (int col3 = 0; col3 < 2; col3++)  
            //            PointsSymbol[row2, col3] = TempPointsSymbol[row2, col3];  
            //    }  
            //    //最后一个子数组的index只有一个。  
            //    int row3 = TempPointsSymbol.GetLength(0);  
            //    PointsSymbol[row3, 0] = PointsSymbol[rows, 0];  
            //    PointsSymbol[row3, 1] = PointsSymbol[rows, 1];  
            //    //后面的清零  
            //    for (int row4 = row3 + 1; row4 < PointsSymbol.GetLength(0); row4++)  
            //    {  
            //        for (int col4 = 0; col4 < 2; col4++)  
            //            PointsSymbol[row4, col4] = 0;  
            //    }  
            //}  
  
        }  
        public int[,] LinearPoints(int[] Array)  
        {  
            Groups = 1;  
            int StartPoint = 0;  
            int row = 0;  
            int col = 0;  
            //最糟糕的情况就是有Array.Length行。  
            int[,] PointsSet = new int[Array.Length, 2];  
            //线性扫描Array,划分数组  
            //初始前index=0  
            PointsSet[row, col] = 0;  
            do  
            {  
                //判断升序子数组最终的index开关  
                bool Judge = false;  
                //从Array第二个数判断是否要结束或者是否是升序子数组.  
                while (++StartPoint < Array.Length && Array[StartPoint] < Array[StartPoint - 1])  
                {  
                    //打开第一个升序子数组结束的index开关  
                    Judge = true;  
                    //重新开始第二个升序子数组的前index  
                    PointsSet[row, col + 1] = StartPoint - 1;  
                    //计算子数组个数  
                    Groups++;  
                    //换行记录自然子数组的index  
                    row++;  
                    break;  
                    //--StartPoint;  
                }  
                //升序子数组结束index  
                if (Judge)  
                    PointsSet[row, col] = StartPoint;  
                //else  
                //    --StartPoint;  
            } while (StartPoint < Array.Length);  
            //最终index=StartPoint - 1,但是糟糕情况下还有剩余若干行为: 0,0 ...  
            PointsSet[row, col + 1] = StartPoint - 1;  
            //调用展示方法             
            DisplaySubarray(Array, PointsSet, Groups);  
            return PointsSet;  
        }  
        public void DisplaySubarray(int[] Array, int[,] PointsSet, int Groups)  
        {  
            Console.WriteLine("Subarray is {0}:", Groups);  
            //展示子数组的前后index  
            for (int r = 0; r < Groups; r++)  
            {  
                for (int c = 0; c < PointsSet.GetLength(1); c++)  
                {  
                    Console.Write(PointsSet[r, c]);  
                    if (c < PointsSet.GetLength(1) - 1)  
                        Console.Write(",");  
                }  
                Console.Write("\t\t");  
            }  
            Console.WriteLine();  
            //展示分出的子数组  
            for (int v = 0; v < Groups; v++)  
            {  
                int i = 1;  
                for (int r = PointsSet[v, 0]; r <= PointsSet[v, 1]; r++)  
                {  
                    Console.Write(Array[r] + " ");  
                    i++;  
                }  
                if (i <= 3)  
                    Console.Write("\t\t");  
                else  
                    Console.Write("\t");  
                if (PointsSet[v, 1] == Array.Length)  
                    break;  
            }  
        }  
  
        public void Copy(int[] Array, int[] merge)  
        {  
            //一部分排好序的元素替换掉原来Array中的元素  
            for (int i = 0; i < Array.Length; i++)  
            {  
                Array[i] = merge[i];  
            }  
        }  
        //输出  
        public override string ToString()  
        {  
            string temporary = string.Empty;  
  
            foreach (var element in Array27)  
                temporary += element + " ";  
  
            temporary += "\n";  
            return temporary;  
        }  
    }  
  
  
    class Program  
    {  
        static void Main(string[] args)  
        {  
            while (true)  
            {  
                Console.WriteLine("请选择:");  
                Console.WriteLine("1.归并排序(非递归)");  
                Console.WriteLine("2.归并排序(递归)");  
                Console.WriteLine("3.归并排序(自然合并)");  
                Console.WriteLine("4.退出");  
                int Arraynum = Convert.ToInt32(Console.ReadLine());  
                switch (Arraynum)  
                {  
                    case 4:  
                        Environment.Exit(0);  
                        break;  
                    case 1:  
                        Console.WriteLine("Please Input Array Length");  
                        int Leng271 = Convert.ToInt32(Console.ReadLine());  
                        Function obj1 = new Function(Leng271);  
  
                        Console.WriteLine("The original sequence:");  
                        Console.WriteLine(obj1);  
                        Console.WriteLine("'MergeSort' Finaly Sorting Result:");  
                        obj1.ToMergeSort();  
                        Console.WriteLine(obj1);  
                        break;  
                    case 2:  
                        Console.WriteLine("Please Input Array Length");  
                        int Leng272 = Convert.ToInt32(Console.ReadLine());  
                        Function obj2 = new Function(Leng272);  
  
                        Console.WriteLine("The original sequence:");  
                        Console.WriteLine(obj2);  
                        Console.WriteLine("'RecursiveMergeSort' Finaly Sorting Result:");  
                        obj2.ToRecursiveMergeSort();  
                        Console.WriteLine(obj2);  
                        break;  
                    case 3:  
                        Console.WriteLine("Please Input Array Length");  
                        int Leng273 = Convert.ToInt32(Console.ReadLine());  
                        Function obj3 = new Function(Leng273);  
  
                        Console.WriteLine("The original sequence:");  
                        Console.WriteLine(obj3);  
                        obj3.ToNaturalMergeSort();  
                        Console.WriteLine(); Console.WriteLine();  
                        Console.WriteLine("'NaturalMergeSort' Finaly Sorting Result:");  
                        Console.WriteLine(obj3);  
                        break;  
                }  
            }  
        }  
    }  
}  

7.基数排序

using System;  
using System.Collections.Generic;  
using System.Linq;  
using System.Text;  
  
namespace Merge  
{  
    public class RadixSorter  
    {  
        //基数排序  
        public int[] RadixSort(int[] ArrayToSort, int digit)  
        {  
            //low to high digit  
            for (int k = 1; k <= digit; k++)  
            {  
                //temp array to store the sort result inside digit  
                int[] tmpArray = new int[ArrayToSort.Length];  
                //temp array for countingsort  
                int[] tmpCountingSortArray = new int[10] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };  
                //CountingSort  
                for (int i = 0; i < ArrayToSort.Length; i++)  
                {  
                    //split the specified digit from the element  
                    int tmpSplitDigit = ArrayToSort[i] / (int)Math.Pow(10, k - 1) - (ArrayToSort[i] / (int)Math.Pow(10, k)) * 10;  
                    tmpCountingSortArray[tmpSplitDigit] += 1;  
                }  
                for (int m = 1; m < 10; m++)  
                {  
                    tmpCountingSortArray[m] += tmpCountingSortArray[m -  
                    1];  
                }  
                //output the value to result  
                for (int n = ArrayToSort.Length - 1; n >= 0; n--)  
                {  
                    int tmpSplitDigit = ArrayToSort[n] / (int)Math.Pow(10, k - 1) -  
                    (ArrayToSort[n] / (int)Math.Pow(10, k)) * 10;  
                    tmpArray[tmpCountingSortArray[tmpSplitDigit] - 1] = ArrayToSort  
                    [n];  
                    tmpCountingSortArray[tmpSplitDigit] -= 1;  
                }  
                //copy the digit-inside sort result to source array  
                for (int p = 0; p < ArrayToSort.Length; p++)  
                {  
                    ArrayToSort[p] = tmpArray[p];  
                }  
            }  
            return ArrayToSort;  
        }  
    }  
  
    class Program  
    {  
        static void Main(string[] args)  
        {  
            int[] intArray = new int[] { 5, 3, 7, 4, 8, 2, 9, 1, 0, 6 };  
            int[] newIntArray = intArray;  
            RadixSorter rS=new RadixSorter();  
            newIntArray = rS.RadixSort(intArray, intArray.Length);  
            foreach (int i in intArray)  
            {  
                Console.Write(i + " ");  
            }  
            Console.ReadKey();  
        }  
    }  
}  

8. 计数排序

using System;  
using System.Collections.Generic;  
using System.Linq;  
using System.Text;  
  
namespace Merge  
{  
    class Program  
    {  
        /// <summary>  
        /// 计数排序。  
        /// 要求:  
        ///     arrayToSort的元素必须大于等于0,或者经过一定的转换使其元素在  
        ///     大于等于0范围内。例如有如下序列(-1,-8,10,11),那么根据最小值8,  
        ///     将各个数字加8转化为(7,0,18,19),然后进行计数排序,结果为(0,7,18,19),  
        ///     然后再将结果个数字减8即为(-8,-1,10,11)  
        /// </summary>  
        /// <param name="arrayToSort">要排序的数组</param>  
        /// <param name="maxValue">数组的最大值加一</param>  
        /// <returns>计数排序后的结果</returns>  
        public static int[] CountingSort(int[] arrayToSort, int k)  
        {  
            // 排序后的结果存储  
            int[] sortedArray = new int[arrayToSort.Length];  
            // 计数数组  
            int[] countingArray = new int[k];  
            // 计数数组初始化  
            for (int i = 0; i < countingArray.Length; i++)  
            {  
                countingArray[i] = 0;  
            }  
  
            // 单个元素计数(经过该步骤countingArray[i]的含义为数字i的个数为countingArray[i])  
            for (int i = 0; i < arrayToSort.Length; i++)  
            {  
                countingArray[arrayToSort[i]] = countingArray[arrayToSort[i]] + 1;  
            }  
            // 计算小于等于某数的个数(经过该步骤countingArray[i]的含义为小于等于数字i的元素个数为countingArray[i])  
            for (int i = 1; i < countingArray.Length; i++)  
            {  
                countingArray[i] += countingArray[i - 1];  
            }  
  
            // 得到排序后的结果  
            for (int i = 0; i < sortedArray.Length; i++)  
            {  
                int numIndex = countingArray[arrayToSort[i]] - 1;  
                sortedArray[numIndex] = arrayToSort[i];  
                countingArray[arrayToSort[i]] = countingArray[arrayToSort[i]] - 1;  
            }  
  
            return sortedArray;  
        }  
  
        static void Main(string[] args)  
        {  
            int[] intArray = new int[] { 5, 3, 7, 4, 8, 2, 9, 1, 0, 6 };  
            int[] intNewArray = intArray;  
            intNewArray = CountingSort(intArray, intArray.Length);  
            foreach (int i in intNewArray)  
            {  
                Console.Write(i + " ");  
            }  
            Console.ReadKey();  
        }  
    }  
}  

9.堆排序

using System;  
using System.Collections.Generic;  
using System.Linq;  
using System.Text;  
  
namespace Merge  
{  
    class Program  
    {  
        //堆排序算法(传递待排数组名,即:数组的地址。故形参数组的各种操作反应到实参数组上)  
        private static void HeapSortFunction(int[] array)  
        {  
            try  
            {  
                BuildMaxHeap(array);    //创建大顶推(初始状态看做:整体无序)  
                for (int i = array.Length - 1; i > 0; i--)  
                {  
                    Swap(ref array[0], ref array[i]); //将堆顶元素依次与无序区的最后一位交换(使堆顶元素进入有序区)  
                    MaxHeapify(array, 0, i); //重新将无序区调整为大顶堆  
                }  
            }  
            catch (Exception ex)  
            {  
                Console.Write(ex.Message);  
            }  
        }  
  
        ///<summary>  
        /// 创建大顶推(根节点大于左右子节点)  
        ///</summary>  
        ///<param name="array">待排数组</param>  
        private static void BuildMaxHeap(int[] array)  
        {  
            try  
            {  
                //根据大顶堆的性质可知:数组的前半段的元素为根节点,其余元素都为叶节点  
                for (int i = array.Length / 2 - 1; i >= 0; i--) //从最底层的最后一个根节点开始进行大顶推的调整  
                {  
                    MaxHeapify(array, i, array.Length); //调整大顶堆  
                }  
            }  
            catch (Exception ex)  
            {  
                Console.Write(ex.Message);  
            }  
        }  
  
        ///<summary>  
        /// 大顶推的调整过程  
        ///</summary>  
        ///<param name="array">待调整的数组</param>  
        ///<param name="currentIndex">待调整元素在数组中的位置(即:根节点)</param>  
        ///<param name="heapSize">堆中所有元素的个数</param>  
        private static void MaxHeapify(int[] array, int currentIndex, int heapSize)  
        {  
            try  
            {  
                int left = 2 * currentIndex + 1;    //左子节点在数组中的位置  
                int right = 2 * currentIndex + 2;   //右子节点在数组中的位置  
                int large = currentIndex;   //记录此根节点、左子节点、右子节点 三者中最大值的位置  
  
                if (left < heapSize && array[left] > array[large])  //与左子节点进行比较  
                {  
                    large = left;  
                }  
                if (right < heapSize && array[right] > array[large])    //与右子节点进行比较  
                {  
                    large = right;  
                }  
                if (currentIndex != large)  //如果 currentIndex != large 则表明 large 发生变化(即:左右子节点中有大于根节点的情况)  
                {  
                    Swap(ref array[currentIndex], ref array[large]);    //将左右节点中的大者与根节点进行交换(即:实现局部大顶堆)  
                    MaxHeapify(array, large, heapSize); //以上次调整动作的large位置(为此次调整的根节点位置),进行递归调整  
                }  
            }  
            catch (Exception ex)  
            {  
                Console.Write(ex.Message);  
            }  
        }  
  
        ///<summary>  
        /// 交换函数  
        ///</summary>  
        ///<param name="a">元素a</param>  
        ///<param name="b">元素b</param>  
        private static void Swap(ref int a, ref int b)  
        {  
            int temp = 0;  
            temp = a;  
            a = b;  
            b = temp;  
        }  
  
        static void Main(string[] args)  
        {  
            int[] intArray = new int[] { 5, 3, 7, 4, 8, 2, 9, 1, 0, 6 };  
            HeapSortFunction(intArray);  
            foreach (int i in intArray)  
            {  
                Console.Write(i + " ");  
            }  
            Console.ReadKey();  
        }  
    }  
}  

排序的分类/稳定性/时间复杂度和空间复杂度总结





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值