Visual C# 诠释常用排序算法

2016-02-19 15:06 2 1 收藏

get新技能是需要付出行动的,即使看得再多也还是要动手试一试。今天图老师小编跟大家分享的是Visual C# 诠释常用排序算法,一起来学习了解下吧!

【 tulaoshi.com - 编程语言 】

  前段时间因为项目需要,做了个用来对数组排序的类,顺便把以前学过的几种排序算法用C#实现一下。用C#的一些机制来诠释了一下算法的是实现。在阅读本之前,需要一些对C#的有些基本的了解,了解方法参数中out ,ref的作用,掌握面向对象的一些基本思想。

  1. 插入排序

  1.1. 基本思想:

  每次将一个待排序的数据元素,插入到前面已经排好序的数列中的适当位置,使数列依然有序;直到待排序数据元素全部插入完为止。

  1.2. 排序过程: 

  :

  [初始关键字] [49] 38 65 97 76 13 27 49

  (38) [38 49] 65 97 76 13 27 49

  (65) [38 49 65] 97 76 13 27 49

  (97) [38 49 65 97] 76 13 27 49

  (76) [38 49 65 76 97] 13 27 49

  (13) [13 38 49 65 76 97] 27 49

  (27) [13 27 38 49 65 76 97] 49

  (49) [13 27 38 49 49 65 76 97]

  1.3. 程序实现

