c#实现冒泡、快速、选择和插入排序算法

摘要:
整理常见的排序算法,并在c#中实现它们,以备将来使用。Codeischeap公司。参见具体实施。1.气泡排序垂直排列已排序的记录数组R[1..N],每个记录R[i]被视为R[i]键的气泡。根据轻气泡不能低于重气泡的原理,从下到上扫描阵列R:任何违反此原理的轻气泡都将被扫描,它们将向上“漂浮”(因此得名气泡)。重复此过程,直到任意两个气泡变轻和变重。代码使用系统

整理一下常用的排序算法,用c#实现,以备日后再用。Code is cheap.看具体实现吧。
1.冒泡排序
将被排序的记录数组R[1..n]垂直排列,每个记录R[i]看作是重量为R[i].key的气泡。根据轻气泡不能在重气泡之下的原则,从下往上扫描数组R:凡扫描到违反本原则的轻气泡,就使其向上"飘浮"(冒泡因此得名)。如此反复进行,直到最后任何两个气泡都是轻者在上,重者在下为止。

c#实现冒泡、快速、选择和插入排序算法第1张c#实现冒泡、快速、选择和插入排序算法第2张Code
using System;
using System.Collections;
using System.Collections.Generic;

namespace BubbleSort
{
    
public class BubbleSorter
    {
        
/// <summary>
        
/// 冒泡排序 
        
/// </summary>
        
/// <param name="numArr"></param>
        public void Sort(int[] numArr)
        {
            
int tmpNum;
            
bool flag = false//交换标志
            for (int i = 1; i < numArr.Length; i++//最多做numArr.Length-1趟排序
            {
                flag 
= false;
                
for (int j = numArr.Length - 1; j >= i; j--//对当前无序区自下向上扫描
                {
                    
if (numArr[j] < numArr[j - 1]) //当前无序区: 轻的在下面,“冒泡”到上面
                    {
                        tmpNum 
= numArr[j];
                        numArr[j] 
= numArr[j - 1];
                        numArr[j 
- 1= tmpNum;
                        flag 
= true;
                    }
                }
                
if (!flag) //如果没有发生交换,终止算法
                    return;
            }
        }

        
public class Program
        {
            
public static void Main()
            {
                
int[] testArr = new int[] { 1511642199215113403347 };
                BubbleSorter sh 
= new BubbleSorter();
                sh.Sort(testArr);
                
for (int m = 0; m < testArr.Length; m++)
                    Console.Write(
"{0} ", testArr[m]);
                Console.Read();
            }
        }
    }
}
冒泡算法小结:
 因为每一趟排序都使有序区增加了一个气泡,在经过n-1趟排序之后,有序区中就有n-1个气泡,而无序区中气泡的重量总是大于等于有序区中气泡的重量,所以整个冒泡排序过程至多需要进行n-1趟排序。若在某一趟排序中未发现气泡位置的交换,则说明待排序的无序区中所有气泡均满足轻者在上,重者在下的原则,因此,冒泡排序过程可在此趟排序后终止。为此,在下面给出的算法中,引入一个布尔量flag,在每趟排序开始前,先将其置为false,若排序过程中发生了交换,则将其置为true.各趟排序结束时检查flag,若未曾发生过交换则终止算法,不再进行下一趟排序。(不加flag也可以实现排序,但是会造成不必要的循环和比较)。
2.快速排序 ***
一、算法思想
     快速排序是C.R.A.Hoare于1962年提出的一种划分交换排序。它采用了一种分治的策略,通常称其为分治法(Divide-and-ConquerMethod)。分治法的基本思想是:将原问题分解为若干个规模更小但结构与原问题相似的子问题。递归地解这些子问题,然后将这些子问题的解组合为原问题的解。
二、快速排序的基本思想
     设当前待排序的无序区为R[low..high],利用分治法可将快速排序的基本思想描述为:
(1)分解:
     在R[low..high]中任选一个记录作为基准(Pivot),以此基准将当前无序区划分为左、右两个较小的子区间R[low..pivotpos-1)和R[pivotpos+1..high],并使左边子区间中所有记录的关键字均小于等于基准记录(不妨记为pivot)的关键字pivot.key,右边的子区间中所有记录的关键字均大于等于pivot.key,而基准记录pivot则位于正确的位置(pivotpos)上,它无须参加后续的排序。注意:划分的关键是要求出基准记录所在的位置pivotpos。划分的结果可以简单地表示为(注意 pivot=R[pivotpos] ):  R[low..pivotpos-1].keys≤R[pivotpos].key≤R[pivotpos+1..high].keys,
其中low≤pivotpos≤high。(边界条件)
(2)求解:
     通过递归调用快速排序对左、右子区间R[low..pivotpos-1]和R[pivotpos+1..high]快速排序。
(3)组合:
     因为当"求解"步骤中的两个递归调用结束时,其左、右两个子区间已有序。对快速排序而言,"组合"步骤无须做什么,可看作是空操作。
c#实现冒泡、快速、选择和插入排序算法第3张c#实现冒泡、快速、选择和插入排序算法第4张Code
using System;

namespace QuickSorter
{
    
public class QuickSort
    {
        
public static void Sort(int[] numArr)
        {
            Sort(numArr, 
0, numArr.Length - 1);
        }

        
private static void Sort(int[] numArr, int left, int right)
        {
            
if (left < right)
            {
                
int middle = numArr[(left + right) / 2];
                
int i = left - 1;
                
int j = right + 1;
                
while (true)
                {
                    
while (numArr[++i] < middle) ;

                    
while (numArr[--j] > middle) ;

                    
if (i >= j)
                        
break;

                    Swap(numArr, i, j);
                }

                Sort(numArr, left, i 
- 1);
                Sort(numArr, j 
+ 1, right);
            }
        }

        
private static void Swap(int[] numArr, int i, int j)
        {
            
int number = numArr[i];
            numArr[i] 
= numArr[j];
            numArr[j] 
= number;
        }

    }

    
public class Program
    {
        
static void Main(string[] args)
        {
            
int[] arr = new int[] { 204127141618559352214 };
            QuickSort.Sort(arr);
            Console.WriteLine(
"Numbers after quicksort:");
            
foreach (int i in arr)
            {
                Console.WriteLine(i);
            }
            Console.Read();
        }
    }
}

 网上还有一种相似的代码,一起贴出来:

c#实现冒泡、快速、选择和插入排序算法第5张c#实现冒泡、快速、选择和插入排序算法第6张Code
using System;

namespace QuickSorter
{
    
public class QuickSorter
    {
        
/// <summary>
        
/// 快速排序算法
        
/// </summary>
        
/// 快速排序为不稳定排序,时间复杂度O(nlog2n),为同数量级中最快的排序方法
        
/// <param name="arr">划分的数组</param>
        
/// <param name="low">数组低端上标</param>
        
/// <param name="high">数组高端下标</param>
        
/// <returns></returns>
        public static int Partition(int[] arr, int low, int high)
        {
            
//进行一趟快速排序,返回中心轴记录位置
            
// arr[0] = arr[low];
            int pivot = arr[low];//把中心轴置于arr[0]
            while (low < high)
            {
                
while (low < high && arr[high] >= pivot)
                    
--high;
                
//将比中心轴记录小的移到低端
                Swap(ref arr[high], ref arr[low]);
                
while (low < high && arr[low] <= pivot)
                    
++low;
                Swap(
ref arr[high], ref arr[low]);
                
//将比中心轴记录大的移到高端
            }
            arr[low] 
= pivot; //中心轴移到正确位置
            return low;  //返回中心轴位置
        }
        
public static void Swap(ref int i, ref int j)
        {
            
int t;
            t 
= i;
            i 
= j;
            j 
= t;
        }
        
public static void Sort(int[] arr, int low, int high)
        {
            
if (low < high - 1)//当 arr[low,high]为空或只一个记录无需排序
            {
                
int pivot = Partition(arr, low, high);
                Sort(arr, low, pivot 
- 1);
                Sort(arr, pivot 
+ 1, high);

            }
        }

    }

    
public class Program
    {
        
static void Main(string[] args)
        {
            
int[] arr = new int[] { 204127141618559352214 };
            QuickSorter.Sort(arr, 
0, arr.Length - 1);
            Console.WriteLine(
"Numbers after quicksort:");
            
foreach (int i in arr)
            {
                Console.WriteLine(i);
            }

            Console.Read();
        }
    }
}

3.选择排序

c#实现冒泡、快速、选择和插入排序算法第7张c#实现冒泡、快速、选择和插入排序算法第8张Code
using System;

namespace SelectionSorter
{
    
/// <summary>
    
///  选择排序(Selection Sort)的基本思想是:每一趟从待排序的记录中选出关键字最小的记录,顺序放在已排好序的子文件的最后,直到全部记录排序完毕。
    
/// </summary>
    public class SelectionSort
    {
        
public static void Sort(int[] numArray)
        {
            
int min, tmp;
            
for (int i = 0; i < numArray.Length - 1; i++)
            {
                min 
= i;
                
for (int j = i + 1; j < numArray.Length; j++)
                {
                    
if (numArray[j] < numArray[min])
                    {
                        min 
= j;
                    }
                }
                tmp 
= numArray[i];
                numArray[i] 
= numArray[min];
                numArray[min] 
= tmp;
            }

        }
    }

    
public class Program
    {
        
static void Main(string[] args)
        {
            
int[] arr = new int[] { 204127141618559352214 };
            SelectionSort.Sort(arr);
            Console.WriteLine(
"Numbers after selectionsort:");
            
foreach (int i in arr)
            {
                Console.WriteLine(i);
            }
            Console.Read();
        }
    }
}

4.插入排序

c#实现冒泡、快速、选择和插入排序算法第9张c#实现冒泡、快速、选择和插入排序算法第10张Code
using System;

namespace InsertSorter
{

    
/// <summary>
    
/// 插入排序(Insertion Sort)的算法描述是一种简单直观的排序算法。它的工作原理是通过构建有序序列,对于未排序数据,
    
/// 在已排序序列中从后向前扫描,找到相应位置并插入。插入排序在实现上,通常采用in-place排序(即只需用到O(1)的额外空间的排序),
    
/// 因而在从后向前扫描过程中,需要反复把已排序元素逐步向后挪位, 为最新元素提供插入空间。
    
/// </summary>
    public class InsertSort
    {
        
public static void Sort(int[] numArr)
        {
            
for (int i = 1; i < numArr.Length; i++//i从1开始
            {
                
int t = numArr[i]; //标志当前未排序数据
                int j = i;
                
while ((j > 0&& (numArr[j - 1> t))
                {
                    numArr[j] 
= numArr[j - 1];
                    j
--;
                }
                numArr[j] 
= t; //在已排序序列中插入当前值
            }
        }
    }

    
public class Program
    {
        
static void Main(string[] args)
        {
            
int[] arr = new int[] { 204127141618559352214 };
            InsertSort.Sort(arr);
            Console.WriteLine(
"Numbers after insertsort:");
            
foreach (int i in arr)
            {
                Console.WriteLine(i);
            }
            Console.Read();
        }
    }
}

虽然在实际的项目中,我们的确很少用到这些或其他更高级的算法,但是”算法是程序的灵魂“。虽然算法确实很难,但是”当你用它们巧妙地解决问题的时候,那种纯粹的喜悦和快乐是任何不曾体验过的人所能感受到的“。很不幸,我还没有体验几次这样的快乐。

免责声明:文章转载自《c#实现冒泡、快速、选择和插入排序算法》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇spring + redis 实现数据的缓存利用Kettle转储接口数据下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

sql优化大全

1. 优化SQL步骤 1. 通过 show status和应用特点了解各种 SQL的执行频率 通过 SHOW STATUS 可以提供服务器状态信息,也可以使用 mysqladmin extende d-status 命令获得。 SHOW STATUS 可以根据需要显示 session 级别的统计结果和 global级别的统计结果。 如显示当前sessi...

关于JavaScript的数组随机排序

昨天了解了一下Fisher–Yates shuffle费雪耶兹随机置乱算法,现在再来看看下面这个曾经网上常见的一个写法: functionshuffle(arr) { arr.sort(function() { return Math.random() - 0.5; }); } 或者使用更简洁的 ES6 的写法: funct...

数据库性能优化

MySQL基础表和数据 数据库访问优化法则 了解计算机系统的硬件基本性能指标,可以快速找到SQL的性能瓶颈点,下面是当前主流计算机性能指标数据。 从图上可以看到基本上每种设备都有两个指标: 延时(响应时间):表示硬件的突发处理能力; 带宽(吞吐量):代表硬件持续处理能力。 从上图可以看出,计算机系统硬件性能从高到代依次为: CPU——Cache(L1-L...

笔试题算法系列(八)百度有趣的排序

[编程题] 有趣的排序 时间限制:1秒 空间限制:32768K 度度熊有一个N个数的数组,他想将数组从小到大 排好序,但是萌萌的度度熊只会下面这个操作:任取数组中的一个数然后将它放置在数组的最后一个位置。问最少操作多少次可以使得数组从小到大有序? 输入描述: 首先输入一个正整数N,接下来的一行输入N个整数。(N <= 50, 每个数的绝对值小...

容器知识的重点总结

什么是容器 数组也是一种容器,可以存放对象或基本数据类型,数组的劣势在于不灵活,容器需要事先定义好,不能随着需求而改变而扩容。而容器则可以随时扩容来装对象,容器也称为集合。 容器的结构 单例集合 将数据一个一个的进行存储 双例集合 基于 key 和 value 的结构存储数据 Collection 接口 LIst接口:有序,可重复 ArrayList 容...

SortedList、SortedSet、HashSet、Hashtable、Dictionary、SortedDictionary 排序/可重复排序/过滤重复排序等简单对比

//泛型的键值集合/有序/Hash算法/占内存较大/不排序,不受装填因子的限制,对读写操作效率较高 Dictionary<int, string> dc = new Dictionary<int, string>(); dc.Add(1, "111111");...