常见排序算法的C#实现
生活随笔
收集整理的這篇文章主要介紹了
常见排序算法的C#实现
小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
排序算法常見(jiàn)的有直接排序、冒泡排序、快速排序、基數(shù)排序、歸并排序等,下面是實(shí)現(xiàn)的代碼,僅供參考。
#region DirectSort/// <summary>/// 直接排序./// 第一次從R[0]~R[n-1]中選取最小值,與R[0]交換,/// 第二次從R[1]~R[n-1]中選取最小值,與R[1]交換,....,/// 第i次從R[i-1]~R[n-1]中選取最小值,與R[i-1]交換,.....,/// 第n-1次從R[n-2]~R[n-1]中選取最小值,與R[n-2]交換,/// 總共通過(guò)n-1次,得到一個(gè)按排序碼從小到大排列的有序序列·/// </summary>/// <param name="data"></param>/// <returns></returns>private static int DirectSort(int[] data){int min = 0;int k = 0;int count = 0;for (int i = 0; i < data.Length; i++){min = data[i];k = i;for (int j = i; j < data.Length; j++){if (min > data[j]){min = data[j];k = j;}count++;}data[k] = data[i];data[i] = min;}return count;}#endregion#region BubbleSort/// <summary>/// 冒泡排序./// 重復(fù)地走訪過(guò)要排序的數(shù)列,一次比較兩個(gè)元素,/// 如果他們的順序錯(cuò)誤就把他們交換過(guò)來(lái)。/// 走訪數(shù)列的工作是重復(fù)地進(jìn)行直到?jīng)]有再需要交換,/// 也就是說(shuō)該數(shù)列已經(jīng)排序完成。/// 這個(gè)算法的名字由來(lái)是因?yàn)樵酱蟮脑貢?huì)經(jīng)由交換慢慢“浮”到數(shù)列的頂端,故名。/// </summary>/// <param name="data"></param>private static int BubbleSort(int[] data){int min = 0;int count = 0;for (int i = 0; i < data.Length; i++){for (int j = 0; j < data.Length - 1 - i; j++){if (data[j] > data[j + 1]){min = data[j + 1];data[j + 1] = data[j];data[j] = min;}count++;}}return count;}#endregion#region QuickSort/// <summary>/// 快速排序./// 通過(guò)一趟排序?qū)⒁判虻臄?shù)據(jù)分割成獨(dú)立的兩部分,/// 其中一部分的所有數(shù)據(jù)都比另外一部分的所有數(shù)據(jù)都要小,/// 然后再按此方法對(duì)這兩部分?jǐn)?shù)據(jù)分別進(jìn)行快速排序,/// 整個(gè)排序過(guò)程可以遞歸進(jìn)行,以此達(dá)到整個(gè)數(shù)據(jù)變成有序序列。/// </summary>/// <param name="data"></param>/// <returns></returns>private static int QuickSort(int[] data){int count = 0;QuickSortInner(data, 0, data.Length - 1, ref count);return count;}private static void QuickSortInner(int[] data, int left, int right, ref int count){if (left >= right) { return; }//完成一次單元排序int middle = QuickSortUnit(data, left, right, ref count);//對(duì)左邊單元進(jìn)行排序QuickSortInner(data, left, middle - 1, ref count);//對(duì)右邊單元進(jìn)行排序QuickSortInner(data, middle + 1, right, ref count);}private static int QuickSortUnit(int[] data, int left, int right, ref int count){int key = data[left];while (left < right){//自右端向左端查找小于key的值for (; ; right--){if (data[right] < key || right <= left){//右邊有小于key的值,直接將該值放到左邊,//此時(shí)right位置的空間空出,留作放置從左邊比較出的大于key的值。//如果右索引已經(jīng)到達(dá)了左邊,right==left,data[left] = data[right]是同數(shù)據(jù)交換,不受影響.data[left] = data[right];count++;break;}}//自左端向右端查找大于key的值for (; ; left++){if (data[left] > key || left >= right){//左邊有大于key的值,直接將該值放到右邊,//此時(shí)left位置的空間空出,留作放置從右邊比較出的小于key的值,或者用來(lái)最后放置key.//如果左索引已經(jīng)到達(dá)了右邊,left==right,data[right] = data[left]是同數(shù)據(jù)交換,不受影響.data[right] = data[left];count++;break;}}}data[left] = key;return right;}#endregion#region RadixSort/// <summary>/// 基數(shù)排序(此處采用LSD法)./// 屬于“分配式排序”(distribution sort),又稱(chēng)“桶子法”(bucket sort)或bin sort,/// 顧名思義,它是透過(guò)鍵值的部份資訊,將要排序的元素分配至某些“桶”中,藉以達(dá)到排序的作用,/// 基數(shù)排序法是屬于穩(wěn)定性的排序,其時(shí)間復(fù)雜度為O (nlog(r)m),其中r為所采取的基數(shù),而m為堆數(shù),/// 在某些時(shí)候,基數(shù)排序法的效率高于其它的穩(wěn)定性排序法。/// ==基數(shù)排序又分MSD和LSD。/// ==最高位優(yōu)先(Most Significant Digit first)法,簡(jiǎn)稱(chēng)MSD法:/// 先按k1排序分組,同一組中記錄,關(guān)鍵碼k1相等,再對(duì)各組按k2排序分成子組,/// 之后,對(duì)后面的關(guān)鍵碼繼續(xù)這樣的排序分組,直到按最次位關(guān)鍵碼kd對(duì)各子組排序后。/// 再將各組連接起來(lái),便得到一個(gè)有序序列。/// ==最低位優(yōu)先(Least Significant Digit first)法,簡(jiǎn)稱(chēng)LSD法:/// 先從kd開(kāi)始排序,再對(duì)kd-1進(jìn)行排序,依次重復(fù),直到對(duì)k1排序后便得到一個(gè)有序序列。/// </summary>/// <param name="data"></param>/// <returns></returns>private static int RadixSort(int[] data){var bucketList = new List<List<int>>();for (int i = 0; i < 10; i++){bucketList.Add(new List<int>());}int count = 0;int positionValue = 0;int maxPosition = 1;//計(jì)算最大位數(shù)for (int i = 0; i < data.Length; i++){var str = data[i].ToString();if (str.Length > maxPosition){maxPosition = str.Length;}}for (int position = 0; position < maxPosition; position++){//分桶for (int i = 0; i < data.Length; i++){positionValue = 0;var str = data[i].ToString();var index = (str.Length - 1) - position;// 計(jì)算出對(duì)應(yīng)位數(shù)的字符串的值if (index >= 0 && str.Length > index){positionValue = int.Parse(str.Substring(index, 1));}bucketList[positionValue].Add(data[i]);count++;}//合并桶int j = 0;foreach (var bucket in bucketList){foreach (var val in bucket){data[j++] = val;}//清空桶bucket.Clear();}}return count;}#endregion#region MergeSort/// <summary>/// 歸并排序./// 該算法是建立在歸并操作上的一種有效的排序算法,/// 該算法是采用分治法(Divide and Conquer)的一個(gè)非常典型的應(yīng)用。/// 將已有序的子序列合并,得到完全有序的序列;即先使每個(gè)子序列有序,再使子序列段間有序。/// 若將兩個(gè)有序表合并成一個(gè)有序表,稱(chēng)為二路歸并。/// ===歸并過(guò)程為:/// 比較a[i]和a[j]的大小,若a[i]≤a[j],則將第一個(gè)有序表中的元素a[i]復(fù)制到r[k]中,并令i和k分別加上1;/// 否則將第二個(gè)有序表中的元素a[j]復(fù)制到r[k]中,并令j和k分別加上1,如此循環(huán)下去,直到其中一個(gè)有序表取完,/// 然后再將另一個(gè)有序表中剩余的元素復(fù)制到r中從下標(biāo)k到下標(biāo)t的單元。/// 歸并排序的算法我們通常用遞歸實(shí)現(xiàn),先把待排序區(qū)間[s, t]以中點(diǎn)二分,接著把左邊子區(qū)間排序,/// 再把右邊子區(qū)間排序,最后把左區(qū)間和右區(qū)間用一次歸并操作合并成有序的區(qū)間[s, t]。/// </summary>/// <param name="data"></param>/// <returns></returns>private static int MergeSort(int[] data){int count = 0;MergeSortInner(data, 0, 1, ref count);return count;}/// <summary>/// 二路歸并./// 原理:將兩個(gè)有序表合并成一個(gè)有序表/// </summary>/// <param name="data"></param>/// <param name="firstStart">第一個(gè)有序表的起始下標(biāo)</param>/// <param name="secondStart">第二個(gè)有序表的起始下標(biāo)</param>/// <param name="secondTail">第二個(gè)有序表的結(jié)束下標(biāo)</param>private static void MergeSortUnit(int[] data, int firstStart, int secondStart, int secondTail, ref int count){int[] newArr = new int[secondTail - firstStart + 1];int firstIndex = firstStart, secondIndex = secondStart, newIndex = 0;while (firstIndex < secondStart && secondIndex <= secondTail){//自小而大合并到一個(gè)序列中if (data[firstIndex] <= data[secondIndex]){newArr[newIndex] = data[firstIndex++];}else{newArr[newIndex] = data[secondIndex++];}newIndex++;count++;}for (; firstIndex < secondStart; firstIndex++, newIndex++){newArr[newIndex] = data[firstIndex];count++;}for (; secondIndex <= secondTail; secondIndex++, newIndex++){newArr[newIndex] = data[secondIndex];count++;}Array.Copy(newArr, 0, data, firstStart, newArr.Length);}/// <summary>/// 歸并排序/// </summary>/// <param name="data"></param>/// <param name="firstStart">第一個(gè)序列的起始索引</param>/// <param name="len">每次歸并的有序集合的長(zhǎng)度</param>private static void MergeSortInner(int[] data, int firstStart, int len, ref int count){int size = data.Length;//歸并排序具體工作原理如下(假設(shè)序列共有n個(gè)元素)://將序列每相鄰兩個(gè)數(shù)字進(jìn)行歸并操作(merge),形成floor(n/2)個(gè)序列,排序后每個(gè)序列包含兩個(gè)元素//將上述序列再次歸并,形成floor(n/4)個(gè)序列,每個(gè)序列包含四個(gè)元素//將上述序列繼續(xù)歸并,形成floor(n/K)個(gè)序列(其中k為2的t次方),直到所有元素排序完畢。int k = len << 1;//新標(biāo)準(zhǔn)序列的組數(shù)int groupStandard = size / k;//除了標(biāo)準(zhǔn)序列外剩余的元素個(gè)數(shù)int leftElement = size % k; // size & (k - 1);//歸并到只剩一個(gè)有序集合的時(shí)候結(jié)束算法if (groupStandard == 0){return;}int secondStart = 0;int secondTail = 0;//進(jìn)行一趟歸并排序for (int i = 0; i < groupStandard; i++){firstStart = i * 2 * len;secondStart = firstStart + len;secondTail = (len << 1) + firstStart - 1;MergeSortUnit(data, firstStart, secondStart, secondTail, ref count);}//將剩下的數(shù)和倒數(shù)第一個(gè)有序集合歸并if (leftElement != 0){firstStart = size - leftElement - 2 * len;secondStart = size - leftElement;secondTail = size - 1;MergeSortUnit(data, firstStart, secondStart, secondTail, ref count);}//遞歸執(zhí)行下一趟歸并排序MergeSortInner(data, 0, 2 * len, ref count);}#endregion以上各排序算法的解釋主要來(lái)自于百度,僅供參考。 static void Main(string[] args){var data = new int[] { 123, 45, 21, 456, 98, 40, 32, 1435, 76, 485, 89, 876, 908, 345, 123 };Console.WriteLine(string.Join(",", data));//直接排序Console.WriteLine("=======直接排序======");var dataTemp = new int[data.Length];data.CopyTo(dataTemp, 0);var count = DirectSort(dataTemp);Console.WriteLine(count + "次=>" + string.Join(",", dataTemp));//冒泡排序Console.WriteLine("=======冒泡排序======");dataTemp = new int[data.Length];data.CopyTo(dataTemp, 0);count = BubbleSort(dataTemp);Console.WriteLine(count + "次=>" + string.Join(",", dataTemp));//快速排序Console.WriteLine("=======快速排序======");dataTemp = new int[data.Length];data.CopyTo(dataTemp, 0);count = QuickSort(dataTemp);Console.WriteLine(count + "次=>" + string.Join(",", dataTemp));//基數(shù)排序Console.WriteLine("=======基數(shù)排序======");dataTemp = new int[data.Length];data.CopyTo(dataTemp, 0);count = RadixSort(dataTemp);Console.WriteLine(count + "次=>" + string.Join(",", dataTemp));//歸并排序Console.WriteLine("=======歸并排序======");dataTemp = new int[data.Length];data.CopyTo(dataTemp, 0);count = MergeSort(dataTemp);Console.WriteLine(count + "次=>" + string.Join(",", dataTemp));Console.ReadLine();}輸出結(jié)果如下圖轉(zhuǎn)載請(qǐng)注明出處
轉(zhuǎn)載于:https://www.cnblogs.com/sparkleDai/p/7604908.html
總結(jié)
以上是生活随笔為你收集整理的常见排序算法的C#实现的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: Win11系统安装 WSA
- 下一篇: C# 委托 / 跨线程访问UI / 线