C#排序算法总结

       有一点我们很容易忽略的是排序算法的稳定性(腾讯校招2016笔试题曾考过)。

  排序算法稳定性的简单形式化定义为:如果Ai = Aj,排序前Ai在Aj之前,排序后Ai还在Aj之前,则称这种排序算法是稳定的。通俗地讲就是保证排序前后两个相等的数的相对顺序不变。

  对于不稳定的排序算法,只要举出一个实例,即可说明它的不稳定性;而对于稳定的排序算法,必须对算法进行分析从而得到稳定的特性。需要注意的是,排序算法是否为稳定的是由具体算法决定的,不稳定的算法在某种条件下可以变为稳定的算法,而稳定的算法在某种条件下也可以变为不稳定的算法。

  例如,对于冒泡排序,原本是稳定的排序算法,如果将记录交换的条件改成A[i] >= A[i + 1],则两个相等的记录就会交换位置,从而变成不稳定的排序算法。

  其次,说一下排序算法稳定性的好处。排序算法如果是稳定的,那么从一个键上排序,然后再从另一个键上排序,前一个键排序的结果可以为后一个键排序所用。基数排序就是这样,先按低位排序,逐次按高位排序,低位排序后元素的顺序在高位也相同时是不会改变的。

  一.冒泡排序(Bubble Sort)

   1.基本思想:两个数比较大小,较大的数下沉,较小的数冒起来。

   2.过程:

      1.比较相邻的两个数据,如果第二个数小,就交换位置。

      2.从后向前两两比较,一直到比较最前两个数据。最终最小数被交换到起始的位置,这样第一个最小数的位置就排好了。

      3.继续重复上述过程,依次将第2.3...n-1个最小数排好位置。

  

    3.平均时间复杂度:O(n2)

    4.C#代码实现:

    

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace BubbleSort
{
    //冒泡排序类
    public class BubbleSorter
    {
        public void Sort(int[] list)
        {
            int i, j, temp;
            bool done = false;
            j = 1;
            while ((j < list.Length) && (!done))
            {
                done = true;
                for (i = 0; i < list.Length - j; i++)
                {
                    if (list[i] > list[i + 1])
                    {
                        done = false;
                        temp = list[i];
                        list[i] = list[i + 1];
                        list[i + 1] = temp;
                    }
                }
                j++;
            }
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            int[] iArrary = new int[] { 1, 5, 13, 6, 10, 55, 99, 2, 87, 12, 34, 75, 33, 47 };
            BubbleSorter sh = new BubbleSorter();
            sh.Sort(iArrary);
            for (int m = 0; m < iArrary.Length; m++)
                Console.Write("{0}", iArrary[m]+",");
            Console.WriteLine();
            Console.ReadKey();
        }
    }
}

  二. 选择排序(SelctionSort)

    1.基本思想:

    在长度为N的无序数组中,第一次遍历n-1个数,找到最小的数值与第一个元素交换;
    第二次遍历n-2个数,找到最小的数值与第二个元素交换;
    。。。
    第n-1次遍历,找到最小的数值与第n-1个元素交换,排序完成。

    2.过程:

 

    3.平均时间复杂度:O(n2)

    4.C#代码实现:

    

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace SelectionSort
{
    //Selection Sort
    //在长度为N的无序数组中,第一次遍历n-1个数,找到最小的数值与第一个元素交换;
    //第二次遍历n-2个数,找到最小的数值与第二个元素交换;
    //。。。
    //第n-1次遍历,找到最小的数值与第n-1个元素交换,排序完成。
    public class SelectionSorter
    {
        private int min;
        public void Sort(int[] list)
        {
            for (int i = 0; i < list.Length - 1; i++)
            {
                min = i;
                for (int j = i + 1; j < list.Length; j++)
                {
                    if (list[j] < list[min])
                        min = j;
                }
                int t = list[min];
                list[min] = list[i];
                list[i] = t;
            }
        }
    }
    class Program
    {
        static void Main(string[] args)
        {
            int[] iArrary = new int[] { 1, 5, 3, 6, 10, 55, 9, 2, 87, 12, 34, 75, 33, 47 };
            SelectionSorter ss = new SelectionSorter();
            ss.Sort(iArrary);
            for (int m = 0; m < iArrary.Length; m++)
                Console.Write("{0}", iArrary[m]+",");
            Console.WriteLine();
            Console.ReadKey();
        }
    }
}

  

  三. 插入排序(Insertion Sort)

    1.基本思想:

    在要排序的一组数中,假定前n-1个数已经排好序,现在将第n个数插到前面的有序数列中,使得这n个数也是排好顺序的。如此反复循环,直到全部排好顺序。

    2.过程:

  

    

    3.平均时间复杂度:O(n2)

    4.C#代码实现:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace InsertionSort
{
    public class InsertionSorter
    {
        public void Sort(int[] list)
        {
            for (int i = 1; i < list.Length; i++)
            {
                int t = list[i];
                int j = i;
                while ((j > 0) && (list[j - 1] > t))
                {
                    list[j] = list[j - 1];
                    --j;
                }
                list[j] = t;
            }
        }
    }
    class Program
    {
        static void Main(string[] args)
        {
            int[] iArrary = new int[] { 1, 13, 3, 6, 10, 55, 98, 2, 87, 12, 34, 75, 33, 47 };
            InsertionSorter ii = new InsertionSorter();
            ii.Sort(iArrary);
            for (int m = 0; m < iArrary.Length; m++)
                Console.Write("{0}", iArrary[m]+",");
            Console.WriteLine();
            Console.ReadKey();
        }
    }
}

   

  四. 希尔排序(Shell Sort)

    1.前言:

    数据序列1: 13-17-20-42-28 利用插入排序,13-17-20-28-42. Number of swap:1;
    数据序列2: 13-17-20-42-14 利用插入排序,13-14-17-20-42. Number of swap:3;
    如果数据序列基本有序,使用插入排序会更加高效。

    2.基本思想:

    在要排序的一组数中,根据某一增量分为若干子序列,并对子序列分别进行插入排序。
    然后逐渐将增量减小,并重复上述过程。直至增量为1,此时数据序列基本有序,最后进行插入排序。

    3.过程:

    4.平均时间复杂度:O(nlogn) ~ O(n^2)

    5.C#代码实现:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ShellSort
{
    public class ShellSorter
    {
        public void Sort(int[] list)
        {
            int inc;
            for (inc = 1; inc <= list.Length / 9; inc = 3 * inc + 1) ;
            for (; inc > 0; inc /= 3)
            {
                for (int i = inc + 1; i <= list.Length; i += inc)
                {
                    int t = list[i - 1];
                    int j = i;
                    while ((j > inc) && (list[j - inc - 1] > t))
                    {
                        list[j - 1] = list[j - inc - 1];
                        j -= inc;
                    }
                    list[j - 1] = t;
                }
            }
        }
    }
    class Program
    {
        static void Main(string[] args)
        {
            int[] iArrary = new int[] { 59,20,17,13,28,14,23,83 };
            ShellSorter sh = new ShellSorter();
            sh.Sort(iArrary);
            for (int m = 0; m < iArrary.Length; m++)
                Console.Write("{0}", iArrary[m]+",");
            Console.WriteLine();
            Console.ReadKey();
        }
    }
}

     参考:http://www.cnblogs.com/eniac12/p/5329396.html

        http://www.runoob.com/w3cnote/sort-algorithm-summary.html

        http://www.cnblogs.com/zxjyuan/archive/2010/01/06/1640092.html

道虽迩,不行不至;事虽小,不为不成。
原文地址:https://www.cnblogs.com/LeeMacrofeng/p/8342277.html