C# 经典排序算法大全

C# 经典排序算法大全

大家好,又见面了,我是全栈君,今天给大家准备了Idea注册码。

C# 经典排序算法大全

选择排序

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace sorter
{
    public class SelectionSorter
    {
        private int min;
        public void Sort(int[] arr)
        {
            for (int i = 0; i < arr.Length - 1; ++i)
            {
                min = i;
                for (int j = i + 1; j < arr.Length; ++j)
                {
                    if (arr[j] < arr[min])
                    {
                        min = j;
                    }
                }
                int t = arr[min];
                arr[min] = arr[i];
                arr[i] = t;
            }
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            int[] arrInt = new int[] { 4, 2, 7, 1, 8, 3, 9, 0, 5, 6 };
            SelectionSorter selSor = new SelectionSorter();
            selSor.Sort(arrInt);
            foreach (int i in arrInt)
            {
                Console.WriteLine(i);
            }
            Console.ReadKey();
        }
    }
}

冒泡排序

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace sorter
{
    public class EbullitionSorter
    {
        public void Sort(int[] arr)
        {
            int i, j, temp;
            bool done = false;
            j = 1;
            while ((j < arr.Length) && (!done))  // 推断长度
            {
                done = true;
                for (i = 0; i < arr.Length - j; i++)
                {
                    if (arr[i] > arr[i + 1])
                    {
                        done = false;
                        temp = arr[i];
                        arr[i] = arr[i + 1]; // 交换数据
                        arr[i + 1] = temp;
                    }
                }
                j++;
            }
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            int[] arrInt = new int[] { 4, 2, 7, 1, 8, 3, 9, 0, 5, 6 };
            EbullitionSorter selSor = new EbullitionSorter();
            selSor.Sort(arrInt);
            foreach (int i in arrInt)
            {
                Console.WriteLine(i);
            }
            Console.ReadKey();
        }
    }
}

高速排序

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace sorter
{
    public class QuickSorter
    {
        private void swap(ref int l, ref int r)
        {
            int temp;
            temp = l;
            l = r;
            r = temp;
        }

        public void Sort(int[] list, int low, int high)
        {
            int pivot; // 存储分支点
            int l, r;
            int mid;
            if (high <= low)
            {
                return;
            }
            else if (high == low + 1)
            {
                if (list[low] > list[high])
                {
                    swap(ref list[low], ref list[high]);
                }
                return;
            }
            mid = (low + high) >> 1;
            pivot = list[mid];
            swap(ref list[low], ref list[mid]);
            l = low + 1;
            r = high;
            do
            {
                while (l <= r && list[l] < pivot)
                {
                    l++;
                }
                while (list[r] >= pivot)
                {
                    r--;
                }
                if (l < r)
                {
                    swap(ref list[l], ref list[r]);
                }
            } while (l < r);
            list[low] = list[r];
            list[r] = pivot;
            if (low + 1 < r)
            {
                Sort(list, low, r - 1);
            }
            if (r + 1 < high)
            {
                Sort(list, r + 1, high);
            }
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            int[] arrInt = new int[] { 4, 2, 7, 1, 8, 3, 9, 0, 5, 6 };
            QuickSorter selSor = new QuickSorter();
            selSor.Sort(arrInt, 0, arrInt.Length - 1);
            foreach (int i in arrInt)
            {
                Console.WriteLine(i);
            }
            Console.ReadKey();
        }
    }
}

插入排序

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace sorter
{
    public class InsertionSorter
    {
        public void Sort(int[] arr)
        {
            for (int i = 1; i < arr.Length; i++)
            {
                int t = arr[i];
                int j = i;
                while ((j > 0) && (arr[j - 1] > t))
                {
                    arr[j] = arr[j - 1]; // 交换顺序
                    --j;
                }
                arr[j] = t;
            }
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            int[] arrInt = new int[] { 4, 2, 7, 1, 8, 3, 9, 0, 5, 6 };
            InsertionSorter selSor = new InsertionSorter();
            selSor.Sort(arrInt);
            foreach (int i in arrInt)
            {
                Console.WriteLine(i);
            }
            Console.ReadKey();
        }
    }
}

希尔排序

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace sorter
{
    public class ShellSorter
    {
        public void Sort(int[] arr)
        {
            int inc;
            for (inc = 1; inc <= arr.Length / 9; inc = 3 * inc + 1) ;
            for (; inc > 0; inc /= 3)
            {
                for (int i = inc + 1; i <= arr.Length; i += inc)
                {
                    int t = arr[i - 1];
                    int j = i;
                    while ((j > inc) && (arr[j - inc - 1] > t))
                    {
                        arr[j - 1] = arr[j - inc - 1]; // 交换数据
                        j -= inc;
                    }
                    arr[j - 1] = t;
                }
            }
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            int[] arrInt = new int[] { 4, 2, 7, 1, 8, 3, 9, 0, 5, 6 };
            ShellSorter selSor = new ShellSorter();
            selSor.Sort(arrInt);
            foreach (int i in arrInt)
            {
                Console.WriteLine(i);
            }
            Console.ReadKey();
        }
    }
}

归并排序

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

基数排序

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

计数排序

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

堆排序

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

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

C# 经典排序算法大全


版权声明:本文博客原创文章。博客,未经同意,不得转载。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/117527.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)


相关推荐

  • 男生pun是什么意思_pun怎么读

    男生pun是什么意思_pun怎么读PUN介绍入门PhotonUnityNetworking(首字母缩写PUN)是一个Unity多人游戏插件包。它提供了身份验证选项、匹配,以及快速、可靠的通过我们的Photon后端实现的游戏内通

  • 超级搜索术

    超级搜索术WeixinSogouSearchZhihuSogouSearch

  • RecycleView 获取第一个可见条目(掉坑篇)

    RecycleView 获取第一个可见条目(掉坑篇)

  • 关于机械臂的模仿学习

    关于机械臂的模仿学习文章目录1.关键词2.数据集3.框架4.大会/论坛5.相关论文1.关键词模仿学习:Imitationlearning2.数据集图像识别领域的数据集:ImageNet目标检测的数据集:COCO机器问答的数据集:SQuAD3.框架斯坦福的李飞飞实验室,开源了分布式强化学习训练框架SURREAL,用来加速学习过程。团队还发现,用SURREAL框架搭配上文的RoboTurk…

  • apache基于域名虚拟主机配置_php配置虚拟主机

    apache基于域名虚拟主机配置_php配置虚拟主机一、apache虚拟主机的配置1、首先在apache的安装目录下找到conf目录下找到httpd.conf文件然后搜索hosts找到把前面的井号去掉即可启动虚拟主机2、然后在apache的安装目录下找到conf目录下的extra找到httpd-vhosts.conf文件在文件最后添加类似我下面的配置,详细参数见说明我这里以myvirtualho

  • 线程池参数及配置「建议收藏」

    线程池参数及配置「建议收藏」线程池-线程池参数及配置在实际项目中线程的应用都会使用线程池来管理,线程池的常用参数及配置学习记录。目录线程池-线程池参数及配置一、线程池在面向对象编程中,创建和销毁对象是很费时间的,因为创建一个对象要获取内存资源或者其它更多资源。在Java中更是如此,虚拟机将试图跟踪每一个对象,以便能够在对象销毁后进行垃圾回收。所以提高服务程序效率的一个手段就是尽可能减少创建和销毁对象的次数,特别是一些很耗资源的对象创建和销毁。如果并发的线程数多,并且每个线程都是…

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号