常见排序算法的C#实现

排序算法常见的有直接排序、冒泡排序、快速排序、基数排序、归并排序等,下面是实现的代码,仅供参考。

 #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]交换,/// 总共通过n-1次,得到一个按排序码从小到大排列的有序序列·/// </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>/// 冒泡排序./// 重复地走访过要排序的数列,一次比较两个元素,/// 如果他们的顺序错误就把他们交换过来。/// 走访数列的工作是重复地进行直到没有再需要交换,/// 也就是说该数列已经排序完成。/// 这个算法的名字由来是因为越大的元素会经由交换慢慢“浮”到数列的顶端,故名。/// </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>/// 快速排序./// 通过一趟排序将要排序的数据分割成独立的两部分,/// 其中一部分的所有数据都比另外一部分的所有数据都要小,/// 然后再按此方法对这两部分数据分别进行快速排序,/// 整个排序过程可以递归进行,以此达到整个数据变成有序序列。/// </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);//对左边单元进行排序QuickSortInner(data, left, middle - 1, ref count);//对右边单元进行排序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的值,直接将该值放到左边,//此时right位置的空间空出,留作放置从左边比较出的大于key的值。//如果右索引已经到达了左边,right==left,data[left] = data[right]是同数据交换,不受影响.data[left] = data[right];count++;break;}}//自左端向右端查找大于key的值for (; ; left++){if (data[left] > key || left >= right){//左边有大于key的值,直接将该值放到右边,//此时left位置的空间空出,留作放置从右边比较出的小于key的值,或者用来最后放置key.//如果左索引已经到达了右边,left==right,data[right] = data[left]是同数据交换,不受影响.data[right] = data[left];count++;break;}}}data[left] = key;return right;}#endregion#region  RadixSort/// <summary>/// 基数排序(此处采用LSD法)./// 属于“分配式排序”(distribution sort),又称“桶子法”(bucket sort)或bin sort,/// 顾名思义,它是透过键值的部份资讯,将要排序的元素分配至某些“桶”中,藉以达到排序的作用,/// 基数排序法是属于稳定性的排序,其时间复杂度为O (nlog(r)m),其中r为所采取的基数,而m为堆数,/// 在某些时候,基数排序法的效率高于其它的稳定性排序法。/// ==基数排序又分MSD和LSD。/// ==最高位优先(Most Significant Digit first)法,简称MSD法:/// 先按k1排序分组,同一组中记录,关键码k1相等,再对各组按k2排序分成子组,/// 之后,对后面的关键码继续这样的排序分组,直到按最次位关键码kd对各子组排序后。/// 再将各组连接起来,便得到一个有序序列。/// ==最低位优先(Least Significant Digit first)法,简称LSD法:/// 先从kd开始排序,再对kd-1进行排序,依次重复,直到对k1排序后便得到一个有序序列。/// </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;//计算最大位数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;// 计算出对应位数的字符串的值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)的一个非常典型的应用。/// 将已有序的子序列合并,得到完全有序的序列;即先使每个子序列有序,再使子序列段间有序。/// 若将两个有序表合并成一个有序表,称为二路归并。/// ===归并过程为:/// 比较a[i]和a[j]的大小,若a[i]≤a[j],则将第一个有序表中的元素a[i]复制到r[k]中,并令i和k分别加上1;/// 否则将第二个有序表中的元素a[j]复制到r[k]中,并令j和k分别加上1,如此循环下去,直到其中一个有序表取完,/// 然后再将另一个有序表中剩余的元素复制到r中从下标k到下标t的单元。/// 归并排序的算法我们通常用递归实现,先把待排序区间[s, t]以中点二分,接着把左边子区间排序,/// 再把右边子区间排序,最后把左区间和右区间用一次归并操作合并成有序的区间[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>/// 二路归并./// 原理:将两个有序表合并成一个有序表/// </summary>/// <param name="data"></param>/// <param name="firstStart">第一个有序表的起始下标</param>/// <param name="secondStart">第二个有序表的起始下标</param>/// <param name="secondTail">第二个有序表的结束下标</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){//自小而大合并到一个序列中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">第一个序列的起始索引</param>/// <param name="len">每次归并的有序集合的长度</param>private static void MergeSortInner(int[] data, int firstStart, int len, ref int count){int size = data.Length;//归并排序具体工作原理如下(假设序列共有n个元素)://将序列每相邻两个数字进行归并操作(merge),形成floor(n/2)个序列,排序后每个序列包含两个元素//将上述序列再次归并,形成floor(n/4)个序列,每个序列包含四个元素//将上述序列继续归并,形成floor(n/K)个序列(其中k为2的t次方),直到所有元素排序完毕。int k = len << 1;//新标准序列的组数int groupStandard = size / k;//除了标准序列外剩余的元素个数int leftElement = size % k; // size & (k - 1);//归并到只剩一个有序集合的时候结束算法if (groupStandard == 0){return;}int secondStart = 0;int secondTail = 0;//进行一趟归并排序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);}//将剩下的数和倒数第一个有序集合归并if (leftElement != 0){firstStart = size - leftElement - 2 * len;secondStart = size - leftElement;secondTail = size - 1;MergeSortUnit(data, firstStart, secondStart, secondTail, ref count);}//递归执行下一趟归并排序MergeSortInner(data, 0, 2 * len, ref count);}#endregion
