C#实现十大排序算法

using System; using System.Linq; using System.Collections.Generic; //by Alexander namespace Sort { class Program { static void Main(string[] args) { int[] myArray = new int[10] { 10, 6, 3, 4, 2, 7, 1, 5, 9, 8 }; // BubbleSort(myArray); // SelectionSort(myArray); // InsertionSort(myArray); // ShellSort(myArray); // QuickSort(myArray); // HeapSort(myArray); // CountSort(myArray); foreach (int element in myArray) { Console.Write("{0} ", element); } List<int> myList = new List<int>(10) { 10, 6, 3, 4, 2, 7, 1, 5, 9, 8 }; // List<int> newList = new List<int>(10) { 0 }; // BucketSort(myList, 3, 6); // newList = RecursiveSort(myList); RadixSort(myList); Console.WriteLine("\n"); foreach (int element in myList) { Console.Write("{0} ", element); } // foreach (int element in newList) // { // Console.Write("{0} ", element); // } } static void Swap(ref int x, ref int y) { int temp = x; x = y; y = temp; } ///冒泡排序 static void BubbleSort(int[] arr) { bool swapped; for (int i = 0; i < arr.Length; i++) { swapped = false; for (int j = 0; j < arr.Length - 1 - i; j++) if (arr[j] > arr[j + 1]) { Swap(ref arr[j], ref arr[j + 1]); if (!swapped) swapped = true; } if (!swapped) return; } } ///选择排序 static void SelectionSort(int[] arr) { int i, j, min, len = arr.Length; for (i = 0; i < len - 1; i++) { min = i; for (j = i + 1; j < len; j++) { if (arr[min].CompareTo(arr[j]) > 0) { min = j; } } Swap(ref arr[min], ref arr[i]); } } ///插入排序 static void InsertionSort(int[] arr) { for (int i = 1; i < arr.Length; i++) { int temp = arr[i]; for (int j = i - 1; j >= 0; j--) { if (arr[j] > temp) { arr[j + 1] = arr[j]; arr[j] = temp; } else break; } } } ///希尔排序 static void ShellSort(int[] arr) { int gap = 1; while (gap < arr.Length) { gap = gap * 3 + 1; } while (gap > 0) { for (int i = gap; i < arr.Length; i++) { int tmp = arr[i]; int j = i - gap; while (j >= 0 && arr[j] > tmp) { arr[j + gap] = arr[j]; j -= gap; } arr[j + gap] = tmp; } gap /= 3; } } ///递归排序 static List<int> RecursiveSort(List<int> list) { if (list.Count <= 1) { return list; } int mid = list.Count / 2; List<int> left = new List<int>(); // 定义左侧List List<int> right = new List<int>(); // 定义右侧List // 以下兩個循環把 lst 分為左右兩個 List for (int i = 0; i < mid; i++) { left.Add(list[i]); } for (int j = mid; j < list.Count; j++) { right.Add(list[j]); } left = RecursiveSort(left); right = RecursiveSort(right); return MergeSortedList(left, right); } /// <summary> /// 合併兩個已經排好序的List /// </summary> /// <param name="left">左側List</param> /// <param name="right">右側List</param> /// <returns></returns> static List<int> MergeSortedList(List<int> left, List<int> right) { List<int> temp = new List<int>(); while (left.Count > 0 && right.Count > 0) { if (left[0] <= right[0]) { temp.Add(left[0]); left.RemoveAt(0); } else { temp.Add(right[0]); right.RemoveAt(0); } } if (left.Count > 0) { for (int i = 0; i < left.Count; i++) { temp.Add(left[i]); } } if (right.Count > 0) { for (int i = 0; i < right.Count; i++) { temp.Add(right[i]); } } return temp; } ///快速排序(目标数组,数组的起始位置,数组的终止位置) static void QuickSort(int[] arr, int left = 0, int right = -1) { if (right.Equals(-1)) right = arr.Length - 1; try { int keyValuePosition; //记录关键值的下标 //当传递的目标数组含有两个以上的元素时,进行递归调用。(即:当传递的目标数组只含有一个元素时,此趟排序结束) if (left < right) { keyValuePosition = Partion(arr, left, right); //获取关键值的下标(快排的核心) QuickSort(arr, left, keyValuePosition - 1); //递归调用,快排划分出来的左区间 QuickSort(arr, keyValuePosition + 1, right); //递归调用,快排划分出来的右区间 } } catch (Exception ex) { Console.WriteLine("Exception: {0}", ex); } } ///快速排序的核心部分:确定关键值在数组中的位置,以此将数组划分成左右两区间,关键值游离在外。(返回关键值应在数组中的下标) static int Partion(int[] arr, int left, int right) { int leftIndex = left; //记录目标数组的起始位置(后续动态的左侧下标) int rightIndex = right; //记录目标数组的结束位置(后续动态的右侧下标) int keyValue = arr[left]; //数组的第一个元素作为关键值 int temp; //当 (左侧动态下标 == 右侧动态下标) 时跳出循环 while (leftIndex < rightIndex) { while (leftIndex < rightIndex && arr[leftIndex] <= keyValue) //左侧动态下标逐渐增加,直至找到大于keyValue的下标 { leftIndex++; } while (leftIndex < rightIndex && arr[rightIndex] > keyValue) //右侧动态下标逐渐减小,直至找到小于或等于keyValue的下标 { rightIndex--; } if (leftIndex < rightIndex) //如果leftIndex < rightIndex,则交换左右动态下标所指定的值;当leftIndex==rightIndex时,跳出整个循环 { temp = arr[leftIndex]; arr[leftIndex] = arr[rightIndex]; arr[rightIndex] = temp; } } //当左右两个动态下标相等时(即:左右下标指向同一个位置),此时便可以确定keyValue的准确位置 temp = keyValue; if (temp < arr[rightIndex]) //当keyValue < 左右下标同时指向的值,将keyValue与rightIndex - 1指向的值交换,并返回rightIndex - 1 { arr[left] = arr[rightIndex - 1]; arr[rightIndex - 1] = temp; return rightIndex - 1; } else //当keyValue >= 左右下标同时指向的值,将keyValue与rightIndex指向的值交换,并返回rightIndex { arr[left] = arr[rightIndex]; arr[rightIndex] = temp; return rightIndex; } } /// <summary> /// 堆排序 /// </summary> /// <param name="arr">待排序数组</param> static void HeapSort(int[] arr) { int nodeCount = arr.Length; int[] tempKey = new int[nodeCount + 1]; // 元素索引从1开始 for (int i = 0; i < nodeCount; i++) { tempKey[i + 1] = arr[i]; } // 初始数据建堆(从含最后一个结点的子树开始构建,依次向前,形成整个二叉堆) for (int i = nodeCount / 2; i >= 1; i--) { Restore(tempKey, i, nodeCount); } // 不断输出堆顶元素、重构堆,进行排序 for (int i = nodeCount; i > 1; i--) { int temp = tempKey[i]; tempKey[i] = tempKey[1]; tempKey[1] = temp; Restore(tempKey, 1, i - 1); } //排序结果 for (int i = 0; i < nodeCount; i++) { arr[i] = tempKey[i + 1]; } } /// <summary> /// 二叉堆的重构(针对于已构建好的二叉堆首尾互换之后的重构) /// </summary> /// <param name="arr"></param> /// <param name="rootNode">根结点j</param> /// <param name="nodeCount">结点数</param> static void Restore(int[] arr, int rootNode, int nodeCount) { while (rootNode <= nodeCount / 2) // 保证根结点有子树 { //找出左右儿子的最大值 int m = (2 * rootNode + 1 <= nodeCount && arr[2 * rootNode + 1] > arr[2 * rootNode]) ? 2 * rootNode + 1 : 2 * rootNode; if (arr[m] > arr[rootNode]) { int temp = arr[m]; arr[m] = arr[rootNode]; arr[rootNode] = temp; rootNode = m; } else { break; } } } ///计数排序 static void CountSort(int[] arr) { if (arr.Length == 0) return; int min = arr[0]; int max = min; foreach (int number in arr) { if (number > max) { max = number; } else if (number < min) { min = number; } } int[] counting = new int[max - min + 1]; for (int i = 0; i < arr.Length; i++) { counting[arr[i] - min] += 1; } int index = -1; for (int i = 0; i < counting.Length; i++) { for (int j = 0; j < counting[i]; j++) { index++; arr[index] = i + min; } } } ///桶排序 static void BucketSort(List<int> list, int bucketCount, int maxBucketCount) { List<List<int>> buckets = new List<List<int>>(bucketCount);//二维列表 for (int i = 0; i < bucketCount; i++) { buckets.Add(new List<int>()); } for (int i = 0; i < list.Count; i++) { // int j = Mathf.Min(list[i] / (maxBucketCount / bucketCount), bucketCount - 1);//j表示改放的哪个桶,不能大于n-1 int j = Math.Min(list[i] / (maxBucketCount / bucketCount), bucketCount - 1);//j表示改放的哪个桶,不能大于n-1 buckets[j].Add(list[i]);//放入对应桶 for (int x = buckets[j].Count - 1; x > 0; x--)//放一个排序一次,两两对比就可以 { if (buckets[j][x] < buckets[j][x - 1])//升序 { int tmp = buckets[j][x];//交换 buckets[j][x] = buckets[j][x - 1]; buckets[j][x - 1] = tmp; } else { break;//如果不发生交换直接退出,因为前面的之前就排序好了 } } } list.Clear();//输出 for (int i = 0; i < buckets.Count; i++) { list.AddRange(buckets[i]); } } ///基数排序 static void RadixSort(List<int> list) { int maxValue = list.Max();//列表内部方法拿过来用用(在Linq中) int it = 0;//需要几趟 //maxvalue 9-1 99-2 999-3 //10^0<=9 10^1>9 it=1 //10^0<99 10^1<99 10^2>99 it=2 while (Math.Pow(10, it) <= maxValue) { List<List<int>> buckets = new List<List<int>>(10);//分10个桶对应0-9 for (int i = 0; i < 10; i++) { buckets.Add(new List<int>()); }//列表初始化大小 for (int i = 0; i < list.Count; i++)//入桶 { //989 it=0 989/10^it=989 989%10=9; int digit = (int)((list[i]) / (Math.Pow(10, it)) % 10);//得到对应桶 buckets[digit].Add(list[i]); }//全部入桶 list.Clear();//依次取出来 for (int i = 0; i < buckets.Count; i++) { list.AddRange(buckets[i]); } it += 1;//继续下一次循环入桶出桶 } } } }

参考链接



作者:艾孜尔江


__EOF__

本文作者艾孜尔江
本文链接https://www.cnblogs.com/ezhar/p/13783108.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。您的鼓励是博主的最大动力!
posted @   艾孜尔江  阅读(406)  评论(0编辑  收藏  举报
编辑推荐:
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 25岁的心里话
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示