(本文来源于图老师网站,更多请访问https://www.tulaoshi.com/bianchengyuyan/)
summary/// 插入排序算法/// /summary/// param name="dblArray"/paramstatic void InsertSort(ref double[] dblArray){ for(int i = 1 ; i  dblArray.Length ; i++) {  int frontArrayIndex = i-1 ;  int CurrentChangeIndex = i ;  while(frontArrayIndex=0)  {   if(dblArray[CurrentChangeIndex]  dblArray[frontArrayIndex])   {    ChangeValue(ref dblArray[CurrentChangeIndex],ref dblArray[frontArrayIndex]);    CurrentChangeIndex = frontArrayIndex ;   }   frontArrayIndex--;  } }}/// summary/// 在内存中交换两个数字的值/// /summary/// param name="A"/param/// param name="B"/paramstatic void ChangeValue (ref double A ,ref double B){ double Temp = A ; A = B ; B = Temp ;}

  2. 选择排序

  2.1. 基本思想:

  每一趟从待排序的数据元素中选出最小(或最大)的一个元素,顺序放在已排好序的数列的最后,直到全部待排序的数据元素排完。

  2.2. 排序过程:

  :

  初始关键字 [49 38 65 97 76 13 27 49]

  第一趟排序后 13 [38 65 97 76 49 27 49]

  第二趟排序后 13 27 [65 97 76 49 38 49]

  第三趟排序后 13 27 38 [97 76 49 65 49]

  第四趟排序后 13 27 38 49 [49 97 65 76]

  第五趟排序后 13 27 38 49 49 [97 97 76]

  第六趟排序后 13 27 38 49 49 76 [76 97]

  第七趟排序后 13 27 38 49 49 76 76 [ 97]

  最后排序结果 13 27 38 49 49 76 76 97

  2.3. 程序实现

/// summary/// 选择排序/// /summary/// param name="dblArray"/paramprivate static void SelectSort(ref double[] dblArray){ for(int i =0 ; i dblArray.Length; i++) {  double MinValue = dblArray[i] ;  int MinValueIndex = i ;  for(int j = i; j dblArray.Length; j++)  {   if(MinValue  dblArray[j] )   {    MinValue = dblArray[j] ;    MinValueIndex = j ;   }  }  ExChangeValue(ref dblArray[i], ref dblArray[MinValueIndex]); }}/// summary/// 交换数据/// /summary/// param name="A"/param/// param name="B"/paramprivate static void ExChangeValue(ref double A , ref double B){ double Temp = A ; A = B ; B = Temp ;}

  3. 冒泡排序

  3.1. 基本思想:

  两两比较待排序数据元素的大小,发现两个数据元素的次序相反时即进行交换,直到没有反序的数据元素为止。

  3.2. 排序过程:

  设想被排序的数组R[1..N]垂直竖立,将每个数据元素看作有重量的气泡,根据轻气泡不能在重气泡之下的原则,从下往上扫描数组R,凡扫描到违反本原则的轻气泡,就使其向上"漂浮",如此反复进行,直至最后任何两个气泡都是轻者在上,重者在下为止

  :

  49 13 13 13 13 13 13 13

  38 49 27 27 27 27 27 27

  65 38 49 38 38 38 38 38

  97 65 38 49 49 49 49 49

  76 97 65 49 49 49 49 49

  13 76 97 65 65 65 65 65

  27 27 76 97 76 76 76 76

  49 49 49 76 97 97 97 97

  3.3. 程序实现

  程序支持顺序和倒序排列。

/// summary/// 冒泡算法/// /summary/// param name="abarray"/param/// param name="IsAscending"是否顺序排序/param/// returns/returnsprivate static double[] BubbleArithmetic(double[] abarray ,bool IsAscending){ if(abarray.Length  0 ) {  for(int i = abarray.Length-1 ;i =0 ;i--)  {   for(int j = i-1 ; j=0 ; j--)   {    if(CheckAccordCondition(abarray[i],abarray[j],IsAscending))    {     ExChangeValue(ref abarray[i],ref abarray[j]);    }   }  } } return abarray;}/// summary/// 交换数据/// /summary/// param name="A"/param/// param name="B"/paramprivate static void ExChangeValue(ref double A , ref double B){ double Temp = A ; A = B ; B = Temp ;}/// summary/// 是否符合条件/// /summary/// returns/returnsprivate static bool CheckAccordCondition(double data1 ,double data2, bool IsAscending){ if(data1  data2) {  return IsAscending == true ? true :false; } else {  return IsAscending == true ? false :true ; }}

  4. 快速排序

  4.1. 基本思想:

  在当前无序区R[1..H]中任取一个数据元素作为比较的"基准"(不妨记为X),用此基准将当前无序区划分为左右两个较小的无序区:R[1..I-1]和R[I+1..H],且左边的无序子区中数据元素均小于等于基准元素,右边的无序子区中数据元素均大于等于基准元素,而基准X则位于最终排序的位置上,即R[1..I-1]≤X.Key≤R[I+1..H](1≤I≤H),当R[1..I-1]和R[I+1..H]均非空时,分别对它们进行上述的划分过程,直至所有无序子区中的数据元素均已排序为止。

  4.2. 排序过程:

  :

  初始关键字 [49 38 65 97 76 13 27 49]

  第一次交换后 [27 38 65 97 76 13 49 49]

  第二次交换后 [27 38 49 97 76 13 65 49]

  第三次交换后 [27 38 13 97 76 49 65 49]

  第四次交换后 [27 38 13 49 76 97 65 49]

  [27 38 13 49 76 97 65 49]

  (一次划分过程)

  初始关键字 [49 38 65 97 76 13 27 49]

  一趟排序之后 [27 38 13] 49 [76 97 65 49]

  二趟排序之后 [13] 27 [38] 49 [49 65]76 [97]

  三趟排序之后 13 27 38 49 49 [65]76 97

  最后的排序结果 13 27 38 49 49 65 76 97

  各趟排序之后的状态

  4.3. 程序实现

/// summary/// 快速排序法/// /summary/// param name="dbArray"/param/// param name="StartIndex"/param/// param name="EndIndex"/paramprivate static void QuickSort( ref double[] dbArray ,int StartIndex ,int EndIndex){ //基数 int CurrentIndex = StartIndex ; //顺序查找 bool IsOrderSearched = true ; //反序查找 bool IsDisOrderSearched = true ; while(IsOrderSearched || IsDisOrderSearched) {  IsDisOrderSearched = false ;  IsOrderSearched = false ;  for(int i =EndIndex ; iCurrentIndex ;i--)  {   if(dbArray[i]  dbArray[CurrentIndex])   {    ExChangeValue(ref dbArray[i] ,ref dbArray[CurrentIndex]);    CurrentIndex = i ;    IsDisOrderSearched = true ;    break ;   }  }  for(int i = StartIndex ; i  CurrentIndex ; i++)  {   if(dbArray[i]  dbArray[CurrentIndex])   {    ExChangeValue(ref dbArray[i] ,ref dbArray[CurrentIndex]);    CurrentIndex = i ;    IsOrderSearched = true ;    break ;   }  } } if( EndIndex - StartIndex  0 ) {  if(CurrentIndex != StartIndex )  {   QuickSort(ref dbArray ,StartIndex,CurrentIndex -1);  }  if(CurrentIndex != EndIndex)  {   QuickSort(ref dbArray ,CurrentIndex+1,EndIndex);  } }}/// 交换数据/// /summary/// param name="A"/param/// param name="B"/paramprivate static void ExChangeValue(ref double A , ref double B){ double Temp = A ; A = B ; B = Temp ;}

  5. 堆排序

  5.1. 基本思想:

  堆排序是一树形选择排序,在排序过程中,将R[1..N]看成是一颗完全二叉树的顺序存储结构,利用完全二叉树中双亲结点和孩子结点之间的内在关系来选择最小的元素。

  5.2. 堆的定义:

(本文来源于图老师网站,更多请访问https://www.tulaoshi.com/bianchengyuyan/)

  N个元素的序列K1,K2,K3,...,Kn.称为堆,当且仅当该序列满足特性:Ki≤K2i Ki ≤K2i+1(1≤ I≤ [N/2])。

  

  堆实质上是满足如下性质的完全二叉树:树中任一非叶子结点的关键字均大于等于其孩子结点的关键字。例如序列10,15,56,25,30,70就是一个堆,它对应的完全二叉树如上图所示。这种堆中根结点(称为堆顶)的关键字最小,我们把它称为小根堆。反之,若完全二叉树中任一非叶子结点的关键字均大于等于其孩子的关键字,则称之为大根堆。

  5.3. 排序过程:

  堆排序正是利用小根堆(或大根堆)来选取当前无序区中关键字小(或最大)的记录实现排序的。我们不妨利用大根堆来排序。每一趟排序的基本操作是:将当前无序区调整为一个大根堆,选取关键字最大的堆顶记录,将它和无序区中的最后一个记录交换。这样,正好和直接选择排序相反,有序区是在原记录区的尾部形成并逐步向前扩大到整个记录区。

  :对关键字序列42,13,91,23,24,16,05,88建堆。

  5.4. 程序实现

/// summary/// 小根堆排序/// /summary/// param name="dblArray"/param/// param name="StartIndex"/param/// returns/returnsprivate static void HeapSort(ref double[] dblArray ){ for(int i = dblArray.Length -1 ; i = 0; i--) {  if(2*i+1dblArray.Length)  {   int MinChildrenIndex = 2*i+1 ;   //比较左子树和右子树,记录最小值的Index   if(2*i+2  dblArray.Length )   {    if(dblArray[2*i+1]dblArray[2*i+2])     MinChildrenIndex = 2*i+2;   }   if(dblArray[i]  dblArray[MinChildrenIndex])   {    ExchageValue(ref dblArray[i],ref dblArray[MinChildrenIndex]);    NodeSort(ref dblArray ,MinChildrenIndex);   }  } }}/// summary/// 节点排序/// /summary/// param name="dblArray"/param/// param name="StartIndex"/paramprivate static void NodeSort(ref double[] dblArray,int StartIndex){ while(2*StartIndex+1  dblArray.Length) {  int MinChildrenIndex = 2*StartIndex+1 ;  if(2*StartIndex+2  dblArray.Length )  {   if(dblArray[2*StartIndex+1]dblArray[2*StartIndex+2])   {    MinChildrenIndex = 2*StartIndex+2;   }  }  if(dblArray[StartIndex]  dblArray[MinChildrenIndex])  {   ExchageValue(ref dblArray[StartIndex],ref dblArray[MinChildrenIndex]);   StartIndex = MinChildrenIndex ;  } }}/// summary/// 交换值/// /summary/// param name="A"/param/// param name="B"/paramprivate static void ExchageValue(ref double A , ref double B){ double Temp = A ; A = B ; B = Temp ;}

  总结:

  人常说算法是程序的灵魂,在作项目的过程中时常注意且不可灵魂出窍。时常去回顾一下以前的数据重要性就如同基督徒每周要做礼拜一样。不能因为有了C# 和Java这种平台之后,就忽略了基础的重要性。

  我用C#的控制台程序 把这几个算法实现了一下,代码在附件中,如有写的不好的地方,敬请指正。

来源:https://www.tulaoshi.com/n/20160219/1608881.html

延伸阅读
C#中程序结构的关键概念为程序、命名空间、类型、成员和程序集。C#程序包括一个或多个源文件。程序中声明类型,类型包含成员并能够被组织到命名空间中。类和接口是类型的例子。字段、方法、属性和事件则是成员的例子。当C#程序被编译时,它们被物理地打包到程序集中。程序集的文件扩展名一般为.exe或者.dll,这取决于它们是实现为应用程序...
作为软件设计和开发人员大都有过使用DLL(动态连接库)的经历,DLL的产生使得我们的应用程序在可维护性、代码的重复使用等方面都有了很大的提高。以前用的DLL一般都是用Visual C++、Delphi或者VB等编程语言来编写的,这种DLL的编写和使用,我们大都已经比较习惯了。作为新一代的程序开发语言--Visual C#,到底是如何编写和使用DLL的呢!本...
简介 在这个练习中,你将使用Microsoft Visual Studio.NET创建,编译,运行一个Hello World应用程序. 在IDE中创建一个新的项目 1.依次点击start- Programs-Microsoft Visual Studio.NET7.0- Microsoft Visual Studio .NET 7.0. IDE起始页就会显示出来,参见图1所示。 图1 Visual Studio .NET中的起始页 注释:当...
程序的活动是通过语句(statement)来表达的。C#支持几种不同的语句,许多语句是以嵌入语句的形式定义的。 块(block)允许在只能使用单个语句的上下文中编写多个语句。块由一个括在大括号{}内的语句列表组成。 声明语句(declaration statement)用于声明局部变量和常量。 表达式语句(expression statement)用于运算表达...
所谓托盘程序顾名思义就是象托起的盘子一样的程序。而所谓的托起的盘子就是程序运行中显示出的图标,而托起的位置就是视窗系统的的工具栏了。托盘程序具有直观、占用屏幕空间较小并且可以为它定义多个功能菜单,这就给操作者带来了方便,所以越来越多的程序设计者都把程序设计成托盘这种方式。我们已经看过了用其他语言设计托盘程序的例子...

经验教程

569

收藏

58
微博分享 QQ分享 QQ空间 手机页面 收藏网站 回到头部