以上各排序算法的解释主要来自于百度,仅供参考。

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));//基数排序Console.WriteLine("=======基数排序======");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();}
输出结果如下图

转载请注明出处


转载于:https://www.cnblogs.com/sparkleDai/p/7604908.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/469348.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【Pytorch神经网络实战案例】11 循环神经网络结构训练语言模型并进行简单预测

1 语言模型步骤 简单概述&#xff1a;根据输入内容&#xff0c;继续输出后面的句子。 1.1 根据需求拆分任务 (1)先对模型输入一段文字&#xff0c;令模型输出之后的一个文字。(2)将模型预测出来的文字当成输入&#xff0c;再放到模型里&#xff0c;使模型预测出下一个文字&…

【Pytorch神经网络理论篇】 20 神经网络中的注意力机制

同学你好&#xff01;本文章于2021年末编写&#xff0c;获得广泛的好评&#xff01; 故在2022年末对本系列进行填充与更新&#xff0c;欢迎大家订阅最新的专栏&#xff0c;获取基于Pytorch1.10版本的理论代码(2023版)实现&#xff0c; Pytorch深度学习理论篇(2023版)目录地址…

【Pytorch神经网络实战案例】12 利用注意力机制的神经网络实现对FashionMNIST数据集图片的分类

1、掩码模式&#xff1a;是相对于变长的循环序列而言的&#xff0c;如果输入的样本序列长度不同&#xff0c;那么会先对其进行对齐处理&#xff08;对短序列补0&#xff0c;对长序列截断&#xff09;&#xff0c;再输入模型。这样&#xff0c;模型中的部分样本中就会有大量的零…

爬虫实战学习笔记_4 网络请求urllib3模块:发送GET/POST请求实例+上传文件+IP代理+json+二进制+超时

1 urllib3模块简介 urllib3是一个第三方的网络请求模块&#xff08;单独安装该模块&#xff09;&#xff0c;在功能上比Python自带的urllib强大。 1.1了解urllib3 urllib3库功能强大&#xff0c;条理清晰的用于HTTP客户端的python库&#xff0c;提供了很多Python标准库里所没…

C. Jon Snow and his Favourite Number DP + 注意数值大小

http://codeforces.com/contest/768/problem/C 这题的数值大小只有1000&#xff0c;那么可以联想到&#xff0c;用数值做数组的下标&#xff0c;就是类似于计数排序那样子。。 这样就可以枚举k次操作&#xff0c;然后for (int i 0; i < 1025; i)&#xff0c;也就是O(1000 *…

【Pytorch神经网络理论篇】 21 信息熵与互信息:联合熵+条件熵+交叉熵+相对熵/KL散度/信息散度+JS散度

同学你好&#xff01;本文章于2021年末编写&#xff0c;获得广泛的好评&#xff01; 故在2022年末对本系列进行填充与更新&#xff0c;欢迎大家订阅最新的专栏&#xff0c;获取基于Pytorch1.10版本的理论代码(2023版)实现&#xff0c; Pytorch深度学习理论篇(2023版)目录地址…

【Pytorch神经网络理论篇】 22 自编码神经网络:概述+变分+条件变分自编码神经网络

同学你好&#xff01;本文章于2021年末编写&#xff0c;获得广泛的好评&#xff01; 故在2022年末对本系列进行填充与更新&#xff0c;欢迎大家订阅最新的专栏&#xff0c;获取基于Pytorch1.10版本的理论代码(2023版)实现&#xff0c; Pytorch深度学习理论篇(2023版)目录地址…

【Pytorch神经网络实战案例】13 构建变分自编码神经网络模型生成Fashon-MNST模拟数据

1 变分自编码神经网络生成模拟数据案例说明 变分自编码里面真正的公式只有一个KL散度。 1.1 变分自编码神经网络模型介绍 主要由以下三个部分构成&#xff1a; 1.1.1 编码器 由两层全连接神经网络组成&#xff0c;第一层有784个维度的输入和256个维度的输出&#xff1b;第…

【Pytorch神经网络实战案例】14 构建条件变分自编码神经网络模型生成可控Fashon-MNST模拟数据

1 条件变分自编码神经网络生成模拟数据案例说明 在实际应用中&#xff0c;条件变分自编码神经网络的应用会更为广泛一些&#xff0c;因为它使得模型输出的模拟数据可控&#xff0c;即可以指定模型输出鞋子或者上衣。 1.1 案例描述 在变分自编码神经网络模型的技术上构建条件…

hibernate持久化对象

转载于:https://www.cnblogs.com/jianxin-lilang/p/6440101.html

【Pytorch神经网络理论篇】 23 对抗神经网络:概述流程 + WGAN模型 + WGAN-gp模型 + 条件GAN + WGAN-div + W散度

同学你好&#xff01;本文章于2021年末编写&#xff0c;获得广泛的好评&#xff01; 故在2022年末对本系列进行填充与更新&#xff0c;欢迎大家订阅最新的专栏&#xff0c;获取基于Pytorch1.10版本的理论代码(2023版)实现&#xff0c; Pytorch深度学习理论篇(2023版)目录地址…

【Pytorch神经网络实战案例】15 WGAN-gp模型生成Fashon-MNST模拟数据

1 WGAN-gp模型生成模拟数据案例说明 使用WGAN-gp模型模拟Fashion-MNIST数据的生成&#xff0c;会使用到WGAN-gp模型、深度卷积GAN(DeepConvolutional GAN&#xff0c;DCGAN)模型、实例归一化技术。 1.1 DCGAN中的全卷积 WGAN-gp模型侧重于GAN模型的训练部分&#xff0c;而DCG…

Android启动过程深入解析

转载自&#xff1a;http://blog.jobbole.com/67931/ 当按下Android设备电源键时究竟发生了什么&#xff1f;Android的启动过程是怎么样的&#xff1f;什么是Linux内核&#xff1f;桌面系统linux内核与Android系统linux内核有什么区别&#xff1f;什么是引导装载程序&#xff1…

【Pytorch神经网络实战案例】16 条件WGAN模型生成可控Fashon-MNST模拟数据

1 条件GAN前置知识 条件GAN也可以使GAN所生成的数据可控&#xff0c;使模型变得实用&#xff0c; 1.1 实验描述 搭建条件GAN模型&#xff0c;实现向模型中输入标签&#xff0c;并使其生成与标签类别对应的模拟数据的功能&#xff0c;基于WGAN-gp模型改造实现带有条件的wGAN-…

Android bootchart(二)

这篇文章讲一下MTK8127开机启动的时间 MTK8127发布版本开机时间大约在&#xff12;&#xff10;秒左右&#xff0c;如果发现开机时间变长&#xff0c;大部分是因为加上了客户订制的东西&#xff0c;代码累赘太多了。 &#xff11;、下面看一下&#xff2d;&#xff34;&#…

Android Camera框架

总体介绍 Android Camera 框架从整体上看是一个 client/service 的架构, 有两个进程: client 进程,可以看成是 AP 端,主要包括 JAVA 代码与一些 native c/c++代码; service 进 程,属于服务端,是 native c/c++代码,主要负责和 linux kernel 中的 camera driver 交互,搜集 li…

【Pytorch神经网络实战案例】17 带W散度的WGAN-div模型生成Fashon-MNST模拟数据

1 WGAN-div 简介 W散度的损失函数GAN-dv模型使用了W散度来替换W距离的计算方式&#xff0c;将原有的真假样本采样操作换为基于分布层面的计算。 2 代码实现 在WGAN-gp的基础上稍加改动来实现&#xff0c;重写损失函数的实现。 2.1 代码实战&#xff1a;引入模块并载入样本-…

【Pytorch神经网络理论篇】 24 神经网络中散度的应用:F散度+f-GAN的实现+互信息神经估计+GAN模型训练技巧

同学你好&#xff01;本文章于2021年末编写&#xff0c;获得广泛的好评&#xff01; 故在2022年末对本系列进行填充与更新&#xff0c;欢迎大家订阅最新的专栏&#xff0c;获取基于Pytorch1.10版本的理论代码(2023版)实现&#xff0c; Pytorch深度学习理论篇(2023版)目录地址…

【Pytorch神经网络实战案例】18 最大化深度互信信息模型DIM实现搜索最相关与最不相关的图片

图片搜索器分为图片的特征提取和匹配两部分&#xff0c;其中图片的特征提取是关键。将使用一种基于无监督模型的提取特征的方法实现特征提取&#xff0c;即最大化深度互信息&#xff08;DeepInfoMax&#xff0c;DIM&#xff09;方法。 1 最大深度互信信息模型DIM简介 在DIM模型…

【Pytorch神经网络实战案例】19 神经网络实现估计互信息的功能

1 案例说明&#xff08;实现MINE正方法的功能&#xff09; 定义两组具有不同分布的模拟数据&#xff0c;使用神经网络的MINE的方法计算两个数据分布之间的互信息 2 代码编写 2.1 代码实战&#xff1a;准备样本数据 import torch import torch.nn as nn import torch.nn.fun…